vrend_renderer: resource create blob

A blob resource is a container for:
  - VIRGL_RENDERER_BLOB_MEM_GUEST: a guest memory allocation
    (referred to as a "guest-only blob resource")

  - VIRGL_RENDERER_BLOB_MEM_HOST3D: a host3d memory allocation
    (referred to as a "host-only blob resource")

  - VIRGL_RENDERER_BLOB_MEM_HOST3D_GUEST: a guest + host3d memory allocation
    (referred to as a "default blob resource").

Blob resources can be used to implement new features and fix shortcomings
with the current resource create path.  The subsequent patches show how
blob resources may be leveraged to implement GL_ARB_buffer_storage
and GL4.5.

Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Acked-by: Gert Wollny <gert.wollny@collabora.com>
macos/master
Gurchetan Singh 5 years ago
parent 13c93dae18
commit 0e736de059
  1. 4
      src/virgl_context.h
  2. 21
      src/virgl_resource.c
  3. 5
      src/virgl_resource.h
  4. 43
      src/virglrenderer.c
  5. 22
      src/virglrenderer.h
  6. 8
      src/vrend_decode.c
  7. 18
      src/vrend_renderer.c
  8. 3
      src/vrend_renderer.h

@ -31,6 +31,7 @@
struct virgl_resource;
struct vrend_transfer_info;
struct pipe_resource;
/**
* Base class for renderer contexts. For example, vrend_decode_ctx is a
@ -54,6 +55,9 @@ struct virgl_context {
int (*submit_cmd)(struct virgl_context *ctx,
const void *buffer,
size_t size);
struct pipe_resource *(*get_blob_pipe)(struct virgl_context *ctx,
uint64_t blob_id);
};
struct virgl_context_foreach_args {

@ -24,6 +24,7 @@
#include "virgl_resource.h"
#include <assert.h>
#include <errno.h>
#include <string.h>
@ -110,6 +111,26 @@ virgl_resource_create_from_pipe(uint32_t res_id, struct pipe_resource *pres)
return 0;
}
int
virgl_resource_create_from_iov(uint32_t res_id,
const struct iovec *iov,
int iov_count)
{
struct virgl_resource *res;
if (iov_count)
assert(iov);
res = virgl_resource_create(res_id);
if (!res)
return ENOMEM;
res->iov = iov;
res->iov_count = iov_count;
return 0;
}
void
virgl_resource_remove(uint32_t res_id)
{

@ -73,6 +73,11 @@ virgl_resource_table_reset(void);
int
virgl_resource_create_from_pipe(uint32_t res_id, struct pipe_resource *pres);
int
virgl_resource_create_from_iov(uint32_t res_id,
const struct iovec *iov,
int iov_count);
void
virgl_resource_remove(uint32_t res_id);

@ -633,3 +633,46 @@ int virgl_renderer_execute(void *execute_args, uint32_t execute_size)
return -EINVAL;
}
}
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 pipe_resource *pipe_res;
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;
pipe_res = ctx->get_blob_pipe(ctx, blob_id);
if (!pipe_res)
return -EINVAL;
ret = virgl_resource_create_from_pipe(res_handle, pipe_res);
if (ret) {
vrend_renderer_resource_destroy((struct vrend_resource *)pipe_res);
return ret;
}
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 {
return -EINVAL;
}
return 0;
}

@ -236,4 +236,26 @@ VIRGL_EXPORT int virgl_renderer_get_poll_fd(void);
VIRGL_EXPORT int virgl_renderer_execute(void *execute_args, uint32_t execute_size);
#define VIRGL_RENDERER_BLOB_MEM_GUEST 0x0001
#define VIRGL_RENDERER_BLOB_MEM_HOST3D 0x0002
#define VIRGL_RENDERER_BLOB_MEM_HOST3D_GUEST 0x0003
#define VIRGL_RENDERER_BLOB_FLAG_USE_MAPPABLE 0x0001
#define VIRGL_RENDERER_BLOB_FLAG_USE_SHAREABLE 0x0002
#define VIRGL_RENDERER_BLOB_FLAG_USE_CROSS_DEVICE 0x0004
struct virgl_renderer_resource_create_blob_args
{
uint32_t res_handle;
uint32_t ctx_id;
uint32_t blob_mem;
uint32_t blob_flags;
uint64_t blob_id;
uint64_t size;
const struct iovec *iovecs;
uint32_t num_iovs;
};
VIRGL_EXPORT int
virgl_renderer_resource_create_blob(const struct virgl_renderer_resource_create_blob_args *args);
#endif

@ -1694,6 +1694,13 @@ static int vrend_decode_ctx_submit_cmd(struct virgl_context *ctx,
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,
uint32_t ctx_id)
{
@ -1705,6 +1712,7 @@ static void vrend_decode_ctx_init_base(struct vrend_decode_ctx *dctx,
ctx->detach_resource = vrend_decode_ctx_detach_resource;
ctx->transfer_3d = vrend_decode_ctx_transfer_3d;
ctx->submit_cmd = vrend_decode_ctx_submit_cmd;
ctx->get_blob_pipe = vrend_decode_get_blob_pipe;
}
void vrend_decode_reset(void)

@ -10349,3 +10349,21 @@ int vrend_renderer_pipe_resource_create(struct vrend_context *ctx, uint32_t blob
list_addtail(&res->head, &ctx->vrend_resources);
return 0;
}
struct pipe_resource *vrend_get_blob_pipe(struct vrend_context *ctx, uint64_t blob_id)
{
uint32_t id = (uint32_t)blob_id;
struct vrend_resource *res, *stor;
LIST_FOR_EACH_ENTRY_SAFE(res, stor, &ctx->vrend_resources, head) {
if (res->blob_id != id)
continue;
list_del(&res->head);
/* Set the blob id to zero, since it won't be used anymore */
res->blob_id = 0;
return &res->base;
}
return NULL;
}

@ -494,4 +494,7 @@ void vrend_sync_make_current(virgl_gl_context);
int
vrend_renderer_pipe_resource_create(struct vrend_context *ctx, uint32_t blob_id,
struct vrend_renderer_resource_create_args *args);
struct pipe_resource *vrend_get_blob_pipe(struct vrend_context *ctx, uint64_t blob_id);
#endif

Loading…
Cancel
Save