virgl: make virgl_renderer_transfer_*_iov more generic

Add virgl_context::transfer_3d, and when ctx_id is specified, use
the callback.

When ctx_id is not specified, the resource is a dumb/scanout
resource and is never referenced by submit_cmd.  It does not need to
go through the callback.  There is no way to either.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Chia-I Wu 5 years ago
parent 94262367bd
commit df99fd7c75
  1. 6
      src/virgl_context.h
  2. 40
      src/virglrenderer.c
  3. 14
      src/vrend_decode.c
  4. 60
      src/vrend_renderer.c
  5. 7
      src/vrend_renderer.h

@ -30,6 +30,7 @@
#include <stdint.h>
struct virgl_resource;
struct vrend_transfer_info;
/**
* Base class for renderer contexts. For example, vrend_decode_ctx is a
@ -45,6 +46,11 @@ struct virgl_context {
void (*detach_resource)(struct virgl_context *ctx,
struct virgl_resource *res);
int (*transfer_3d)(struct virgl_context *ctx,
struct virgl_resource *res,
const struct vrend_transfer_info *info,
int transfer_mode);
int (*submit_cmd)(struct virgl_context *ctx,
const void *buffer,
size_t size);

@ -174,8 +174,12 @@ int virgl_renderer_transfer_write_iov(uint32_t handle,
struct iovec *iovec,
unsigned int iovec_cnt)
{
struct virgl_resource *res = virgl_resource_lookup(handle);
struct vrend_transfer_info transfer_info;
if (!res)
return EINVAL;
transfer_info.ctx_id = ctx_id;
transfer_info.level = level;
transfer_info.stride = stride;
@ -187,8 +191,20 @@ int virgl_renderer_transfer_write_iov(uint32_t handle,
transfer_info.context0 = true;
transfer_info.synchronized = false;
return vrend_renderer_transfer_iov(handle, &transfer_info,
VIRGL_TRANSFER_TO_HOST);
if (ctx_id) {
struct virgl_context *ctx = virgl_context_lookup(ctx_id);
if (!ctx)
return EINVAL;
return ctx->transfer_3d(ctx, res, &transfer_info,
VIRGL_TRANSFER_TO_HOST);
} else {
if (!res->pipe_resource)
return EINVAL;
return vrend_renderer_transfer_pipe(res->pipe_resource, &transfer_info,
VIRGL_TRANSFER_TO_HOST);
}
}
int virgl_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id,
@ -198,8 +214,12 @@ int virgl_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id,
uint64_t offset, struct iovec *iovec,
int iovec_cnt)
{
struct virgl_resource *res = virgl_resource_lookup(handle);
struct vrend_transfer_info transfer_info;
if (!res)
return EINVAL;
transfer_info.ctx_id = ctx_id;
transfer_info.level = level;
transfer_info.stride = stride;
@ -211,8 +231,20 @@ int virgl_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id,
transfer_info.context0 = true;
transfer_info.synchronized = false;
return vrend_renderer_transfer_iov(handle, &transfer_info,
VIRGL_TRANSFER_FROM_HOST);
if (ctx_id) {
struct virgl_context *ctx = virgl_context_lookup(ctx_id);
if (!ctx)
return EINVAL;
return ctx->transfer_3d(ctx, res, &transfer_info,
VIRGL_TRANSFER_FROM_HOST);
} else {
if (!res->pipe_resource)
return EINVAL;
return vrend_renderer_transfer_pipe(res->pipe_resource, &transfer_info,
VIRGL_TRANSFER_FROM_HOST);
}
}
int virgl_renderer_resource_attach_iov(int res_handle, struct iovec *iov,

@ -1365,7 +1365,8 @@ static int vrend_decode_transfer3d(struct vrend_decode_ctx *ctx, int length, uin
transfer_mode != VIRGL_TRANSFER_FROM_HOST)
return EINVAL;
return vrend_renderer_transfer_iov(dst_handle, &info, transfer_mode);
return vrend_renderer_transfer_iov(ctx->grctx, dst_handle, &info,
transfer_mode);
}
static int vrend_decode_copy_transfer3d(struct vrend_decode_ctx *ctx, int length)
@ -1451,6 +1452,16 @@ static void vrend_decode_ctx_detach_resource(struct virgl_context *ctx,
vrend_renderer_detach_res_ctx(dctx->grctx, res->res_id);
}
static int vrend_decode_ctx_transfer_3d(struct virgl_context *ctx,
struct virgl_resource *res,
const struct vrend_transfer_info *info,
int transfer_mode)
{
struct vrend_decode_ctx *dctx = (struct vrend_decode_ctx *)ctx;
return vrend_renderer_transfer_iov(dctx->grctx, res->res_id, info,
transfer_mode);
}
static int vrend_decode_ctx_submit_cmd(struct virgl_context *ctx,
const void *buffer,
size_t size)
@ -1646,6 +1657,7 @@ static void vrend_decode_ctx_init_base(struct vrend_decode_ctx *dctx,
ctx->destroy = vrend_decode_ctx_destroy;
ctx->attach_resource = vrend_decode_ctx_attach_resource;
ctx->detach_resource = vrend_decode_ctx_detach_resource;
ctx->transfer_3d = vrend_decode_ctx_transfer_3d;
ctx->submit_cmd = vrend_decode_ctx_submit_cmd;
}

@ -7624,34 +7624,17 @@ static int vrend_renderer_transfer_send_iov(struct vrend_resource *res,
return 0;
}
int vrend_renderer_transfer_iov(uint32_t dst_handle,
const struct vrend_transfer_info *info,
int transfer_mode)
static int vrend_renderer_transfer_internal(struct vrend_context *ctx,
struct vrend_resource *res,
const struct vrend_transfer_info *info,
int transfer_mode)
{
struct vrend_resource *res;
struct vrend_context *ctx;
const struct iovec *iov;
int num_iovs;
if (!info->box)
return EINVAL;
if (info->ctx_id == 0) {
ctx = vrend_state.ctx0;
res = vrend_renderer_res_lookup(dst_handle);
} else {
ctx = vrend_lookup_renderer_ctx(info->ctx_id);
if (!ctx)
return EINVAL;
res = vrend_renderer_ctx_res_lookup(ctx, dst_handle);
}
if (!res) {
if (info->ctx_id)
vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
return EINVAL;
}
void* fence = NULL;
#ifdef HAVE_EPOXY_EGL_H
// Some platforms require extra synchronization before transferring.
@ -7672,8 +7655,8 @@ int vrend_renderer_transfer_iov(uint32_t dst_handle,
}
if (!iov) {
if (info->ctx_id)
vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
if (ctx != vrend_state.ctx0)
vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res->handle);
return EINVAL;
}
@ -7711,6 +7694,32 @@ int vrend_renderer_transfer_iov(uint32_t dst_handle,
return 0;
}
int vrend_renderer_transfer_iov(struct vrend_context *ctx,
uint32_t dst_handle,
const struct vrend_transfer_info *info,
int transfer_mode)
{
struct vrend_resource *res;
res = vrend_renderer_ctx_res_lookup(ctx, dst_handle);
if (!res) {
vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
return EINVAL;
}
return vrend_renderer_transfer_internal(ctx, res, info,
transfer_mode);
}
int vrend_renderer_transfer_pipe(struct pipe_resource *pres,
const struct vrend_transfer_info *info,
int transfer_mode)
{
struct vrend_resource *res = (struct vrend_resource *)pres;
return vrend_renderer_transfer_internal(vrend_state.ctx0, res, info,
transfer_mode);
}
int vrend_transfer_inline_write(struct vrend_context *ctx,
uint32_t dst_handle,
const struct vrend_transfer_info *info)
@ -10008,8 +10017,9 @@ void vrend_renderer_get_rect(struct pipe_resource *pres,
transfer_info.iovec = iov;
transfer_info.iovec_cnt = num_iovs;
transfer_info.context0 = true;
vrend_renderer_transfer_iov(res->handle, &transfer_info,
VIRGL_TRANSFER_FROM_HOST);
vrend_renderer_transfer_pipe(pres, &transfer_info,
VIRGL_TRANSFER_FROM_HOST);
}
void vrend_renderer_attach_res_ctx(struct vrend_context *ctx,

@ -289,10 +289,15 @@ void vrend_set_framebuffer_state_no_attach(struct vrend_context *ctx,
void vrend_texture_barrier(struct vrend_context *ctx,
unsigned flags);
int vrend_renderer_transfer_iov(uint32_t dst_handle,
int vrend_renderer_transfer_iov(struct vrend_context *ctx,
uint32_t dst_handle,
const struct vrend_transfer_info *info,
int transfer_mode);
int vrend_renderer_transfer_pipe(struct pipe_resource *pres,
const struct vrend_transfer_info *info,
int transfer_mode);
void vrend_renderer_resource_copy_region(struct vrend_context *ctx,
uint32_t dst_handle, uint32_t dst_level,
uint32_t dstx, uint32_t dsty, uint32_t dstz,

Loading…
Cancel
Save