Module: Mesa
Branch: main
Commit: 4d9329ee90d0cdec5e7e4689b6cd6a81e3dd65a2
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=4d9329ee90d0cdec5e7e4689b6cd6a81e3dd65a2

Author: Boris Brezillon <[email protected]>
Date:   Wed Sep  8 09:56:04 2021 +0200

panvk: Implement vkCmdBlitImage()

Signed-off-by: Boris Brezillon <[email protected]>
Reviewed-by: Tomeu Vizoso <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12961>

---

 src/panfrost/vulkan/panvk_vX_meta_blit.c | 167 ++++++++++++++++++++++++++++++-
 1 file changed, 165 insertions(+), 2 deletions(-)

diff --git a/src/panfrost/vulkan/panvk_vX_meta_blit.c 
b/src/panfrost/vulkan/panvk_vX_meta_blit.c
index c04ed4a9782..f1247e8c5ef 100644
--- a/src/panfrost/vulkan/panvk_vX_meta_blit.c
+++ b/src/panfrost/vulkan/panvk_vX_meta_blit.c
@@ -27,6 +27,115 @@
 
 #include "panvk_private.h"
 
+static void
+panvk_meta_blit(struct panvk_cmd_buffer *cmdbuf,
+                const struct pan_blit_info *blitinfo)
+{
+   struct panfrost_device *pdev = &cmdbuf->device->physical_device->pdev;
+   struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info;
+   struct pan_blit_context ctx;
+   struct pan_image_view views[2] = {
+      {
+         .format = blitinfo->dst.planes[0].format,
+         .dim = MALI_TEXTURE_DIMENSION_2D,
+         .image = blitinfo->dst.planes[0].image,
+         .nr_samples = blitinfo->dst.planes[0].image->layout.nr_samples,
+         .first_level = blitinfo->dst.level,
+         .last_level = blitinfo->dst.level,
+         .swizzle = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, 
PIPE_SWIZZLE_W },
+      },
+   };
+
+   *fbinfo = (struct pan_fb_info){
+      .width = u_minify(blitinfo->dst.planes[0].image->layout.width, 
blitinfo->dst.level),
+      .height = u_minify(blitinfo->dst.planes[0].image->layout.height, 
blitinfo->dst.level),
+      .extent = {
+         .minx = MAX2(MIN2(blitinfo->dst.start.x, blitinfo->dst.end.x), 0),
+         .miny = MAX2(MIN2(blitinfo->dst.start.y, blitinfo->dst.end.y), 0),
+         .maxx = MAX2(blitinfo->dst.start.x, blitinfo->dst.end.x),
+         .maxy = MAX2(blitinfo->dst.start.y, blitinfo->dst.end.y),
+      },
+      .nr_samples = blitinfo->dst.planes[0].image->layout.nr_samples,
+   };
+
+   fbinfo->extent.maxx = MIN2(fbinfo->extent.maxx, fbinfo->width - 1);
+   fbinfo->extent.maxy = MIN2(fbinfo->extent.maxy, fbinfo->height - 1);
+
+   /* TODO: don't force preloads of dst resources if unneeded */
+
+   const struct util_format_description *fdesc =
+      util_format_description(blitinfo->dst.planes[0].image->layout.format);
+
+   if (util_format_has_depth(fdesc)) {
+      /* We want the image format here, otherwise we might lose one of the
+       * component.
+       */
+      views[0].format = blitinfo->dst.planes[0].image->layout.format;
+      fbinfo->zs.view.zs = &views[0];
+      fbinfo->zs.preload.z = true;
+      fbinfo->zs.preload.s = util_format_has_stencil(fdesc);
+   } else if (util_format_has_stencil(fdesc)) {
+      fbinfo->zs.view.s = &views[0];
+      fbinfo->zs.preload.s = true;
+   } else {
+      fbinfo->rt_count = 1;
+      fbinfo->rts[0].view = &views[0];
+      fbinfo->rts[0].preload = true;
+      cmdbuf->state.fb.crc_valid[0] = false;
+      fbinfo->rts[0].crc_valid = &cmdbuf->state.fb.crc_valid[0];
+   }
+
+   if (blitinfo->dst.planes[1].format != PIPE_FORMAT_NONE) {
+      /* TODO: don't force preloads of dst resources if unneeded */
+      views[1].format = blitinfo->dst.planes[1].format;
+      views[1].dim = MALI_TEXTURE_DIMENSION_2D;
+      views[1].image = blitinfo->dst.planes[1].image;
+      views[1].nr_samples = blitinfo->dst.planes[1].image->layout.nr_samples;
+      views[1].first_level = blitinfo->dst.level;
+      views[1].last_level = blitinfo->dst.level;
+      views[1].swizzle[0] = PIPE_SWIZZLE_X;
+      views[1].swizzle[1] = PIPE_SWIZZLE_Y;
+      views[1].swizzle[2] = PIPE_SWIZZLE_Z;
+      views[1].swizzle[3] = PIPE_SWIZZLE_W;
+      fbinfo->zs.view.s = &views[1];
+   }
+
+   if (cmdbuf->state.batch)
+      panvk_per_arch(cmd_close_batch)(cmdbuf);
+
+   GENX(pan_blit_ctx_init)(pdev, blitinfo, &cmdbuf->desc_pool.base, &ctx);
+   do {
+      if (ctx.dst.cur_layer < 0)
+         continue;
+
+      panvk_cmd_open_batch(cmdbuf);
+
+      struct panvk_batch *batch = cmdbuf->state.batch;
+      mali_ptr tsd, tiler;
+
+      views[0].first_layer = views[0].last_layer = ctx.dst.cur_layer;
+      views[1].first_layer = views[1].last_layer = views[0].first_layer;
+      batch->blit.src = blitinfo->src.planes[0].image->data.bo;
+      batch->blit.dst = blitinfo->dst.planes[0].image->data.bo;
+      panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true);
+      panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf);
+      panvk_per_arch(cmd_prepare_tiler_context)(cmdbuf);
+
+#if PAN_ARCH >= 6
+      tsd = batch->tls.gpu;
+      tiler = batch->tiler.descs.gpu;
+#else
+      tsd = batch->fb.desc.gpu;
+      tiler = 0;
+#endif
+
+      struct panfrost_ptr job =
+         GENX(pan_blit)(&ctx, &cmdbuf->desc_pool.base, &batch->scoreboard, 
tsd, tiler);
+      util_dynarray_append(&batch->jobs, void *, job.cpu);
+      panvk_per_arch(cmd_close_batch)(cmdbuf);
+   } while (pan_blit_next_surface(&ctx));
+}
+
 void
 panvk_per_arch(CmdBlitImage)(VkCommandBuffer commandBuffer,
                              VkImage srcImage,
@@ -36,9 +145,63 @@ panvk_per_arch(CmdBlitImage)(VkCommandBuffer commandBuffer,
                              uint32_t regionCount,
                              const VkImageBlit *pRegions,
                              VkFilter filter)
-
 {
-   panvk_stub();
+   VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
+   VK_FROM_HANDLE(panvk_image, src, srcImage);
+   VK_FROM_HANDLE(panvk_image, dst, destImage);
+
+   for (unsigned i = 0; i < regionCount; i++) {
+      const VkImageBlit *region = &pRegions[i];
+      struct pan_blit_info info = {
+         .src = {
+            .planes[0].image = &src->pimage,
+            .planes[0].format = src->pimage.layout.format,
+            .level = region->srcSubresource.mipLevel,
+            .start = {
+               region->srcOffsets[0].x,
+               region->srcOffsets[0].y,
+               region->srcOffsets[0].z,
+               region->srcSubresource.baseArrayLayer,
+            },
+            .end = {
+               region->srcOffsets[1].x,
+               region->srcOffsets[1].y,
+               region->srcOffsets[1].z,
+               region->srcSubresource.baseArrayLayer + 
region->srcSubresource.layerCount - 1,
+            },
+         },
+         .dst = {
+            .planes[0].image = &dst->pimage,
+            .planes[0].format = dst->pimage.layout.format,
+            .level = region->dstSubresource.mipLevel,
+            .start = {
+               region->dstOffsets[0].x,
+               region->dstOffsets[0].y,
+               region->dstOffsets[0].z,
+               region->dstSubresource.baseArrayLayer,
+            },
+            .end = {
+               region->dstOffsets[1].x,
+               region->dstOffsets[1].y,
+               region->dstOffsets[1].z,
+               region->dstSubresource.baseArrayLayer + 
region->dstSubresource.layerCount - 1,
+            },
+         },
+         .nearest = filter == VK_FILTER_NEAREST,
+      };
+
+      if (region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+         info.src.planes[0].format = 
util_format_stencil_only(info.src.planes[0].format);
+      else if (region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
+         info.src.planes[0].format = 
util_format_get_depth_only(info.src.planes[0].format);
+
+      if (region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
+         info.dst.planes[0].format = 
util_format_stencil_only(info.dst.planes[0].format);
+      else if (region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
+         info.dst.planes[0].format = 
util_format_get_depth_only(info.dst.planes[0].format);
+
+      panvk_meta_blit(cmdbuf, &info);
+   }
 }
 
 void

Reply via email to