diff --git a/src/virglrenderer.c b/src/virglrenderer.c index c43d901..a2c37de 100644 --- a/src/virglrenderer.c +++ b/src/virglrenderer.c @@ -654,44 +654,56 @@ int virgl_renderer_execute(void *execute_args, uint32_t execute_size) int virgl_renderer_resource_create_blob(const struct virgl_renderer_resource_create_blob_args *args) { - - int ret; - uint32_t blob_mem = args->blob_mem; - uint64_t blob_id = args->blob_id; - uint32_t res_handle = args->res_handle; + struct virgl_context *ctx; struct pipe_resource *pipe_res; + bool has_host_storage; + bool has_guest_storage; + int ret; - if (blob_mem == VIRGL_RENDERER_BLOB_MEM_HOST3D || - blob_mem == VIRGL_RENDERER_BLOB_MEM_HOST3D_GUEST) { - struct virgl_context *ctx = virgl_context_lookup(args->ctx_id); - if (!ctx) - return -EINVAL; + switch (args->blob_mem) { + case VIRGL_RENDERER_BLOB_MEM_GUEST: + has_host_storage = false; + has_guest_storage = true; + break; + case VIRGL_RENDERER_BLOB_MEM_HOST3D: + has_host_storage = true; + has_guest_storage = false; + break; + case VIRGL_RENDERER_BLOB_MEM_HOST3D_GUEST: + has_host_storage = true; + has_guest_storage = true; + break; + default: + return -EINVAL; + } - pipe_res = ctx->get_blob_pipe(ctx, blob_id); - if (!pipe_res) - return -EINVAL; + if (!has_host_storage) { + return virgl_resource_create_from_iov(args->res_handle, + args->iovecs, + args->num_iovs); + } - ret = virgl_resource_create_from_pipe(res_handle, pipe_res); - if (ret) { - vrend_renderer_resource_destroy((struct vrend_resource *)pipe_res); - return ret; - } + ctx = virgl_context_lookup(args->ctx_id); + if (!ctx) + return -EINVAL; - if (blob_mem == VIRGL_RENDERER_BLOB_MEM_HOST3D_GUEST) { - ret = virgl_renderer_resource_attach_iov(res_handle, args->iovecs, args->num_iovs); - if (ret) { - virgl_resource_remove(res_handle); - return ret; - } - } - } else if (blob_mem == VIRGL_RENDERER_BLOB_MEM_GUEST) { - ret = virgl_resource_create_from_iov(res_handle, args->iovecs, args->num_iovs); - if (ret) - return -EINVAL; - } else { + pipe_res = ctx->get_blob_pipe(ctx, args->blob_id); + if (!pipe_res) return -EINVAL; + + ret = virgl_resource_create_from_pipe(args->res_handle, pipe_res); + if (ret) { + vrend_renderer_resource_destroy((struct vrend_resource *)pipe_res); + return ret; } + if (has_guest_storage) { + ret = virgl_renderer_resource_attach_iov(args->res_handle, args->iovecs, args->num_iovs); + if (ret) { + virgl_resource_remove(args->res_handle); + return ret; + } + } return 0; }