zink: move buffer<->image copying to pipe_context::resource_copy_region hook
that's a todo item off the list Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9566>
This commit is contained in:
parent
88f41a8fa5
commit
d40e372fe9
|
@ -1841,6 +1841,84 @@ zink_copy_buffer(struct zink_context *ctx, struct zink_batch *batch, struct zink
|
||||||
vkCmdCopyBuffer(batch->cmdbuf, src->buffer, dst->buffer, 1, ®ion);
|
vkCmdCopyBuffer(batch->cmdbuf, src->buffer, dst->buffer, 1, ®ion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_copy_image_buffer(struct zink_context *ctx, struct zink_batch *batch, struct zink_resource *dst, struct zink_resource *src,
|
||||||
|
unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz,
|
||||||
|
unsigned src_level, const struct pipe_box *src_box, enum pipe_map_flags map_flags)
|
||||||
|
{
|
||||||
|
struct zink_resource *img = dst->base.target == PIPE_BUFFER ? src : dst;
|
||||||
|
struct zink_resource *buf = dst->base.target == PIPE_BUFFER ? dst : src;
|
||||||
|
|
||||||
|
if (!batch)
|
||||||
|
batch = zink_batch_no_rp(ctx);
|
||||||
|
|
||||||
|
bool buf2img = buf == src;
|
||||||
|
|
||||||
|
if (buf2img) {
|
||||||
|
zink_resource_image_barrier(ctx, batch, img, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0);
|
||||||
|
zink_resource_buffer_barrier(ctx, batch, buf, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||||
|
} else {
|
||||||
|
zink_resource_image_barrier(ctx, batch, img, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0, 0);
|
||||||
|
zink_resource_buffer_barrier(ctx, batch, buf, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||||
|
util_range_add(&dst->base, &dst->valid_buffer_range, dstx, dstx + src_box->width);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkBufferImageCopy region = {};
|
||||||
|
region.bufferOffset = buf2img ? src_box->x : dstx;
|
||||||
|
region.bufferRowLength = 0;
|
||||||
|
region.bufferImageHeight = 0;
|
||||||
|
region.imageSubresource.mipLevel = buf2img ? dst_level : src_level;
|
||||||
|
region.imageSubresource.layerCount = 1;
|
||||||
|
if (img->base.array_size > 1) {
|
||||||
|
region.imageSubresource.baseArrayLayer = buf2img ? dstz : src_box->z;
|
||||||
|
region.imageSubresource.layerCount = src_box->depth;
|
||||||
|
region.imageExtent.depth = 1;
|
||||||
|
} else {
|
||||||
|
region.imageOffset.z = buf2img ? dstz : src_box->z;
|
||||||
|
region.imageExtent.depth = src_box->depth;
|
||||||
|
}
|
||||||
|
region.imageOffset.x = buf2img ? dstx : src_box->x;
|
||||||
|
region.imageOffset.y = buf2img ? dsty : src_box->y;
|
||||||
|
|
||||||
|
region.imageExtent.width = src_box->width;
|
||||||
|
region.imageExtent.height = src_box->height;
|
||||||
|
|
||||||
|
zink_batch_reference_resource_rw(batch, img, buf2img);
|
||||||
|
zink_batch_reference_resource_rw(batch, buf, !buf2img);
|
||||||
|
|
||||||
|
/* we're using u_transfer_helper_deinterleave, which means we'll be getting PIPE_MAP_* usage
|
||||||
|
* to indicate whether to copy either the depth or stencil aspects
|
||||||
|
*/
|
||||||
|
unsigned aspects = 0;
|
||||||
|
if (map_flags) {
|
||||||
|
assert((map_flags & (PIPE_MAP_DEPTH_ONLY | PIPE_MAP_STENCIL_ONLY)) !=
|
||||||
|
(PIPE_MAP_DEPTH_ONLY | PIPE_MAP_STENCIL_ONLY));
|
||||||
|
if (map_flags & PIPE_MAP_DEPTH_ONLY)
|
||||||
|
aspects = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
|
else if (map_flags & PIPE_MAP_STENCIL_ONLY)
|
||||||
|
aspects = VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
|
}
|
||||||
|
if (!aspects)
|
||||||
|
aspects = img->aspect;
|
||||||
|
while (aspects) {
|
||||||
|
int aspect = 1 << u_bit_scan(&aspects);
|
||||||
|
region.imageSubresource.aspectMask = aspect;
|
||||||
|
|
||||||
|
/* this may or may not work with multisampled depth/stencil buffers depending on the driver implementation:
|
||||||
|
*
|
||||||
|
* srcImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT
|
||||||
|
* - vkCmdCopyImageToBuffer spec
|
||||||
|
*
|
||||||
|
* dstImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT
|
||||||
|
* - vkCmdCopyBufferToImage spec
|
||||||
|
*/
|
||||||
|
if (buf2img)
|
||||||
|
vkCmdCopyBufferToImage(batch->cmdbuf, buf->buffer, img->image, img->layout, 1, ®ion);
|
||||||
|
else
|
||||||
|
vkCmdCopyImageToBuffer(batch->cmdbuf, img->image, img->layout, buf->buffer, 1, ®ion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zink_resource_copy_region(struct pipe_context *pctx,
|
zink_resource_copy_region(struct pipe_context *pctx,
|
||||||
struct pipe_resource *pdst,
|
struct pipe_resource *pdst,
|
||||||
|
@ -1911,8 +1989,7 @@ zink_resource_copy_region(struct pipe_context *pctx,
|
||||||
src->base.target == PIPE_BUFFER) {
|
src->base.target == PIPE_BUFFER) {
|
||||||
zink_copy_buffer(ctx, NULL, dst, src, dstx, src_box->x, src_box->width);
|
zink_copy_buffer(ctx, NULL, dst, src, dstx, src_box->x, src_box->width);
|
||||||
} else
|
} else
|
||||||
debug_printf("zink: TODO resource copy\n");
|
zink_copy_image_buffer(ctx, NULL, dst, src, dst_level, dstx, dsty, dstz, src_level, src_box, 0);
|
||||||
//util_range_add(dst, &dst->valid_buffer_range, dstx, dstx + src_box->width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pipe_stream_output_target *
|
static struct pipe_stream_output_target *
|
||||||
|
|
|
@ -328,6 +328,11 @@ void
|
||||||
zink_copy_buffer(struct zink_context *ctx, struct zink_batch *batch, struct zink_resource *dst, struct zink_resource *src,
|
zink_copy_buffer(struct zink_context *ctx, struct zink_batch *batch, struct zink_resource *dst, struct zink_resource *src,
|
||||||
unsigned dst_offset, unsigned src_offset, unsigned size);
|
unsigned dst_offset, unsigned src_offset, unsigned size);
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_copy_image_buffer(struct zink_context *ctx, struct zink_batch *batch, struct zink_resource *dst, struct zink_resource *src,
|
||||||
|
unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz,
|
||||||
|
unsigned src_level, const struct pipe_box *src_box, enum pipe_map_flags map_flags);
|
||||||
|
|
||||||
void
|
void
|
||||||
zink_context_update_descriptor_states(struct zink_context *ctx, bool is_compute);
|
zink_context_update_descriptor_states(struct zink_context *ctx, bool is_compute);
|
||||||
|
|
||||||
|
|
|
@ -522,76 +522,24 @@ zink_resource_from_handle(struct pipe_screen *pscreen,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
zink_transfer_copy_bufimage(struct zink_context *ctx,
|
zink_transfer_copy_bufimage(struct zink_context *ctx,
|
||||||
struct zink_resource *res,
|
struct zink_resource *dst,
|
||||||
struct zink_resource *staging_res,
|
struct zink_resource *src,
|
||||||
struct zink_transfer *trans,
|
struct zink_transfer *trans)
|
||||||
bool buf2img)
|
|
||||||
{
|
{
|
||||||
struct zink_batch *batch = zink_batch_no_rp(ctx);
|
|
||||||
|
|
||||||
if (buf2img) {
|
|
||||||
zink_resource_image_barrier(ctx, batch, res, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0);
|
|
||||||
} else {
|
|
||||||
zink_resource_image_barrier(ctx, batch, res, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
VkBufferImageCopy copyRegion = {};
|
|
||||||
copyRegion.bufferOffset = staging_res->offset;
|
|
||||||
copyRegion.bufferRowLength = 0;
|
|
||||||
copyRegion.bufferImageHeight = 0;
|
|
||||||
copyRegion.imageSubresource.mipLevel = trans->base.level;
|
|
||||||
copyRegion.imageSubresource.layerCount = 1;
|
|
||||||
if (res->base.array_size > 1) {
|
|
||||||
copyRegion.imageSubresource.baseArrayLayer = trans->base.box.z;
|
|
||||||
copyRegion.imageSubresource.layerCount = trans->base.box.depth;
|
|
||||||
copyRegion.imageExtent.depth = 1;
|
|
||||||
} else {
|
|
||||||
copyRegion.imageOffset.z = trans->base.box.z;
|
|
||||||
copyRegion.imageExtent.depth = trans->base.box.depth;
|
|
||||||
}
|
|
||||||
copyRegion.imageOffset.x = trans->base.box.x;
|
|
||||||
copyRegion.imageOffset.y = trans->base.box.y;
|
|
||||||
|
|
||||||
copyRegion.imageExtent.width = trans->base.box.width;
|
|
||||||
copyRegion.imageExtent.height = trans->base.box.height;
|
|
||||||
|
|
||||||
zink_batch_reference_resource_rw(batch, res, buf2img);
|
|
||||||
zink_batch_reference_resource_rw(batch, staging_res, !buf2img);
|
|
||||||
|
|
||||||
/* we're using u_transfer_helper_deinterleave, which means we'll be getting PIPE_MAP_* usage
|
|
||||||
* to indicate whether to copy either the depth or stencil aspects
|
|
||||||
*/
|
|
||||||
unsigned aspects = 0;
|
|
||||||
assert((trans->base.usage & (PIPE_MAP_DEPTH_ONLY | PIPE_MAP_STENCIL_ONLY)) !=
|
assert((trans->base.usage & (PIPE_MAP_DEPTH_ONLY | PIPE_MAP_STENCIL_ONLY)) !=
|
||||||
(PIPE_MAP_DEPTH_ONLY | PIPE_MAP_STENCIL_ONLY));
|
(PIPE_MAP_DEPTH_ONLY | PIPE_MAP_STENCIL_ONLY));
|
||||||
if (trans->base.usage & PIPE_MAP_DEPTH_ONLY)
|
|
||||||
aspects = VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
||||||
else if (trans->base.usage & PIPE_MAP_STENCIL_ONLY)
|
|
||||||
aspects = VK_IMAGE_ASPECT_STENCIL_BIT;
|
|
||||||
else {
|
|
||||||
aspects = aspect_from_format(res->base.format);
|
|
||||||
}
|
|
||||||
while (aspects) {
|
|
||||||
int aspect = 1 << u_bit_scan(&aspects);
|
|
||||||
copyRegion.imageSubresource.aspectMask = aspect;
|
|
||||||
|
|
||||||
/* this may or may not work with multisampled depth/stencil buffers depending on the driver implementation:
|
bool buf2img = src->base.target == PIPE_BUFFER;
|
||||||
*
|
|
||||||
* srcImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT
|
|
||||||
* - vkCmdCopyImageToBuffer spec
|
|
||||||
*
|
|
||||||
* dstImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT
|
|
||||||
* - vkCmdCopyBufferToImage spec
|
|
||||||
*/
|
|
||||||
if (buf2img)
|
|
||||||
vkCmdCopyBufferToImage(batch->cmdbuf, staging_res->buffer, res->image, res->layout, 1, ©Region);
|
|
||||||
else
|
|
||||||
vkCmdCopyImageToBuffer(batch->cmdbuf, res->image, res->layout, staging_res->buffer, 1, ©Region);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
struct pipe_box box = trans->base.box;
|
||||||
|
int x = box.x;
|
||||||
|
if (buf2img)
|
||||||
|
box.x = src->offset;
|
||||||
|
|
||||||
|
zink_copy_image_buffer(ctx, NULL, dst, src, trans->base.level, buf2img ? x : dst->offset,
|
||||||
|
box.y, box.z, trans->base.level, &box, trans->base.usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
|
@ -722,12 +670,7 @@ zink_transfer_map(struct pipe_context *pctx,
|
||||||
/* don't actually have to stall here, only ensure batch is submitted */
|
/* don't actually have to stall here, only ensure batch is submitted */
|
||||||
zink_flush_compute(ctx);
|
zink_flush_compute(ctx);
|
||||||
struct zink_context *ctx = zink_context(pctx);
|
struct zink_context *ctx = zink_context(pctx);
|
||||||
bool ret = zink_transfer_copy_bufimage(ctx, res,
|
zink_transfer_copy_bufimage(ctx, staging_res, res, trans);
|
||||||
staging_res, trans,
|
|
||||||
false);
|
|
||||||
if (ret == false)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* need to wait for rendering to finish */
|
/* need to wait for rendering to finish */
|
||||||
zink_fence_wait(pctx);
|
zink_fence_wait(pctx);
|
||||||
}
|
}
|
||||||
|
@ -800,7 +743,7 @@ zink_transfer_flush_region(struct pipe_context *pctx,
|
||||||
if (ptrans->resource->target == PIPE_BUFFER)
|
if (ptrans->resource->target == PIPE_BUFFER)
|
||||||
zink_copy_buffer(ctx, NULL, res, staging_res, box->x, box->x, box->width);
|
zink_copy_buffer(ctx, NULL, res, staging_res, box->x, box->x, box->width);
|
||||||
else
|
else
|
||||||
zink_transfer_copy_bufimage(ctx, res, staging_res, trans, true);
|
zink_transfer_copy_bufimage(ctx, res, staging_res, trans);
|
||||||
if (batch_uses)
|
if (batch_uses)
|
||||||
pctx->flush(pctx, NULL, 0);
|
pctx->flush(pctx, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue