From df99fd7c758c65a500d1bcef25eeafb434b09ddd Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sun, 29 Mar 2020 15:37:16 -0700 Subject: [PATCH] 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 Tested-by: Gurchetan Singh Reviewed-by: Gurchetan Singh --- src/virgl_context.h | 6 +++++ src/virglrenderer.c | 40 ++++++++++++++++++++++++++--- src/vrend_decode.c | 14 ++++++++++- src/vrend_renderer.c | 60 ++++++++++++++++++++++++++------------------ src/vrend_renderer.h | 7 +++++- 5 files changed, 96 insertions(+), 31 deletions(-) diff --git a/src/virgl_context.h b/src/virgl_context.h index e6a8ae1..0393ba8 100644 --- a/src/virgl_context.h +++ b/src/virgl_context.h @@ -30,6 +30,7 @@ #include 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); diff --git a/src/virglrenderer.c b/src/virglrenderer.c index 1bd17ee..58f51ab 100644 --- a/src/virglrenderer.c +++ b/src/virglrenderer.c @@ -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, diff --git a/src/vrend_decode.c b/src/vrend_decode.c index 7281b7f..4b80606 100644 --- a/src/vrend_decode.c +++ b/src/vrend_decode.c @@ -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; } diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index ac34659..4aad24f 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -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, diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h index 6022cbf..7ed0e4b 100644 --- a/src/vrend_renderer.h +++ b/src/vrend_renderer.h @@ -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,