diff --git a/src/virglrenderer.c b/src/virglrenderer.c index 46513fe..af935ef 100644 --- a/src/virglrenderer.c +++ b/src/virglrenderer.c @@ -1002,6 +1002,57 @@ virgl_renderer_resource_export_blob(uint32_t res_id, uint32_t *fd_type, int *fd) return 0; } +int +virgl_renderer_resource_import_blob(const struct virgl_renderer_resource_import_blob_args *args) +{ + TRACE_FUNC(); + struct virgl_resource *res; + + /* user resource id must be greater than 0 */ + if (args->res_handle == 0) + return -EINVAL; + + switch (args->blob_mem) { + case VIRGL_RENDERER_BLOB_MEM_HOST3D: + break; + default: + return -EINVAL; + } + + enum virgl_resource_fd_type fd_type = VIRGL_RESOURCE_FD_INVALID; + switch (args->fd_type) { + case VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF: + fd_type = VIRGL_RESOURCE_FD_DMABUF; + break; + case VIRGL_RENDERER_BLOB_FD_TYPE_OPAQUE: + fd_type = VIRGL_RESOURCE_FD_OPAQUE; + break; + case VIRGL_RENDERER_BLOB_FD_TYPE_SHM: + fd_type = VIRGL_RESOURCE_FD_SHM; + break; + default: + return -EINVAL; + } + + if (args->fd < 0) + return -EINVAL; + if (args->size == 0) + return -EINVAL; + + res = virgl_resource_create_from_fd(args->res_handle, + fd_type, + args->fd, + NULL, + 0); + if (!res) + return -ENOMEM; + + res->map_info = 0; + res->map_size = args->size; + + return 0; +} + int virgl_renderer_export_fence(uint32_t client_fence_id, int *fd) { diff --git a/src/virglrenderer.h b/src/virglrenderer.h index 1a4318d..dbee288 100644 --- a/src/virglrenderer.h +++ b/src/virglrenderer.h @@ -328,6 +328,18 @@ VIRGL_EXPORT int virgl_renderer_resource_get_map_info(uint32_t res_handle, uint3 VIRGL_EXPORT int virgl_renderer_resource_export_blob(uint32_t res_id, uint32_t *fd_type, int *fd); +struct virgl_renderer_resource_import_blob_args +{ + uint32_t res_handle; + uint32_t blob_mem; + uint32_t fd_type; + int fd; + uint64_t size; +}; + +VIRGL_EXPORT int +virgl_renderer_resource_import_blob(const struct virgl_renderer_resource_import_blob_args *args); + VIRGL_EXPORT int virgl_renderer_export_fence(uint32_t client_fence_id, int *fd);