Mesa (main): freedreno/a6xx: Fix a bunch of 3D texture layout to match blob behavior.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Nov 15 22:46:48 UTC 2021


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

Author: Emma Anholt <emma at anholt.net>
Date:   Fri Nov  5 11:41:36 2021 -0700

freedreno/a6xx: Fix a bunch of 3D texture layout to match blob behavior.

This doesn't get all of the texelfetch sampler3d testcases working, but
it's sure a lot more.

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

---

 src/freedreno/ci/freedreno-a630-fails.txt |   1 -
 src/freedreno/fdl/fd6_layout.c            |  44 ++++--
 src/freedreno/fdl/fd6_layout_test.c       | 237 ++++++++++++++++++++++++++++++
 3 files changed, 266 insertions(+), 16 deletions(-)

diff --git a/src/freedreno/ci/freedreno-a630-fails.txt b/src/freedreno/ci/freedreno-a630-fails.txt
index 41e779d0ce2..c1be5994d51 100644
--- a/src/freedreno/ci/freedreno-a630-fails.txt
+++ b/src/freedreno/ci/freedreno-a630-fails.txt
@@ -377,7 +377,6 @@ spec at ext_transform_feedback@structs struct-array-elem run interface,Fail
 spec at ext_transform_feedback@tessellation triangle_fan flat_first,Fail
 spec at ext_transform_feedback@tessellation triangle_strip flat_first,Fail
 spec at glsl-1.30@execution at texelfetch fs sampler3d 1x129x9-98x129x9,Fail
-spec at glsl-1.30@execution at texelfetch fs sampler3d 98x129x1-98x129x9,Fail
 spec at glsl-1.30@execution at texelfetch fs sampler3d 98x1x9-98x129x9,Fail
 spec at glsl-1.50@execution at compatibility@clipping at gs-clip-vertex-const-accept,Fail
 spec at glsl-1.50@execution at compatibility@clipping at gs-clip-vertex-different-from-position,Fail
