virgl: rework blob support

Replace virgl_context::get_blob_pipe by virgl_context::get_blob,
which supports fd-based blobs.  There is also optional
virgl_context::get_blob_done to give the context a chance to
associate a resource with a blob.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Chia-I Wu 5 years ago
parent 1a54debea0
commit 7594f3030e
  1. 34
      src/virgl_context.h
  2. 37
      src/virglrenderer.c
  3. 24
      src/vrend_decode.c

@ -29,10 +29,22 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
struct virgl_resource; #include "virgl_resource.h"
struct vrend_transfer_info; struct vrend_transfer_info;
struct pipe_resource; struct pipe_resource;
struct virgl_context_blob {
/* valid fd or pipe resource */
enum virgl_resource_fd_type type;
union {
int fd;
struct pipe_resource *pipe_resource;
} u;
void *renderer_data;
};
/** /**
* Base class for renderer contexts. For example, vrend_decode_ctx is a * Base class for renderer contexts. For example, vrend_decode_ctx is a
* subclass of virgl_context. * subclass of virgl_context.
@ -52,12 +64,26 @@ struct virgl_context {
const struct vrend_transfer_info *info, const struct vrend_transfer_info *info,
int transfer_mode); int transfer_mode);
/* These are used to create a virgl_resource from a context object.
*
* get_blob returns a virgl_context_blob from which a virgl_resource can be
* created. get_blob_done is optional and allows the context to associate
* the newly created resource with the context object.
*
* Note that get_blob is a one-time thing. The context object might be
* destroyed or reject subsequent get_blob calls.
*/
int (*get_blob)(struct virgl_context *ctx,
uint64_t blob_id,
uint32_t blob_flags,
struct virgl_context_blob *blob);
void (*get_blob_done)(struct virgl_context *ctx,
uint32_t res_id,
struct virgl_context_blob *blob);
int (*submit_cmd)(struct virgl_context *ctx, int (*submit_cmd)(struct virgl_context *ctx,
const void *buffer, const void *buffer,
size_t size); size_t size);
struct pipe_resource *(*get_blob_pipe)(struct virgl_context *ctx,
uint64_t blob_id);
}; };
struct virgl_context_foreach_args { struct virgl_context_foreach_args {

@ -647,7 +647,7 @@ 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 virgl_renderer_resource_create_blob(const struct virgl_renderer_resource_create_blob_args *args)
{ {
struct virgl_context *ctx; struct virgl_context *ctx;
struct pipe_resource *pipe_res; struct virgl_context_blob blob;
bool has_host_storage; bool has_host_storage;
bool has_guest_storage; bool has_guest_storage;
int ret; int ret;
@ -694,19 +694,34 @@ int virgl_renderer_resource_create_blob(const struct virgl_renderer_resource_cre
if (!ctx) if (!ctx)
return -EINVAL; return -EINVAL;
pipe_res = ctx->get_blob_pipe(ctx, args->blob_id); ret = ctx->get_blob(ctx, args->blob_id, args->blob_flags, &blob);
if (!pipe_res) if (ret)
return -EINVAL;
ret = virgl_resource_create_from_pipe(args->res_handle,
pipe_res,
args->iovecs,
args->num_iovs);
if (ret) {
vrend_renderer_resource_destroy((struct vrend_resource *)pipe_res);
return ret; return ret;
if (blob.type != VIRGL_RESOURCE_FD_INVALID) {
ret = virgl_resource_create_from_fd(args->res_handle,
blob.type,
blob.u.fd,
args->iovecs,
args->num_iovs);
if (ret) {
close(blob.u.fd);
return ret;
}
} else {
ret = virgl_resource_create_from_pipe(args->res_handle,
blob.u.pipe_resource,
args->iovecs,
args->num_iovs);
if (ret) {
vrend_renderer_resource_destroy((struct vrend_resource *)blob.u.pipe_resource);
return ret;
}
} }
if (ctx->get_blob_done)
ctx->get_blob_done(ctx, args->res_handle, &blob);
return 0; return 0;
} }

@ -1502,6 +1502,20 @@ static int vrend_decode_ctx_transfer_3d(struct virgl_context *ctx,
transfer_mode); transfer_mode);
} }
static int vrend_decode_ctx_get_blob(struct virgl_context *ctx,
uint64_t blob_id,
UNUSED uint32_t blob_flags,
struct virgl_context_blob *blob)
{
struct vrend_decode_ctx *dctx = (struct vrend_decode_ctx *)ctx;
blob->type = VIRGL_RESOURCE_FD_INVALID;
/* this transfers ownership and blob_id is no longer valid */
blob->u.pipe_resource = vrend_get_blob_pipe(dctx->grctx, blob_id);
return blob->u.pipe_resource ? 0 : EINVAL;
}
static int vrend_decode_ctx_submit_cmd(struct virgl_context *ctx, static int vrend_decode_ctx_submit_cmd(struct virgl_context *ctx,
const void *buffer, const void *buffer,
size_t size) size_t size)
@ -1694,13 +1708,6 @@ static int vrend_decode_ctx_submit_cmd(struct virgl_context *ctx,
return ret; return ret;
} }
static struct pipe_resource *vrend_decode_get_blob_pipe(struct virgl_context *ctx,
uint64_t blob_id)
{
struct vrend_decode_ctx *dctx = (struct vrend_decode_ctx *)ctx;
return vrend_get_blob_pipe(dctx->grctx, blob_id);
}
static void vrend_decode_ctx_init_base(struct vrend_decode_ctx *dctx, static void vrend_decode_ctx_init_base(struct vrend_decode_ctx *dctx,
uint32_t ctx_id) uint32_t ctx_id)
{ {
@ -1711,8 +1718,9 @@ static void vrend_decode_ctx_init_base(struct vrend_decode_ctx *dctx,
ctx->attach_resource = vrend_decode_ctx_attach_resource; ctx->attach_resource = vrend_decode_ctx_attach_resource;
ctx->detach_resource = vrend_decode_ctx_detach_resource; ctx->detach_resource = vrend_decode_ctx_detach_resource;
ctx->transfer_3d = vrend_decode_ctx_transfer_3d; ctx->transfer_3d = vrend_decode_ctx_transfer_3d;
ctx->get_blob = vrend_decode_ctx_get_blob;
ctx->get_blob_done = NULL;
ctx->submit_cmd = vrend_decode_ctx_submit_cmd; ctx->submit_cmd = vrend_decode_ctx_submit_cmd;
ctx->get_blob_pipe = vrend_decode_get_blob_pipe;
} }
void vrend_decode_reset(void) void vrend_decode_reset(void)

Loading…
Cancel
Save