1 /* 2 * Copyright 2021 Google LLC 3 * SPDX-License-Identifier: MIT 4 */ 5 6 #ifndef RENDER_PROTOCOL_H 7 #define RENDER_PROTOCOL_H 8 9 #include <stdint.h> 10 11 #include "virgl_resource.h" 12 #include "virglrenderer.h" 13 #include "virglrenderer_hw.h" 14 15 /* this covers the command line options and the socket type */ 16 #define RENDER_SERVER_VERSION 0 17 18 /* The protocol itself is internal to virglrenderer. There is no backward 19 * compatibility to be kept. 20 */ 21 22 /* client ops, which are handled by the server process */ 23 enum render_client_op { 24 RENDER_CLIENT_OP_NOP = 0, 25 RENDER_CLIENT_OP_INIT, 26 RENDER_CLIENT_OP_RESET, 27 RENDER_CLIENT_OP_CREATE_CONTEXT, 28 RENDER_CLIENT_OP_DESTROY_CONTEXT, 29 30 RENDER_CLIENT_OP_COUNT, 31 }; 32 33 /* context ops, which are handled by workers (subprocesses or threads) created 34 * by the server process 35 */ 36 enum render_context_op { 37 RENDER_CONTEXT_OP_NOP = 0, 38 RENDER_CONTEXT_OP_INIT, 39 RENDER_CONTEXT_OP_CREATE_RESOURCE, 40 RENDER_CONTEXT_OP_IMPORT_RESOURCE, 41 RENDER_CONTEXT_OP_DESTROY_RESOURCE, 42 RENDER_CONTEXT_OP_SUBMIT_CMD, 43 RENDER_CONTEXT_OP_SUBMIT_FENCE, 44 45 RENDER_CONTEXT_OP_COUNT, 46 }; 47 48 struct render_client_op_header { 49 enum render_client_op op; 50 }; 51 52 struct render_client_op_nop_request { 53 struct render_client_op_header header; 54 }; 55 56 /* Initialize virglrenderer. 57 * 58 * This roughly corresponds to virgl_renderer_init. 59 */ 60 struct render_client_op_init_request { 61 struct render_client_op_header header; 62 uint32_t flags; /* VIRGL_RENDERER_USE_* and others */ 63 }; 64 65 /* Remove all contexts. 66 * 67 * This roughly corresponds to virgl_renderer_reset. 68 */ 69 struct render_client_op_reset_request { 70 struct render_client_op_header header; 71 }; 72 73 /* Create a context, which will be serviced by a worker. 74 * 75 * See also the comment before main() for the process model. 76 * 77 * This roughly corresponds to virgl_renderer_context_create_with_flags. 78 */ 79 struct render_client_op_create_context_request { 80 struct render_client_op_header header; 81 uint32_t ctx_id; 82 char ctx_name[32]; 83 }; 84 85 struct render_client_op_create_context_reply { 86 bool ok; 87 /* followed by 1 socket fd if ok */ 88 }; 89 90 /* Destroy a context, including the worker. 91 * 92 * This roughly corresponds to virgl_renderer_context_destroy. 93 */ 94 struct render_client_op_destroy_context_request { 95 struct render_client_op_header header; 96 uint32_t ctx_id; 97 }; 98 99 union render_client_op_request { 100 struct render_client_op_header header; 101 struct render_client_op_nop_request nop; 102 struct render_client_op_init_request init; 103 struct render_client_op_reset_request reset; 104 struct render_client_op_create_context_request create_context; 105 struct render_client_op_destroy_context_request destroy_context; 106 }; 107 108 struct render_context_op_header { 109 enum render_context_op op; 110 }; 111 112 struct render_context_op_nop_request { 113 struct render_context_op_header header; 114 }; 115 116 /* Initialize the context. 117 * 118 * The shmem is required and currently holds an array of atomic_uint. Each 119 * atomic_uint represents the current sequence number of a ring (as defined by 120 * the virtio-gpu spec). 121 * 122 * The eventfd is optional. When given, it will be written to when there are 123 * changes to any of the sequence numbers. 124 * 125 * This roughly corresponds to virgl_renderer_context_create_with_flags. 126 */ 127 struct render_context_op_init_request { 128 struct render_context_op_header header; 129 uint32_t flags; /* VIRGL_RENDERER_CONTEXT_FLAG_*/ 130 size_t shmem_size; 131 /* followed by 1 shmem fd and optionally 1 eventfd */ 132 }; 133 134 /* Export a blob resource from the context 135 * 136 * This roughly corresponds to: 137 * - virgl_renderer_resource_create_blob 138 * - virgl_renderer_resource_get_map_info 139 * - virgl_renderer_resource_export_blob 140 * - virgl_renderer_ctx_attach_resource 141 */ 142 struct render_context_op_create_resource_request { 143 struct render_context_op_header header; 144 uint32_t res_id; 145 uint64_t blob_id; 146 uint64_t blob_size; 147 uint32_t blob_flags; /* VIRGL_RENDERER_BLOB_FLAG_* */ 148 }; 149 150 struct render_context_op_create_resource_reply { 151 enum virgl_resource_fd_type fd_type; 152 uint32_t map_info; /* VIRGL_RENDERER_MAP_* */ 153 /* followed by 1 fd if not VIRGL_RESOURCE_FD_INVALID */ 154 }; 155 156 /* Import a blob resource to the context 157 * 158 * This roughly corresponds to: 159 * - virgl_renderer_resource_import_blob 160 * - virgl_renderer_ctx_attach_resource 161 */ 162 struct render_context_op_import_resource_request { 163 struct render_context_op_header header; 164 uint32_t res_id; 165 enum virgl_resource_fd_type fd_type; 166 uint64_t size; 167 /* followed by 1 fd */ 168 }; 169 170 /* Free a blob resource from the context 171 * 172 * This roughly corresponds to: 173 * - virgl_renderer_resource_unref 174 */ 175 struct render_context_op_destroy_resource_request { 176 struct render_context_op_header header; 177 uint32_t res_id; 178 }; 179 180 /* Submit a small command stream to the context. 181 * 182 * The size limit depends on the socket type. Currently, SOCK_SEQPACKET is 183 * used and the size limit is best treated as one page. 184 * 185 * This roughly corresponds to virgl_renderer_submit_cmd. 186 */ 187 struct render_context_op_submit_cmd_request { 188 struct render_context_op_header header; 189 size_t size; 190 char cmd[256]; 191 /* if size > sizeof(cmd), followed by (size - sizeof(cmd)) bytes in another 192 * message; size still must be small 193 */ 194 }; 195 196 struct render_context_op_submit_cmd_reply { 197 bool ok; 198 }; 199 200 /* Submit a fence to the context. 201 * 202 * This submits a fence to the specified ring. When the fence signals, the 203 * current sequence number of the ring in the shmem is updated. 204 * 205 * This roughly corresponds to virgl_renderer_context_create_fence. 206 */ 207 struct render_context_op_submit_fence_request { 208 struct render_context_op_header header; 209 uint32_t flags; /* VIRGL_RENDERER_FENCE_FLAG_* */ 210 /* TODO fix virgl_renderer_context_create_fence to use ring_index */ 211 uint32_t ring_index; 212 uint32_t seqno; 213 }; 214 215 union render_context_op_request { 216 struct render_context_op_header header; 217 struct render_context_op_nop_request nop; 218 struct render_context_op_init_request init; 219 struct render_context_op_create_resource_request create_resource; 220 struct render_context_op_import_resource_request import_resource; 221 struct render_context_op_destroy_resource_request destroy_resource; 222 struct render_context_op_submit_cmd_request submit_cmd; 223 struct render_context_op_submit_fence_request submit_fence; 224 }; 225 226 #endif /* RENDER_PROTOCOL_H */ 227