Mesa (master): tu: Fix buffer compressed pitch calculation with unaligned sizes

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue May 19 20:18:41 UTC 2020


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

Author: Connor Abbott <cwabbott0 at gmail.com>
Date:   Tue May 19 13:30:37 2020 +0200

tu: Fix buffer compressed pitch calculation with unaligned sizes

We can just set the extent and not bufferRowLength/bufferImageHeight,
and the extent may not be a multiple of the block size if it covers the
entire image. In this case we have to first divide to get the
width/height in terms of blocks, and then multiply by the block size to
get the buffer's pitch and layer size. Multiplying and dividing instead
won't get the correct result when the extent covers the entire image and
isn't a multiple of the block size. This also makes the code easier to
follow because we don't calculate a pitch in non-sensical units (bytes
times the block width) as an intermediate step.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5098>

---

 src/freedreno/vulkan/tu_clear_blit.c | 31 ++++++++++++++++++-------------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/src/freedreno/vulkan/tu_clear_blit.c b/src/freedreno/vulkan/tu_clear_blit.c
index 2b6668a1785..35a4ccd3fe6 100644
--- a/src/freedreno/vulkan/tu_clear_blit.c
+++ b/src/freedreno/vulkan/tu_clear_blit.c
@@ -1232,8 +1232,8 @@ static void
 copy_compressed(VkFormat format,
                 VkOffset3D *offset,
                 VkExtent3D *extent,
-                uint32_t *pitch,
-                uint32_t *layer_size)
+                uint32_t *width,
+                uint32_t *height)
 {
    if (!vk_format_is_compressed(format))
       return;
@@ -1248,10 +1248,10 @@ copy_compressed(VkFormat format,
       extent->width = DIV_ROUND_UP(extent->width, block_width);
       extent->height = DIV_ROUND_UP(extent->height, block_height);
    }
-   if (pitch)
-      *pitch /= block_width;
-   if (layer_size)
-      *layer_size /= (block_width * block_height);
+   if (width)
+      *width = DIV_ROUND_UP(*width, block_width);
+   if (height)
+      *height = DIV_ROUND_UP(*height, block_height);
 }
 
 static void
@@ -1283,16 +1283,18 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmd,
 
    VkOffset3D offset = info->imageOffset;
    VkExtent3D extent = info->imageExtent;
-   uint32_t pitch =
-      (info->bufferRowLength ?: extent.width) * vk_format_get_blocksize(src_format);
-   uint32_t layer_size = (info->bufferImageHeight ?: extent.height) * pitch;
+   uint32_t src_width = info->bufferRowLength ?: extent.width;
+   uint32_t src_height = info->bufferImageHeight ?: extent.height;
 
    if (dst_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || vk_format_is_compressed(src_format)) {
       assert(src_format == dst_format);
-      copy_compressed(dst_format, &offset, &extent, &pitch, &layer_size);
+      copy_compressed(dst_format, &offset, &extent, &src_width, &src_height);
       src_format = dst_format = copy_format(dst_format);
    }
 
+   uint32_t pitch = src_width * vk_format_get_blocksize(src_format);
+   uint32_t layer_size = src_height * pitch;
+
    /* note: the src_va/pitch alignment of 64 is for 2D engine,
     * it is also valid for 1cpp format with shader path (stencil aspect path)
     */
@@ -1364,15 +1366,18 @@ tu_copy_image_to_buffer(struct tu_cmd_buffer *cmd,
    const struct blit_ops *ops = stencil_read ? &r3d_ops : &r2d_ops;
    VkOffset3D offset = info->imageOffset;
    VkExtent3D extent = info->imageExtent;
-   uint32_t pitch = (info->bufferRowLength ?: extent.width) * vk_format_get_blocksize(dst_format);
-   uint32_t layer_size = (info->bufferImageHeight ?: extent.height) * pitch;
+   uint32_t dst_width = info->bufferRowLength ?: extent.width;
+   uint32_t dst_height = info->bufferImageHeight ?: extent.height;
 
    if (dst_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || vk_format_is_compressed(dst_format)) {
       assert(src_format == dst_format);
-      copy_compressed(dst_format, &offset, &extent, &pitch, &layer_size);
+      copy_compressed(dst_format, &offset, &extent, &dst_width, &dst_height);
       src_format = dst_format = copy_format(dst_format);
    }
 
+   uint32_t pitch = dst_width * vk_format_get_blocksize(dst_format);
+   uint32_t layer_size = pitch * dst_height;
+
    /* note: the dst_va/pitch alignment of 64 is for 2D engine,
     * it is also valid for 1cpp format with shader path (stencil aspect)
     */



More information about the mesa-commit mailing list