freedreno/layout: add explicit offset/pitch argument to fdl6_layout
authorJonathan Marek <jonathan@marek.ca>
Tue, 12 May 2020 23:38:48 +0000 (19:38 -0400)
committerMarge Bot <eric+marge@anholt.net>
Wed, 27 May 2020 04:02:58 +0000 (04:02 +0000)
fdl6_layout will return false when the explicit pitch is not valid.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4596>

src/freedreno/fdl/fd6_layout.c
src/freedreno/fdl/fd_layout_test.c
src/freedreno/fdl/freedreno_layout.h
src/freedreno/vulkan/tu_clear_blit.c
src/freedreno/vulkan/tu_image.c
src/gallium/drivers/freedreno/a6xx/fd6_resource.c

index ea71da8918fc6d3dbb65b07b8bb38bfee2f17dbf..20aec1fdb9a777531ccd8400b4896d7b6db5d301 100644 (file)
@@ -90,12 +90,16 @@ fdl6_pitchalign(struct fdl_layout *layout, int level)
 /* NOTE: good way to test this is:  (for example)
  *  piglit/bin/texelFetch fs sampler3D 100x100x8
  */
-void
+bool
 fdl6_layout(struct fdl_layout *layout,
                enum pipe_format format, uint32_t nr_samples,
                uint32_t width0, uint32_t height0, uint32_t depth0,
-               uint32_t mip_levels, uint32_t array_size, bool is_3d)
+               uint32_t mip_levels, uint32_t array_size, bool is_3d,
+               struct fdl_slice *plane_layout)
 {
+       uint32_t offset;
+       uint32_t pitch0;
+
        assert(nr_samples > 0);
        layout->width0 = width0;
        layout->height0 = height0;
@@ -129,7 +133,18 @@ fdl6_layout(struct fdl_layout *layout,
                layout->base_align = 64;
        }
 
-       uint32_t pitch0 = util_align_npot(width0, fdl6_pitchalign(layout, 0));
+       if (plane_layout) {
+               offset = plane_layout->offset;
+               pitch0 = plane_layout->pitch;
+               if (align(pitch0, fdl6_pitchalign(layout, 0) * layout->cpp) != pitch0)
+                       return false;
+               pitch0 /= layout->cpp; /* explicit pitch is in bytes */
+               if (pitch0 < width0 && height0 > 1)
+                       return false;
+       } else {
+               offset = 0;
+               pitch0 = util_align_npot(width0, fdl6_pitchalign(layout, 0));
+       }
 
        uint32_t ubwc_width0 = width0;
        uint32_t ubwc_height0 = height0;
@@ -182,7 +197,7 @@ fdl6_layout(struct fdl_layout *layout,
                        util_align_npot(util_format_get_nblocksx(format, u_minify(pitch0, level)),
                                        fdl6_pitchalign(layout, level));
 
-               slice->offset = layout->size;
+               slice->offset = offset + layout->size;
                uint32_t blocks = nblocksx * nblocksy;
 
                slice->pitch = nblocksx * layout->cpp;
@@ -216,7 +231,7 @@ fdl6_layout(struct fdl_layout *layout,
 
                        ubwc_slice->size0 = align(meta_pitch * meta_height, UBWC_PLANE_SIZE_ALIGNMENT);
                        ubwc_slice->pitch = meta_pitch;
-                       ubwc_slice->offset = layout->ubwc_layer_size;
+                       ubwc_slice->offset = offset + layout->ubwc_layer_size;
                        layout->ubwc_layer_size += ubwc_slice->size0;
                }
        }
@@ -236,6 +251,11 @@ fdl6_layout(struct fdl_layout *layout,
                        layout->slices[level].offset += layout->ubwc_layer_size * array_size;
                layout->size += layout->ubwc_layer_size * array_size;
        }
+
+       /* include explicit offset in size */
+       layout->size += offset;
+
+       return true;
 }
 
 void
index f0bdecf925877c30f7bbe6120aa6876398c18750..03174e5868838166924ca9388ef5994e83aaf3c4 100644 (file)
@@ -52,7 +52,8 @@ bool fdl_test_layout(const struct testcase *testcase, int gpu_id)
                                MAX2(testcase->layout.depth0, 1),
                                mip_levels,
                                MAX2(testcase->array_size, 1),
