1 // Copyright 2023 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef VIRTGPU_GFXSTREAM_RENDERER_H 16 #define VIRTGPU_GFXSTREAM_RENDERER_H 17 18 /* An implementation of virtio-gpu-3d that streams rendering commands. */ 19 20 #include <stddef.h> 21 #include <stdint.h> 22 23 #if defined(_WIN32) 24 #if !defined(GFXSTREAM_NO_IOVEC) 25 struct iovec { 26 void* iov_base; /* Starting address */ 27 size_t iov_len; /* Length in bytes */ 28 }; 29 #endif 30 #else 31 #include <sys/uio.h> 32 #endif 33 34 struct stream_renderer_box { 35 uint32_t x, y, z; 36 uint32_t w, h, d; 37 }; 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /** 44 * Versioning 45 */ 46 #define STREAM_RENDERER_VERSION_MAJOR 0 47 #define STREAM_RENDERER_VERSION_MINOR 1 48 #define STREAM_RENDERER_VERSION_PATCH 2 49 50 #ifdef _WIN32 51 #define VG_EXPORT __declspec(dllexport) 52 #else 53 #define VG_EXPORT __attribute__((visibility("default"))) 54 #endif 55 56 struct stream_renderer_resource_create_args { 57 uint32_t handle; 58 uint32_t target; 59 uint32_t format; 60 uint32_t bind; 61 uint32_t width; 62 uint32_t height; 63 uint32_t depth; 64 uint32_t array_size; 65 uint32_t last_level; 66 uint32_t nr_samples; 67 uint32_t flags; 68 }; 69 70 #define STREAM_RENDERER_FLAG_FENCE (1 << 0) 71 #define STREAM_RENDERER_FLAG_FENCE_RING_IDX (1 << 1) 72 #define STREAM_RENDERER_FLAG_FENCE_SHAREABLE (1 << 2) 73 struct stream_renderer_fence { 74 uint32_t flags; 75 uint64_t fence_id; 76 uint32_t ctx_id; 77 uint8_t ring_idx; 78 }; 79 80 #define STREAM_MEM_HANDLE_TYPE_OPAQUE_FD 0x1 81 #define STREAM_MEM_HANDLE_TYPE_DMABUF 0x2 82 #define STREAM_MEM_HANDLE_TYPE_OPAQUE_WIN32 0x3 83 #define STREAM_MEM_HANDLE_TYPE_SHM 0x4 84 #define STREAM_MEM_HANDLE_TYPE_ZIRCON 0x5 85 #define STREAM_FENCE_HANDLE_TYPE_OPAQUE_FD 0x6 86 #define STREAM_FENCE_HANDLE_TYPE_SYNC_FD 0x7 87 #define STREAM_FENCE_HANDLE_TYPE_OPAQUE_WIN32 0x8 88 #define STREAM_FENCE_HANDLE_TYPE_ZIRCON 0x9 89 struct stream_renderer_handle { 90 int64_t os_handle; 91 uint32_t handle_type; 92 }; 93 94 // @user_data: custom user data passed during `stream_renderer_init` 95 // @type: one of STREAM_RENDERER_DEBUG_* 96 // @string: null-terminated C-string 97 #define STREAM_RENDERER_DEBUG_ERROR 0x1 98 #define STREAM_RENDERER_DEBUG_WARN 0x2 99 #define STREAM_RENDERER_DEBUG_INFO 0x3 100 #define STREAM_RENDERER_DEBUG_DEBUG 0x4 101 struct stream_renderer_debug { 102 uint32_t debug_type; 103 const char* message; 104 }; 105 106 // Log level of gfxstream 107 #ifndef STREAM_RENDERER_LOG_LEVEL 108 #define STREAM_RENDERER_LOG_LEVEL STREAM_RENDERER_DEBUG_INFO 109 #endif 110 111 void stream_renderer_log(uint32_t type, const char* file, int line, const char* pretty_function, 112 const char* format, ...); 113 114 #if STREAM_RENDERER_LOG_LEVEL >= STREAM_RENDERER_DEBUG_ERROR 115 #define stream_renderer_error(format, ...) \ 116 do { \ 117 stream_renderer_log(STREAM_RENDERER_DEBUG_ERROR, __FILE__, __LINE__, __PRETTY_FUNCTION__, \ 118 format, ##__VA_ARGS__); \ 119 } while (0) 120 #else 121 #define stream_renderer_error(format, ...) 122 #endif 123 124 #if STREAM_RENDERER_LOG_LEVEL >= STREAM_RENDERER_DEBUG_WARN 125 #define stream_renderer_warn(format, ...) \ 126 do { \ 127 stream_renderer_log(STREAM_RENDERER_DEBUG_WARN, __FILE__, __LINE__, __PRETTY_FUNCTION__, \ 128 format, ##__VA_ARGS__); \ 129 } while (0) 130 #else 131 #define stream_renderer_warn(format, ...) 132 #endif 133 134 #if STREAM_RENDERER_LOG_LEVEL >= STREAM_RENDERER_DEBUG_INFO 135 #define stream_renderer_info(format, ...) \ 136 do { \ 137 stream_renderer_log(STREAM_RENDERER_DEBUG_INFO, __FILE__, __LINE__, __FUNCTION__, format, \ 138 ##__VA_ARGS__); \ 139 } while (0) 140 #else 141 #define stream_renderer_info(format, ...) 142 #endif 143 144 #if STREAM_RENDERER_LOG_LEVEL >= STREAM_RENDERER_DEBUG_DEBUG 145 #define stream_renderer_debug(format, ...) \ 146 do { \ 147 stream_renderer_log(STREAM_RENDERER_DEBUG_DEBUG, __FILE__, __LINE__, __PRETTY_FUNCTION__, \ 148 format, ##__VA_ARGS__); \ 149 } while (0) 150 #else 151 #define stream_renderer_debug(format, ...) 152 #endif 153 154 // Callback for writing a fence. 155 typedef void (*stream_renderer_fence_callback)(void* user_data, 156 struct stream_renderer_fence* fence_data); 157 158 // Callback for allowing debug prints or possibly even aborts. 159 typedef void (*stream_renderer_debug_callback)(void* user_data, 160 struct stream_renderer_debug* debug); 161 162 // Parameters - data passed to initialize the renderer, with the goal of avoiding FFI breakages. 163 // To change the data a parameter is passing safely, you should create a new parameter and 164 // deprecate the old one. The old parameter may be removed after sufficient time. 165 // 166 // STREAM_RENDERER_PARAM_NULL: Reserved value 167 // 168 // The following are required for correct operation: 169 // STREAM_RENDERER_PARAM_USER_DATA: User data, for custom use by VMM. 170 // STREAM_RENDERER_PARAM_RENDERER_FLAGS: Bitwise flags for the renderer. 171 // STREAM_RENDERER_PARAM_FENCE_CALLBACK: A function of the type `stream_renderer_fence_callback` 172 173 // The following are optional: 174 // STREAM_RENDERER_PARAM_WIN0_WIDTH: The width of window[0], when using surface-based rendering 175 // STREAM_RENDERER_PARAM_WIN0_HEIGHT: The height of window[0], when using surface-based rendering 176 #define STREAM_RENDERER_PARAM_NULL 0 177 #define STREAM_RENDERER_PARAM_USER_DATA 1 178 #define STREAM_RENDERER_PARAM_RENDERER_FLAGS 2 179 #define STREAM_RENDERER_PARAM_FENCE_CALLBACK 3 180 #define STREAM_RENDERER_PARAM_WIN0_WIDTH 4 181 #define STREAM_RENDERER_PARAM_WIN0_HEIGHT 5 182 #define STREAM_RENDERER_PARAM_DEBUG_CALLBACK 6 183 184 // An entry in the stream renderer parameters list. 185 // The key should be one of STREAM_RENDERER_PARAM_* 186 // The value can be either a uint64_t or cast to a pointer to a struct, depending on if the 187 // parameter needs to pass data bigger than a single uint64_t. 188 struct stream_renderer_param { 189 uint64_t key; 190 uint64_t value; 191 }; 192 193 // Entry point for the stream renderer. 194 // Pass a list of parameters to configure the renderer. The available ones are listed above. If a 195 // parameter is not supported, the renderer will ignore it and warn in stderr. 196 // Return value 0 indicates success, and a negative number indicates failure. 197 VG_EXPORT int stream_renderer_init(struct stream_renderer_param* stream_renderer_params, 198 uint64_t num_params); 199 200 VG_EXPORT void stream_renderer_teardown(void); 201 202 VG_EXPORT int stream_renderer_resource_create(struct stream_renderer_resource_create_args* args, 203 struct iovec* iov, uint32_t num_iovs); 204 205 VG_EXPORT void stream_renderer_resource_unref(uint32_t res_handle); 206 VG_EXPORT void stream_renderer_context_destroy(uint32_t handle); 207 208 struct stream_renderer_command { 209 uint32_t ctx_id; 210 uint32_t cmd_size; 211 uint8_t* cmd; 212 213 // Unstable: do not use until release strictly greater than 0.1.2 214 uint32_t num_in_fences; 215 struct stream_renderer_handle* fences; 216 }; 217 218 VG_EXPORT int stream_renderer_submit_cmd(struct stream_renderer_command* cmd); 219 220 VG_EXPORT int stream_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id, uint32_t level, 221 uint32_t stride, uint32_t layer_stride, 222 struct stream_renderer_box* box, uint64_t offset, 223 struct iovec* iov, int iovec_cnt); 224 VG_EXPORT int stream_renderer_transfer_write_iov(uint32_t handle, uint32_t ctx_id, int level, 225 uint32_t stride, uint32_t layer_stride, 226 struct stream_renderer_box* box, uint64_t offset, 227 struct iovec* iovec, unsigned int iovec_cnt); 228 VG_EXPORT void stream_renderer_get_cap_set(uint32_t set, uint32_t* max_ver, uint32_t* max_size); 229 VG_EXPORT void stream_renderer_fill_caps(uint32_t set, uint32_t version, void* caps); 230 231 VG_EXPORT int stream_renderer_resource_attach_iov(int res_handle, struct iovec* iov, int num_iovs); 232 VG_EXPORT void stream_renderer_resource_detach_iov(int res_handle, struct iovec** iov, 233 int* num_iovs); 234 VG_EXPORT void stream_renderer_ctx_attach_resource(int ctx_id, int res_handle); 235 VG_EXPORT void stream_renderer_ctx_detach_resource(int ctx_id, int res_handle); 236 237 struct stream_renderer_create_blob { 238 uint32_t blob_mem; 239 uint32_t blob_flags; 240 uint64_t blob_id; 241 uint64_t size; 242 }; 243 244 #define STREAM_BLOB_MEM_GUEST 1 245 #define STREAM_BLOB_MEM_HOST3D 2 246 #define STREAM_BLOB_MEM_HOST3D_GUEST 3 247 248 #define STREAM_BLOB_FLAG_USE_MAPPABLE 1 249 #define STREAM_BLOB_FLAG_USE_SHAREABLE 2 250 #define STREAM_BLOB_FLAG_USE_CROSS_DEVICE 4 251 #define STREAM_BLOB_FLAG_CREATE_GUEST_HANDLE 8 252 253 VG_EXPORT int stream_renderer_create_blob(uint32_t ctx_id, uint32_t res_handle, 254 const struct stream_renderer_create_blob* create_blob, 255 const struct iovec* iovecs, uint32_t num_iovs, 256 const struct stream_renderer_handle* handle); 257 258 VG_EXPORT int stream_renderer_export_blob(uint32_t res_handle, 259 struct stream_renderer_handle* handle); 260 261 VG_EXPORT int stream_renderer_resource_map(uint32_t res_handle, void** hvaOut, uint64_t* sizeOut); 262 VG_EXPORT int stream_renderer_resource_unmap(uint32_t res_handle); 263 264 VG_EXPORT int stream_renderer_context_create(uint32_t ctx_id, uint32_t nlen, const char* name, 265 uint32_t context_init); 266 267 VG_EXPORT int stream_renderer_create_fence(const struct stream_renderer_fence* fence); 268 269 #define STREAM_RENDERER_MAP_CACHE_MASK 0x0f 270 #define STREAM_RENDERER_MAP_CACHE_NONE 0x00 271 #define STREAM_RENDERER_MAP_CACHE_CACHED 0x01 272 #define STREAM_RENDERER_MAP_CACHE_UNCACHED 0x02 273 #define STREAM_RENDERER_MAP_CACHE_WC 0x03 274 VG_EXPORT int stream_renderer_resource_map_info(uint32_t res_handle, uint32_t* map_info); 275 276 // Unique identifier for a GPU device. 277 struct stream_renderer_device_id { 278 uint8_t device_uuid[16]; 279 uint8_t driver_uuid[16]; 280 }; 281 282 struct stream_renderer_vulkan_info { 283 uint32_t memory_index; 284 struct stream_renderer_device_id device_id; 285 }; 286 287 VG_EXPORT int stream_renderer_vulkan_info(uint32_t res_handle, 288 struct stream_renderer_vulkan_info* vulkan_info); 289 290 #ifdef __cplusplus 291 } // extern "C" 292 #endif 293 294 // based on VIRGL_RENDERER_USE* and friends 295 enum RendererFlags { 296 STREAM_RENDERER_FLAGS_USE_EGL_BIT = 1 << 0, 297 STREAM_RENDERER_FLAGS_THREAD_SYNC = 1 << 1, 298 STREAM_RENDERER_FLAGS_USE_GLX_BIT = 1 << 2, 299 STREAM_RENDERER_FLAGS_USE_SURFACELESS_BIT = 1 << 3, 300 STREAM_RENDERER_FLAGS_USE_GLES_BIT = 1 << 4, 301 STREAM_RENDERER_FLAGS_USE_VK_BIT = 1 << 5, 302 STREAM_RENDERER_FLAGS_USE_EXTERNAL_BLOB = 1 << 6, 303 STREAM_RENDERER_FLAGS_USE_SYSTEM_BLOB = 1 << 7, 304 STREAM_RENDERER_FLAGS_VULKAN_NATIVE_SWAPCHAIN_BIT = 1 << 8, 305 // Unstable: do not use until a release greater than 0.1.2 306 STREAM_RENDERER_FLAGS_VULKAN_EXTERNAL_SYNC = 1 << 31, 307 }; 308 309 #endif 310