diff --git a/src/freedreno/fdl/fd6_layout.c b/src/freedreno/fdl/fd6_layout.c
index 44d062e8320..dd09a3c6d54 100644
--- a/src/freedreno/fdl/fd6_layout.c
+++ b/src/freedreno/fdl/fd6_layout.c
@@ -188,20 +188,15 @@ fdl6_layout(struct fdl_layout *layout, enum pipe_format format,
    ubwc_height0 = align(DIV_ROUND_UP(ubwc_height0, ubwc_blockheight),
                         ubwc_tile_height_alignment);
 
+   uint32_t min_3d_layer_size = 0;
+
    for (uint32_t level = 0; level < mip_levels; level++) {
       uint32_t depth = u_minify(depth0, level);
       struct fdl_slice *slice = &layout->slices[level];
       struct fdl_slice *ubwc_slice = &layout->ubwc_slices[level];
       uint32_t tile_mode = fdl_tile_mode(layout, level);
       uint32_t pitch = fdl_pitch(layout, level);
-      uint32_t height;
-
-      /* tiled levels of 3D textures are rounded up to PoT dimensions: */
-      if (is_3d && tile_mode) {
-         height = u_minify(util_next_power_of_two(height0), level);
-      } else {
-         height = u_minify(height0, level);
-      }
+      uint32_t height = u_minify(height0, level);
 
       uint32_t nblocksy = util_format_get_nblocksy(format, height);
       if (tile_mode)
@@ -219,17 +214,36 @@ fdl6_layout(struct fdl_layout *layout, enum pipe_format format,
 
       slice->offset = offset + layout->size;
 
-      /* 1d array and 2d array textures must all have the same layer size
-       * for each miplevel on a6xx. 3d textures can have different layer
-       * sizes for high levels, but the hw auto-sizer is buggy (or at least
-       * different than what this code does), so as soon as the layer size
-       * range gets into range, we stop reducing it.
+      /* 1d array and 2d array textures must all have the same layer size for
+       * each miplevel on a6xx.  For 3D, the layer size automatically reduces
+       * until the value we specify in TEX_CONST_3_MIN_LAYERSZ, which is used to
+       * make sure that we follow alignment requirements after minification.
        */
       if (is_3d) {
-         if (level < 1 || layout->slices[level - 1].size0 > 0xf000) {
+         if (level == 0) {
             slice->size0 = align(nblocksy * pitch, 4096);
+         } else if (min_3d_layer_size) {
+            slice->size0 = min_3d_layer_size;
          } else {
-            slice->size0 = layout->slices[level - 1].size0;
+            /* Note: level * 2 for minifying in both X and Y. */
+            slice->size0 = u_minify(layout->slices[0].size0, level * 2);
+
+            /* If this level didn't reduce the pitch by half, then fix it up,
+             * and this is the end of layer size reduction.
+             */
+            uint32_t pitch = fdl_pitch(layout, level);
+            if (pitch != fdl_pitch(layout, level - 1) / 2)
+               min_3d_layer_size = slice->size0 = nblocksy * pitch;
+
+            /* If the height is now less than the alignment requirement, then
+             * scale it up and let this be the minimum layer size.
+             */
+            if (tile_mode && util_format_get_nblocksy(format, height) < heightalign)
+               min_3d_layer_size = slice->size0 = nblocksy * pitch;
+
+            /* If the size would become un-page-aligned, stay aligned instead. */
+            if (align(slice->size0, 4096) != slice->size0)
+               min_3d_layer_size = slice->size0 = align(slice->size0, 4096);
          }
       } else {
          slice->size0 = nblocksy * pitch;
diff --git a/src/freedreno/fdl/fd6_layout_test.c b/src/freedreno/fdl/fd6_layout_test.c
index 91639843df7..f4eda11355f 100644
--- a/src/freedreno/fdl/fd6_layout_test.c
+++ b/src/freedreno/fdl/fd6_layout_test.c
@@ -683,6 +683,243 @@ static const struct testcase
                      },
                },
          },
+
+         /* Easy 32x32x32 3d case */
+         {
+            .format = PIPE_FORMAT_R9G9B9E5_FLOAT,
+            .is_3d = true,
+            .layout =
+               {
+                  .tile_mode = TILE6_3,
+                  .ubwc = false,
+                  .width0 = 32,
+                  .height0 = 32,
+                  .depth0 = 32,
+                  .slices =
+                     {
+                        {.offset = 0, .pitch = 256, .size0 = 8192},
+                        {.offset = 262144, .pitch = 256, .size0 = 4096},
+                        {.offset = 327680, .pitch = 256, .size0 = 4096},
+                        {.offset = 360448, .pitch = 256, .size0 = 4096},
+                        {.offset = 376832, .pitch = 256, .size0 = 4096},
+                        {.offset = 385024, .pitch = 256},
+                     },
+               },
+         },
+
+         /* Scale up a bit to 128x128x32 3d */
+         {
+            .format = PIPE_FORMAT_R9G9B9E5_FLOAT,
+            .is_3d = true,
+            .layout =
+               {
+                  .tile_mode = TILE6_3,
+                  .ubwc = false,
+                  .width0 = 128,
+                  .height0 = 128,
+                  .depth0 = 32,
+                  .slices =
+                     {
+                        {.offset = 0, .pitch = 512, .size0 = 65536},
+                        {.offset = 2097152, .pitch = 256, .size0 = 16384},
+                        {.offset = 2359296, .pitch = 256, .size0 = 8192},
+                        {.offset = 2424832, .pitch = 256, .size0 = 8192},
+                        {.offset = 2457600, .pitch = 256, .size0 = 8192},
+                        {.offset = 2473984, .pitch = 256},
+                        {.offset = 2482176, .pitch = 256},
+                        {.offset = 2490368, .pitch = 256},
+                     },
+               },
+         },
+
+         /* Changing width to 1 changes where minimum layer size happens. */
+         {
+            .format = PIPE_FORMAT_R9G9B9E5_FLOAT,
+            .is_3d = true,
+            .layout =
+               {
+                  .tile_mode = TILE6_LINEAR,
+                  .ubwc = false,
+                  .width0 = 1,
+                  .height0 = 128,
+                  .depth0 = 32,
+                  .slices =
+                     {
+                        {.offset = 0, .pitch = 256, .size0 = 32768},
+                        {.offset = 1048576, .pitch = 256, .size0 = 16384},
+                        {.offset = 1310720, .pitch = 256, .size0 = 16384},
+                        {.offset = 1441792, .pitch = 256, .size0 = 16384},
+                        {.offset = 1507328, .pitch = 256, .size0 = 16384},
+                        {.offset = 1540096, .pitch = 256},
+                        {.offset = 1556480, .pitch = 256},
+                        {.offset = 1572864, .pitch = 256},
+                     },
+               },
+         },
+
+         /* And increasing width makes it happen later. */
+         {
+            .format = PIPE_FORMAT_R9G9B9E5_FLOAT,
+            .is_3d = true,
+            .layout =
+               {
+                  .tile_mode = TILE6_3,
+                  .ubwc = false,
+                  .width0 = 1024,
+                  .height0 = 128,
+                  .depth0 = 32,
+                  .slices =
+                     {
+                        {.offset = 0, .pitch = 4096, .size0 = 524288},
+                        {.offset = 16777216, .pitch = 2048, .size0 = 131072},
+                        {.offset = 18874368, .pitch = 1024, .size0 = 32768},
+                        {.offset = 19136512, .pitch = 512, .size0 = 8192},
+                        {.offset = 19169280, .pitch = 256, .size0 = 4096},
+                        {.offset = 19177472, .pitch = 256},
+                        {.offset = 19181568, .pitch = 256},
+                        {.offset = 19185664, .pitch = 256},
+                        {.offset = 19189760, .pitch = 256},
+                        {.offset = 19193856, .pitch = 256},
+                        {.offset = 19197952, .pitch = 256},
+                     },
+               },
+         },
+
+         /* NPOT height case that piglit was catching 3d texture failure in, we
+          * use a higher depth though to get more slice pitches detected from
+          * the blob.
+          */
+         {
+            .format = PIPE_FORMAT_R9G9B9E5_FLOAT,
+            .is_3d = true,
+            .layout =
+               {
+                  .tile_mode = TILE6_3,
+                  .ubwc = false,
+                  .width0 = 128,
+                  .height0 = 129,
+                  .depth0 = 16,
+                  .slices =
+                     {
+                        {.offset = 0, .pitch = 512, .size0 = 73728},
+                        {.offset = 1179648, .pitch = 256, .size0 = 20480},
+                        {.offset = 1343488, .pitch = 256, .size0 = 20480},
+                        {.offset = 1425408, .pitch = 256, .size0 = 20480},
+                        {.offset = 1466368, .pitch = 256},
+                        {.offset = 1486848, .pitch = 256},
+                        {.offset = 1507328, .pitch = 256},
+                        {.offset = 1527808, .pitch = 256},
+                     },
+               },
+         },
+
+         /* NPOT height case that my first 3d layout ideas failed on. */
+         {
+            .format = PIPE_FORMAT_R9G9B9E5_FLOAT,
+            .is_3d = true,
+            .layout =
+               {
+                  .tile_mode = TILE6_3,
+                  .ubwc = false,
+                  .width0 = 128,
+                  .height0 = 132,
+                  .depth0 = 16,
+                  .slices =
+                     {
+                        {.offset = 0, .pitch = 512, .size0 = 73728},
+                        {.offset = 1179648, .pitch = 256, .size0 = 20480},
+                        {.offset = 1343488, .pitch = 256, .size0 = 20480},
+                        {.offset = 1425408, .pitch = 256, .size0 = 20480},
+                        {.offset = 1466368, .pitch = 256},
+                        {.offset = 1486848, .pitch = 256},
+                        {.offset = 1507328, .pitch = 256},
+                        {.offset = 1527808, .pitch = 256},
+                     },
+               },
+         },
+
+         /* blob used MIN_LAYERSZ = 0x3000 here.
+          *
+          * This is an interesting case for 3d layout, since pitch stays NPOT for a while.
+          */
+         {
+            .format = PIPE_FORMAT_R9G9B9E5_FLOAT,
+            .is_3d = true,
+            .layout =
+               {
+                  .tile_mode = TILE6_3,
+                  .ubwc = false,
+                  .width0 = 768,
+                  .height0 = 32,
+                  .depth0 = 128,
+                  .slices =
+                     {
+                        {.offset = 0, .pitch = 3072, .size0 = 98304},
+                        {.offset = 12582912, .pitch = 1536, .size0 = 24576},
+                        {.offset = 14155776, .pitch = 768, .size0 = 12288},
+                        {.offset = 14548992, .pitch = 512, .size0 = 12288},
+                        {.offset = 14745600, .pitch = 256, .size0 = 12288},
+                        {.offset = 14843904, .pitch = 256, .size0 = 12288},
+                        {.offset = 14893056, .pitch = 256, .size0 = 12288},
+                        {.offset = 14917632, .pitch = 256},
+                        {.offset = 14929920, .pitch = 256},
+                        {.offset = 14942208, .pitch = 256},
+                     },
+               },
+         },
+
+         /* dEQP-GLES31.functional.copy_image.mixed.viewclass_128_bits_mixed.rgba32f_rg11_eac.texture3d_to_texture2d */
+#if 0 /* XXX: We disagree with the blob about level 0 size0, but the testcase passes. */
+         {
+            .format = PIPE_FORMAT_R32G32B32A32_FLOAT,
+            .is_3d = true,
+            .layout =
+               {
+                  .tile_mode = TILE6_3,
+                  .ubwc = false,
+                  .width0 = 129,
+                  .height0 = 129,
+                  .depth0 = 17,
+                  .slices =
+                     {
+                        {.offset = 0, .pitch = 3072, .size0 = 524288},
+                        {.offset = 8912896, .pitch = 2048, .size0 = 131072},
+                        {.offset = 9961472, .pitch = 1024, .size0 = 32768},
+                        {.offset = 10092544, .pitch = 1024, .size0 = 16384},
+                        {.offset = 10125312, .pitch = 1024},
+                        {.offset = 10141696, .pitch = 1024},
+                        {.offset = 10158080, .pitch = 1024},
+                        {.offset = 10174464, .pitch = 1024},
+                     },
+               },
+         },
+#endif
+
+         /* Size minification issue found while looking at the above test. */
+         {
+            .format = PIPE_FORMAT_R32G32B32A32_FLOAT,
+            .is_3d = true,
+            .layout =
+               {
+                  .tile_mode = TILE6_3,
+                  .ubwc = false,
+                  .width0 = 129,
+                  .height0 = 9,
+                  .depth0 = 8,
+                  .slices =
+                     {
+                        {.offset = 0, .pitch = 3072, .size0 = 49152},
+                        {.offset = 393216, .pitch = 2048, .size0 = 32768},
+                        {.offset = 524288, .pitch = 1024, .size0 = 32768},
+                        {.offset = 589824, .pitch = 1024},
+                        {.offset = 622592, .pitch = 1024},
+                        {.offset = 655360, .pitch = 1024},
+                        {.offset = 688128, .pitch = 1024},
+                        {.offset = 720896, .pitch = 1024},
+                     },
+               },
+         },
+
 };
 
 int



More information about the mesa-commit mailing list