-                               testcase->is_3d);
+                               testcase->is_3d,
+                               NULL);
        } else {
                assert(gpu_id >= 500);
                fdl5_layout(&layout,
index 6753890bf4a1c7a0c761150226c2999ce946dbd2..ec4090066ca8afd66ead4c21841dc7905da5fa35 100644 (file)
@@ -190,11 +190,12 @@ fdl5_layout(struct fdl_layout *layout,
                uint32_t width0, uint32_t height0, uint32_t depth0,
                uint32_t mip_levels, uint32_t array_size, bool is_3d);
 
-void
+bool
 fdl6_layout(struct fdl_layout *layout,
                enum pipe_format format, uint32_t nr_samples,
                uint32_t width0, uint32_t height0, uint32_t depth0,
-               uint32_t mip_levels, uint32_t array_size, bool is_3d);
+               uint32_t mip_levels, uint32_t array_size, bool is_3d,
+               struct fdl_slice *plane_layout);
 
 void
 fdl_dump_layout(struct fdl_layout *layout);
index 48e49b224d2189e67f6c93d705b10db2e6644095..c200c8d97750d80700115da0e9b4f7b80aae7d28 100644 (file)
@@ -1580,7 +1580,8 @@ tu_copy_image_to_image(struct tu_cmd_buffer *cmd,
                   staging_image.extent.depth,
                   staging_image.level_count,
                   staging_image.layer_count,
-                  staging_image.type == VK_IMAGE_TYPE_3D);
+                  staging_image.type == VK_IMAGE_TYPE_3D,
+                  NULL);
 
       VkResult result = tu_get_scratch_bo(cmd->device,
                                           staging_image.layout.size,
index de8b6dc3f0d146a11606a64e385da700d5aacf58..3e16f81290476aa6545b4098aacf38c576a4deb5 100644 (file)
@@ -157,7 +157,8 @@ tu_image_create(VkDevice _device,
                pCreateInfo->extent.depth,
                pCreateInfo->mipLevels,
                pCreateInfo->arrayLayers,
-               pCreateInfo->imageType == VK_IMAGE_TYPE_3D);
+               pCreateInfo->imageType == VK_IMAGE_TYPE_3D,
+               NULL);
 
    *pImage = tu_image_to_handle(image);
 
index 73434e0e41c5db4cac3fa99142b34c3da878ce98..c3e349395797ee7733007eb6a09f8a331ed508ed 100644 (file)
@@ -153,7 +153,8 @@ fd6_setup_slices(struct fd_resource *rsc)
        fdl6_layout(&rsc->layout, prsc->format, fd_resource_nr_samples(prsc),
                        prsc->width0, prsc->height0, prsc->depth0,
                        prsc->last_level + 1, prsc->array_size,
-                       prsc->target == PIPE_TEXTURE_3D);
+                       prsc->target == PIPE_TEXTURE_3D,
+                       NULL);
 
        return rsc->layout.size;
 }
@@ -175,18 +176,11 @@ fill_ubwc_buffer_sizes(struct fd_resource *rsc)
        rsc->layout.ubwc = true;
        rsc->layout.tile_mode = TILE6_3;
 
-       fdl6_layout(&rsc->layout, prsc->format, fd_resource_nr_samples(prsc),
+       if (!fdl6_layout(&rsc->layout, prsc->format, fd_resource_nr_samples(prsc),
                        prsc->width0, prsc->height0, prsc->depth0,
-                       prsc->last_level + 1, prsc->array_size, false);
-
-       if (fd_resource_slice(rsc, 0)->pitch != slice.pitch)
+                       prsc->last_level + 1, prsc->array_size, false, &slice))
                return -1;
 
-       /* The imported buffer may specify an offset, add that in here. */
-       rsc->layout.slices[0].offset += slice.offset;
-       rsc->layout.ubwc_slices[0].offset += slice.offset;
-       rsc->layout.size += slice.offset;
-
        if (rsc->layout.size > fd_bo_size(rsc->bo))
                return -1;