vrend: Support copy transfers

Support the copy_transfer3d command, which transfers data to a host
resource by copying from another staging resource. This is used
by the guest to avoid waiting in case it needs to write to a busy
resource.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Alexandros Frantzis 6 years ago committed by Gert Wollny
parent 1e2f540de5
commit 59064c6520
  1. 23
      src/vrend_decode.c
  2. 40
      src/vrend_renderer.c
  3. 4
      src/vrend_renderer.h

@ -1344,6 +1344,26 @@ static int vrend_decode_transfer3d(struct vrend_decode_ctx *ctx, int length, uin
return vrend_renderer_transfer_iov(&info, transfer_mode); return vrend_renderer_transfer_iov(&info, transfer_mode);
} }
static int vrend_decode_copy_transfer3d(struct vrend_decode_ctx *ctx, int length)
{
struct pipe_box box;
struct vrend_transfer_info info;
uint32_t src_handle;
if (length != VIRGL_COPY_TRANSFER3D_SIZE)
return EINVAL;
memset(&info, 0, sizeof(info));
info.box = &box;
vrend_decode_transfer_common(ctx, &info);
info.offset = get_buf_entry(ctx, VIRGL_COPY_TRANSFER3D_SRC_RES_OFFSET);
info.synchronized = (get_buf_entry(ctx, VIRGL_COPY_TRANSFER3D_SYNCHRONIZED) != 0);
src_handle = get_buf_entry(ctx, VIRGL_COPY_TRANSFER3D_SRC_RES_HANDLE);
return vrend_renderer_copy_transfer3d(ctx->grctx, &info, src_handle);
}
void vrend_renderer_context_create_internal(uint32_t handle, uint32_t nlen, void vrend_renderer_context_create_internal(uint32_t handle, uint32_t nlen,
const char *debug_name) const char *debug_name)
{ {
@ -1584,6 +1604,9 @@ int vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw)
case VIRGL_CCMD_TRANSFER3D: case VIRGL_CCMD_TRANSFER3D:
ret = vrend_decode_transfer3d(gdctx, len, ctx_id); ret = vrend_decode_transfer3d(gdctx, len, ctx_id);
break; break;
case VIRGL_CCMD_COPY_TRANSFER3D:
ret = vrend_decode_copy_transfer3d(gdctx, len);
break;
case VIRGL_CCMD_END_TRANSFERS: case VIRGL_CCMD_END_TRANSFERS:
ret = 0; ret = 0;
break; break;

@ -7140,6 +7140,44 @@ int vrend_transfer_inline_write(struct vrend_context *ctx,
} }
int vrend_renderer_copy_transfer3d(struct vrend_context *ctx,
struct vrend_transfer_info *info,
uint32_t src_handle)
{
struct vrend_resource *src_res, *dst_res;
src_res = vrend_renderer_ctx_res_lookup(ctx, src_handle);
dst_res = vrend_renderer_ctx_res_lookup(ctx, info->handle);
if (!src_res) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, src_handle);
return EINVAL;
}
if (!dst_res) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, info->handle);
return EINVAL;
}
if (!src_res->iov) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, info->handle);
return EINVAL;
}
if (!check_transfer_bounds(dst_res, info)) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, info->handle);
return EINVAL;
}
if (!check_iov_bounds(dst_res, info, src_res->iov, src_res->num_iovs)) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, info->handle);
return EINVAL;
}
return vrend_renderer_transfer_write_iov(ctx, dst_res, src_res->iov,
src_res->num_iovs, info);
}
void vrend_set_stencil_ref(struct vrend_context *ctx, void vrend_set_stencil_ref(struct vrend_context *ctx,
struct pipe_stencil_ref *ref) struct pipe_stencil_ref *ref)
{ {
@ -9045,6 +9083,8 @@ static void vrend_renderer_fill_caps_v2(int gl_ver, int gles_ver, union virgl_c
caps->v2.capability_bits |= VIRGL_CAP_3D_ASTC; caps->v2.capability_bits |= VIRGL_CAP_3D_ASTC;
caps->v2.capability_bits |= VIRGL_CAP_INDIRECT_INPUT_ADDR; caps->v2.capability_bits |= VIRGL_CAP_INDIRECT_INPUT_ADDR;
caps->v2.capability_bits |= VIRGL_CAP_COPY_TRANSFER;
} }
void vrend_renderer_fill_caps(uint32_t set, UNUSED uint32_t version, void vrend_renderer_fill_caps(uint32_t set, UNUSED uint32_t version,

@ -225,6 +225,10 @@ void vrend_set_num_vbo(struct vrend_context *ctx,
int vrend_transfer_inline_write(struct vrend_context *ctx, int vrend_transfer_inline_write(struct vrend_context *ctx,
struct vrend_transfer_info *info); struct vrend_transfer_info *info);
int vrend_renderer_copy_transfer3d(struct vrend_context *ctx,
struct vrend_transfer_info *info,
uint32_t src_handle);
void vrend_set_viewport_states(struct vrend_context *ctx, void vrend_set_viewport_states(struct vrend_context *ctx,
uint32_t start_slot, uint32_t num_viewports, uint32_t start_slot, uint32_t num_viewports,
const struct pipe_viewport_state *state); const struct pipe_viewport_state *state);

Loading…
Cancel
Save