1 /* 2 * Copyright 2021 The ChromiumOS Authors 3 * Use of this source code is governed by a BSD-style license that can be 4 * found in the LICENSE file. 5 */ 6 7 #include <stdarg.h> 8 #include <stdbool.h> 9 #include <stdint.h> 10 #include <stdlib.h> 11 12 #if defined(_WIN32) 13 struct iovec; 14 #else 15 #include <sys/uio.h> 16 #endif 17 18 #ifndef RUTABAGA_GFX_FFI_H 19 #define RUTABAGA_GFX_FFI_H 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /** 26 * Versioning 27 */ 28 #define RUTABAGA_VERSION_MAJOR 0 29 #define RUTABAGA_VERSION_MINOR 1 30 #define RUTABAGA_VERSION_PATCH 3 31 32 /** 33 * Rutabaga capsets. 34 */ 35 #define RUTABAGA_CAPSET_VIRGL 1 36 #define RUTABAGA_CAPSET_VIRGL2 2 37 #define RUTABAGA_CAPSET_GFXSTREAM_VULKAN 3 38 #define RUTABAGA_CAPSET_VENUS 4 39 #define RUTABAGA_CAPSET_CROSS_DOMAIN 5 40 #define RUTABAGA_CAPSET_DRM 6 41 #define RUTABAGA_CAPSET_GFXSTREAM_MAGMA 7 42 #define RUTABAGA_CAPSET_GFXSTREAM_GLES 8 43 #define RUTABAGA_CAPSET_GFXSTREAM_COMPOSER 9 44 45 /** 46 * Blob resource creation parameters. 47 */ 48 #define RUTABAGA_BLOB_MEM_GUEST 1 49 #define RUTABAGA_BLOB_MEM_HOST3D 2 50 #define RUTABAGA_BLOB_MEM_HOST3D_GUEST 3 51 52 #define RUTABAGA_BLOB_FLAG_USE_MAPPABLE 1 53 #define RUTABAGA_BLOB_FLAG_USE_SHAREABLE 2 54 #define RUTABAGA_BLOB_FLAG_USE_CROSS_DEVICE 4 55 56 /** 57 * Mapped memory caching flags (see virtio_gpu spec) 58 */ 59 #define RUTABAGA_MAP_CACHE_MASK 0x0f 60 #define RUTABAGA_MAP_CACHE_CACHED 0x01 61 #define RUTABAGA_MAP_CACHE_UNCACHED 0x02 62 #define RUTABAGA_MAP_CACHE_WC 0x03 63 64 /** 65 * Mapped memory access flags (not in virtio_gpu spec) 66 */ 67 #define RUTABAGA_MAP_ACCESS_MASK 0xf0 68 #define RUTABAGA_MAP_ACCESS_READ 0x10 69 #define RUTABAGA_MAP_ACCESS_WRITE 0x20 70 #define RUTABAGA_MAP_ACCESS_RW 0x30 71 72 /** 73 * Rutabaga handle types 74 */ 75 #define RUTABAGA_MEM_HANDLE_TYPE_OPAQUE_FD 0x1 76 #define RUTABAGA_MEM_HANDLE_TYPE_DMABUF 0x2 77 #define RUTABAGA_MEM_HANDLE_TYPE_OPAQUE_WIN32 0x3 78 #define RUTABAGA_MEM_HANDLE_TYPE_SHM 0x4 79 #define RUTABAGA_MEM_HANDLE_TYPE_ZIRCON 0x5 80 81 #define RUTABAGA_FENCE_HANDLE_TYPE_OPAQUE_FD 0x6 82 #define RUTABAGA_FENCE_HANDLE_TYPE_SYNC_FD 0x7 83 #define RUTABAGA_FENCE_HANDLE_TYPE_OPAQUE_WIN32 0x8 84 #define RUTABAGA_FENCE_HANDLE_TYPE_ZIRCON 0x9 85 86 /** 87 * Rutabaga channel types 88 */ 89 #define RUTABAGA_CHANNEL_TYPE_WAYLAND 1 90 91 /** 92 * Rutabaga WSI 93 */ 94 #define RUTABAGA_WSI_SURFACELESS 0x1 95 96 /** 97 * Rutabaga flags for creating fences. 98 */ 99 #define RUTABAGA_FLAG_FENCE (1 << 0) 100 #define RUTABAGA_FLAG_INFO_RING_IDX (1 << 1) 101 #define RUTABAGA_FLAG_FENCE_SHAREABLE (1 << 2) 102 103 /** 104 * Rutabaga Debug 105 */ 106 #define RUTABAGA_DEBUG_ERROR 0x1 107 #define RUTABAGA_DEBUG_WARN 0x2 108 #define RUTABAGA_DEBUG_INFO 0x3 109 110 struct rutabaga; 111 112 struct rutabaga_create_blob { 113 uint32_t blob_mem; 114 uint32_t blob_flags; 115 uint64_t blob_id; 116 uint64_t size; 117 }; 118 119 struct rutabaga_create_3d { 120 uint32_t target; 121 uint32_t format; 122 uint32_t bind; 123 uint32_t width; 124 uint32_t height; 125 uint32_t depth; 126 uint32_t array_size; 127 uint32_t last_level; 128 uint32_t nr_samples; 129 uint32_t flags; 130 }; 131 132 struct rutabaga_transfer { 133 uint32_t x; 134 uint32_t y; 135 uint32_t z; 136 uint32_t w; 137 uint32_t h; 138 uint32_t d; 139 uint32_t level; 140 uint32_t stride; 141 uint32_t layer_stride; 142 uint64_t offset; 143 }; 144 145 struct rutabaga_iovecs { 146 struct iovec *iovecs; 147 size_t num_iovecs; 148 }; 149 150 struct rutabaga_handle { 151 int64_t os_handle; 152 uint32_t handle_type; 153 }; 154 155 struct rutabaga_mapping { 156 void *ptr; 157 uint64_t size; 158 }; 159 160 struct rutabaga_command { 161 uint32_t ctx_id; 162 uint32_t cmd_size; 163 uint8_t *cmd; 164 165 /** 166 * Unstable, don't use until version > 0.1.3 167 */ 168 uint32_t num_in_fences; 169 uint64_t *fence_ids; 170 }; 171 172 /** 173 * Assumes null-terminated C-string. 174 */ 175 struct rutabaga_channel { 176 const char *channel_name; 177 uint32_t channel_type; 178 }; 179 180 struct rutabaga_channels { 181 struct rutabaga_channel *channels; 182 size_t num_channels; 183 }; 184 185 struct rutabaga_fence { 186 uint32_t flags; 187 uint64_t fence_id; 188 uint32_t ctx_id; 189 uint32_t ring_idx; 190 }; 191 192 struct rutabaga_debug { 193 uint32_t debug_type; 194 const char *message; 195 }; 196 197 /** 198 * Throwing an exception inside this callback is not allowed. 199 */ 200 typedef void (*rutabaga_fence_callback)(uint64_t user_data, const struct rutabaga_fence *fence); 201 202 /** 203 * # Safety 204 * - Throwing an exception inside this callback is not allowed. 205 * - `rutabaga_debug` and contained values only valid for the duration of callback. 206 */ 207 typedef void (*rutabaga_debug_callback)(uint64_t user_data, const struct rutabaga_debug *debug); 208 209 struct rutabaga_builder { 210 // Required for correct functioning 211 uint64_t user_data; 212 uint64_t capset_mask; 213 uint64_t wsi; 214 rutabaga_fence_callback fence_cb; 215 216 // Optional for debugging. 217 rutabaga_debug_callback debug_cb; 218 219 // Optional and platform specific 220 struct rutabaga_channels *channels; 221 222 // Optional, renderer specific, null-terminated C-string. 223 const char *renderer_features; 224 }; 225 226 /** 227 * Expects `capset_names` to delimited by a colon, i.e.: "gfxstream:cross_domain:magma". 228 * 229 * # Safety 230 * - - `capset_names` must be a null-terminated C-string. 231 */ 232 int32_t rutabaga_calculate_capset_mask(const char *capset_names, uint64_t *capset_mask); 233 234 /** 235 * Initialize rutabaga. 236 * 237 * All API calls using `ptr` must on the same thread that called `rutabaga_init`. 238 * 239 * # Safety 240 * - If `(*builder).channels` is not null, the caller must ensure `(*channels).channels` points to 241 * a valid array of `struct rutabaga_channel` of size `(*channels).num_channels`. 242 * - The `channel_name` field of `struct rutabaga_channel` must be a null-terminated C-string. 243 */ 244 int32_t rutabaga_init(const struct rutabaga_builder *builder, struct rutabaga **ptr); 245 246 /** 247 * # Safety 248 * - `ptr` must have been created by `rutabaga_init`. 249 */ 250 int32_t rutabaga_finish(struct rutabaga **ptr); 251 252 int32_t rutabaga_get_num_capsets(struct rutabaga *ptr, uint32_t *num_capsets); 253 254 int32_t rutabaga_get_capset_info(struct rutabaga *ptr, uint32_t capset_index, uint32_t *capset_id, 255 uint32_t *capset_version, uint32_t *capset_size); 256 257 /** 258 * # Safety 259 * - `capset` must point an array of bytes of size `capset_size`. 260 */ 261 int32_t rutabaga_get_capset(struct rutabaga *ptr, uint32_t capset_id, uint32_t version, 262 uint8_t *capset, uint32_t capset_size); 263 264 /** 265 * # Safety 266 * - `context_name` must either be NULL or a valid pointer to an array of at least 267 * `context_name_len` bytes encoding a UTF-8 string. 268 */ 269 int32_t rutabaga_context_create(struct rutabaga *ptr, uint32_t ctx_id, uint32_t context_init, 270 const char *context_name, uint32_t context_name_len); 271 272 int32_t rutabaga_context_destroy(struct rutabaga *ptr, uint32_t ctx_id); 273 274 int32_t rutabaga_context_attach_resource(struct rutabaga *ptr, uint32_t ctx_id, 275 uint32_t resource_id); 276 277 int32_t rutabaga_context_detach_resource(struct rutabaga *ptr, uint32_t ctx_id, 278 uint32_t resource_id); 279 280 int32_t rutabaga_resource_create_3d(struct rutabaga *ptr, uint32_t resource_id, 281 const struct rutabaga_create_3d *create_3d); 282 283 /** 284 * # Safety 285 * - If `iovecs` is not null, the caller must ensure `(*iovecs).iovecs` points to a valid array of 286 * iovecs of size `(*iovecs).num_iovecs`. 287 * - Each iovec must point to valid memory starting at `iov_base` with length `iov_len`. 288 * - Each iovec must valid until the resource's backing is explicitly detached or the resource is 289 * is unreferenced. 290 */ 291 int32_t rutabaga_resource_attach_backing(struct rutabaga *ptr, uint32_t resource_id, 292 const struct rutabaga_iovecs *iovecs); 293 294 int32_t rutabaga_resource_detach_backing(struct rutabaga *ptr, uint32_t resource_id); 295 296 /** 297 * # Safety 298 * - If `iovecs` is not null, the caller must ensure `(*iovecs).iovecs` points to a valid array of 299 * iovecs of size `(*iovecs).num_iovecs`. 300 */ 301 int32_t rutabaga_resource_transfer_read(struct rutabaga *ptr, uint32_t ctx_id, uint32_t resource_id, 302 const struct rutabaga_transfer *transfer, 303 const struct iovec *iovec); 304 305 int32_t rutabaga_resource_transfer_write(struct rutabaga *ptr, uint32_t ctx_id, 306 uint32_t resource_id, 307 const struct rutabaga_transfer *transfer); 308 309 /** 310 * # Safety 311 * - If `iovecs` is not null, the caller must ensure `(*iovecs).iovecs` points to a valid array of 312 * iovecs of size `(*iovecs).num_iovecs`. 313 * - If `handle` is not null, the caller must ensure it is a valid OS-descriptor. Ownership is 314 * transferred to rutabaga. 315 * - Each iovec must valid until the resource's backing is explicitly detached or the resource is 316 * is unreferenced. 317 */ 318 int32_t rutabaga_resource_create_blob(struct rutabaga *ptr, uint32_t ctx_id, uint32_t resource_id, 319 const struct rutabaga_create_blob *rutabaga_create_blob, 320 const struct rutabaga_iovecs *iovecs, 321 const struct rutabaga_handle *handle); 322 323 int32_t rutabaga_resource_unref(struct rutabaga *ptr, uint32_t resource_id); 324 325 /** 326 * # Safety 327 * Caller owns raw descriptor on success and is responsible for closing it. 328 */ 329 int32_t rutabaga_resource_export_blob(struct rutabaga *ptr, uint32_t resource_id, 330 struct rutabaga_handle *handle); 331 332 int32_t rutabaga_resource_map(struct rutabaga *ptr, uint32_t resource_id, 333 struct rutabaga_mapping *mapping); 334 335 int32_t rutabaga_resource_unmap(struct rutabaga *ptr, uint32_t resource_id); 336 337 int32_t rutabaga_resource_map_info(struct rutabaga *ptr, uint32_t resource_id, uint32_t *map_info); 338 339 /** 340 * # Safety 341 * - `cmd` must be not null 342 * - `cmd->cmd` point to a contiguous memory region of `cmd_size` bytes. 343 * - `cmd->fence_ids` must point to a contiguous array of `num_in_fences` elements 344 */ 345 int32_t rutabaga_submit_command(struct rutabaga *ptr, struct rutabaga_command *cmd); 346 347 int32_t rutabaga_create_fence(struct rutabaga *ptr, const struct rutabaga_fence *fence); 348 349 /** 350 * Write a snapshot to `dir`. The directory is expected to already exist and to be empty. 351 * 352 * # Safety 353 * - `dir` must be a null-terminated C-string. 354 * - Unstable, don't use until version > 0.1.3 355 */ 356 int32_t rutabaga_snapshot(struct rutabaga *ptr, const char *dir); 357 358 /** 359 * Restore from a snapshot at `dir`. 360 * 361 * # Safety 362 * - `dir` must be a null-terminated C-string. 363 * - Unstable, don't use until version > 0.1.3 364 */ 365 int32_t rutabaga_restore(struct rutabaga *ptr, const char *dir); 366 367 int32_t rutabaga_resource_wait_sync(struct rutabaga *ptr, uint32_t resource_id); 368 369 #ifdef __cplusplus 370 } 371 #endif 372 373 #endif 374