Module: Mesa
Branch: master
Commit: d40e372fe9774c3fb93c14a7f3e588daef88ce86
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=d40e372fe9774c3fb93c14a7f3e588daef88ce86

Author: Mike Blumenkrantz <[email protected]>
Date:   Wed Oct  7 15:55:16 2020 -0400

zink: move buffer<->image copying to pipe_context::resource_copy_region hook

that's a todo item off the list

Reviewed-by: Dave Airlie <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9566>

---

 src/gallium/drivers/zink/zink_context.c  | 81 +++++++++++++++++++++++++++++-
 src/gallium/drivers/zink/zink_context.h  |  5 ++
 src/gallium/drivers/zink/zink_resource.c | 85 ++++++--------------------------
 3 files changed, 98 insertions(+), 73 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_context.c 
b/src/gallium/drivers/zink/zink_context.c
index d2d38f24408..fb234d1c837 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -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, &region);
 }
 
+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, &region);
+      else
+         vkCmdCopyImageToBuffer(batch->cmdbuf, img->image, img->layout, 
buf->buffer, 1, &region);
+   }
+}
+
 static void
 zink_resource_copy_region(struct pipe_context *pctx,
                           struct pipe_resource *pdst,
@@ -1911,8 +1989,7 @@ zink_resource_copy_region(struct pipe_context *pctx,
               src->base.target == PIPE_BUFFER) {
       zink_copy_buffer(ctx, NULL, dst, src, dstx, src_box->x, src_box->width);
    } else
-      debug_printf("zink: TODO resource copy\n");
-      //util_range_add(dst, &dst->valid_buffer_range, dstx, dstx + 
src_box->width);
+      zink_copy_image_buffer(ctx, NULL, dst, src, dst_level, dstx, dsty, dstz, 
src_level, src_box, 0);
 }
 
 static struct pipe_stream_output_target *
diff --git a/src/gallium/drivers/zink/zink_context.h 
b/src/gallium/drivers/zink/zink_context.h
index 47c29614c54..5db1b421f5c 100644
--- a/src/gallium/drivers/zink/zink_context.h
+++ b/src/gallium/drivers/zink/zink_context.h
@@ -328,6 +328,11 @@ void
 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);
 
+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
 zink_context_update_descriptor_states(struct zink_context *ctx, bool 
is_compute);
 
diff --git a/src/gallium/drivers/zink/zink_resource.c 
b/src/gallium/drivers/zink/zink_resource.c
index 1b5f71338b2..0949c835dbd 100644
--- a/src/gallium/drivers/zink/zink_resource.c
+++ b/src/gallium/drivers/zink/zink_resource.c
@@ -522,76 +522,24 @@ zink_resource_from_handle(struct pipe_screen *pscreen,
 #endif
 }
 
-static bool
+static void
 zink_transfer_copy_bufimage(struct zink_context *ctx,
-                            struct zink_resource *res,
-                            struct zink_resource *staging_res,
-                            struct zink_transfer *trans,
-                            bool buf2img)
+                            struct zink_resource *dst,
+                            struct zink_resource *src,
+                            struct zink_transfer *trans)
 {
-   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)) 
!=
           (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:
-       *
-       * 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, &copyRegion);
-      else
-         vkCmdCopyImageToBuffer(batch->cmdbuf, res->image, res->layout, 
staging_res->buffer, 1, &copyRegion);
-   }
+   bool buf2img = src->base.target == PIPE_BUFFER;
 
-   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
@@ -722,12 +670,7 @@ zink_transfer_map(struct pipe_context *pctx,
                /* don't actually have to stall here, only ensure batch is 
submitted */
                zink_flush_compute(ctx);
             struct zink_context *ctx = zink_context(pctx);
-            bool ret = zink_transfer_copy_bufimage(ctx, res,
-                                                   staging_res, trans,
-                                                   false);
-            if (ret == false)
-               return NULL;
-
+            zink_transfer_copy_bufimage(ctx, staging_res, res, trans);
             /* need to wait for rendering to finish */
             zink_fence_wait(pctx);
          }
@@ -800,7 +743,7 @@ zink_transfer_flush_region(struct pipe_context *pctx,
          if (ptrans->resource->target == PIPE_BUFFER)
             zink_copy_buffer(ctx, NULL, res, staging_res, box->x, box->x, 
box->width);
          else
-            zink_transfer_copy_bufimage(ctx, res, staging_res, trans, true);
+            zink_transfer_copy_bufimage(ctx, res, staging_res, trans);
          if (batch_uses)
             pctx->flush(pctx, NULL, 0);
       }

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to