diff --git a/src/gallium/drivers/virgl/virgl_buffer.c b/src/gallium/drivers/virgl/virgl_buffer.c index ed001722ab4..93ccaeee995 100644 --- a/src/gallium/drivers/virgl/virgl_buffer.c +++ b/src/gallium/drivers/virgl/virgl_buffer.c @@ -112,7 +112,7 @@ static void virgl_buffer_transfer_unmap(struct pipe_context *ctx, trans->offset = transfer->box.x; } - if (trans->copy_src_res) { + if (trans->copy_src_hw_res) { virgl_encode_copy_transfer(vctx, trans); /* It's now safe for other mappings to use the transfer_uploader. */ vctx->transfer_uploader_in_use = false; diff --git a/src/gallium/drivers/virgl/virgl_encode.c b/src/gallium/drivers/virgl/virgl_encode.c index 2975e6048cf..0489f088012 100644 --- a/src/gallium/drivers/virgl/virgl_encode.c +++ b/src/gallium/drivers/virgl/virgl_encode.c @@ -1168,16 +1168,17 @@ void virgl_encode_copy_transfer(struct virgl_context *ctx, struct virgl_transfer *trans) { uint32_t command; - struct virgl_resource *copy_src_res = virgl_resource(trans->copy_src_res); struct virgl_screen *vs = virgl_screen(ctx->base.screen); + assert(trans->copy_src_hw_res); + command = VIRGL_CMD0(VIRGL_CCMD_COPY_TRANSFER3D, 0, VIRGL_COPY_TRANSFER3D_SIZE); virgl_encoder_write_cmd_dword(ctx, command); /* Copy transfers need to explicitly specify the stride, since it may differ * from the image stride. */ virgl_encoder_transfer3d_common(vs, ctx->cbuf, trans, virgl_transfer3d_explicit_stride); - virgl_encoder_emit_resource(vs, ctx->cbuf, copy_src_res); + vs->vws->emit_res(vs->vws, ctx->cbuf, trans->copy_src_hw_res, TRUE); virgl_encoder_write_dword(ctx->cbuf, trans->copy_src_offset); /* At the moment all copy transfers are synchronized. */ virgl_encoder_write_dword(ctx->cbuf, 1); diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c index 5e372de7f15..24f388f86ec 100644 --- a/src/gallium/drivers/virgl/virgl_resource.c +++ b/src/gallium/drivers/virgl/virgl_resource.c @@ -461,7 +461,7 @@ virgl_resource_create_transfer(struct virgl_context *vctx, trans->base.layer_stride = metadata->layer_stride[level]; trans->offset = offset; util_range_init(&trans->range); - trans->copy_src_res = NULL; + trans->copy_src_hw_res = NULL; trans->copy_src_offset = 0; if (trans->base.resource->target != PIPE_TEXTURE_3D && @@ -481,7 +481,7 @@ void virgl_resource_destroy_transfer(struct virgl_context *vctx, { struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; - pipe_resource_reference(&trans->copy_src_res, NULL); + vws->resource_reference(vws, &trans->copy_src_hw_res, NULL); util_range_destroy(&trans->range); vws->resource_reference(vws, &trans->hw_res, NULL); @@ -569,6 +569,7 @@ void *virgl_transfer_uploader_map(struct virgl_context *vctx, struct virgl_transfer *vtransfer) { struct virgl_resource *vres = virgl_resource(vtransfer->base.resource); + struct pipe_resource *copy_src_res = NULL; unsigned size; unsigned align_offset; unsigned stride; @@ -600,8 +601,15 @@ void *virgl_transfer_uploader_map(struct virgl_context *vctx, u_upload_alloc(vctx->transfer_uploader, 0, size + align_offset, VIRGL_MAP_BUFFER_ALIGNMENT, &vtransfer->copy_src_offset, - &vtransfer->copy_src_res, &map_addr); + ©_src_res, &map_addr); if (map_addr) { + struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws; + + /* Extract and reference the hw_res backing the pipe_resource. */ + vws->resource_reference(vws, &vtransfer->copy_src_hw_res, + virgl_resource(copy_src_res)->hw_res); + pipe_resource_reference(©_src_res, NULL); + /* Update source offset and address to point to the requested x coordinate * if we have an align_offset (see above for more information). */ vtransfer->copy_src_offset += align_offset; diff --git a/src/gallium/drivers/virgl/virgl_resource.h b/src/gallium/drivers/virgl/virgl_resource.h index f9439a9489f..d390f1ce3cd 100644 --- a/src/gallium/drivers/virgl/virgl_resource.h +++ b/src/gallium/drivers/virgl/virgl_resource.h @@ -96,7 +96,7 @@ struct virgl_transfer { * that the transfer source data should be taken from this * resource instead of the original transfer resource. */ - struct pipe_resource *copy_src_res; + struct virgl_hw_res *copy_src_hw_res; /* The offset in the copy source resource to copy data from. */ uint32_t copy_src_offset; }; diff --git a/src/gallium/drivers/virgl/virgl_texture.c b/src/gallium/drivers/virgl/virgl_texture.c index 3c5737c5d17..1553d41a072 100644 --- a/src/gallium/drivers/virgl/virgl_texture.c +++ b/src/gallium/drivers/virgl/virgl_texture.c @@ -355,7 +355,7 @@ static void virgl_texture_transfer_unmap(struct pipe_context *ctx, } if (queue_unmap) { - if (trans->copy_src_res) { + if (trans->copy_src_hw_res) { virgl_encode_copy_transfer(vctx, trans); /* It's now safe for other mappings to use the transfer_uploader. */ vctx->transfer_uploader_in_use = false; diff --git a/src/gallium/drivers/virgl/virgl_transfer_queue.c b/src/gallium/drivers/virgl/virgl_transfer_queue.c index 33f8b62f4a3..970ee986cc1 100644 --- a/src/gallium/drivers/virgl/virgl_transfer_queue.c +++ b/src/gallium/drivers/virgl/virgl_transfer_queue.c @@ -289,7 +289,7 @@ int virgl_transfer_queue_unmap(struct virgl_transfer_queue *queue, struct list_iteration_args iter; /* We don't support copy transfers in the transfer queue. */ - assert(!transfer->copy_src_res); + assert(!transfer->copy_src_hw_res); /* Attempt to merge multiple intersecting transfers into a single one. */ if (transfer->base.resource->target == PIPE_BUFFER) { @@ -364,7 +364,7 @@ virgl_transfer_queue_extend(struct virgl_transfer_queue *queue, struct list_iteration_args iter; /* We don't support extending from copy transfers. */ - assert(!transfer->copy_src_res); + assert(!transfer->copy_src_hw_res); if (transfer->base.resource->target == PIPE_BUFFER) { memset(&iter, 0, sizeof(iter));