Mesa (master): radv: Fix mipmap extent adjustment on GFX9+.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Oct 12 21:16:14 UTC 2020


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

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Fri Oct  9 03:12:55 2020 +0200

radv: Fix mipmap extent adjustment on GFX9+.

With arrays we really have to use the correct size for the base
mipmap to get the right array pitch. In particular, using
surf_pitch results in pitch that is bigger than the base mipmap
and hence results in wrong pitches computed by the HW.

It seems that on GFX9 this has mostly been hidden by the epitch
provided in the descriptor but this is not something we do on
GFX10 anymore.

Now this has some draw-backs:

1. normalized coordinates don't work
2. Bounds checking uses slightly bigger bounds.

2 mostly is not an issue as we still ensure that they're within
the texture memory and not overlapping other layers/mips, but
we can't properly ignore writes.

1 is kinda dead in the water ... On the other hand I'd argue that
using normalized coords & a filter for sampling a block view of
a compressed format is extraordinarily useless.

The old method we employed already had these drawbacks for everything
except the base miplevel of the imageview.

AFAICT this is the same tradeoff AMDVLK makes and no CTS test hits
this. (once it does I think the HW is dead in the water ... Only
workaround I can think of is shader processing which is hard because
we don't know texture formats at compile time.)

I also removed the extra calculations when the image has only 1 mip
level because they ended up being a no-op in that case.

CC: mesa-stable
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2292
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2266
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2483
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2906
Gitlab: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3607
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7090>

---

 src/amd/common/ac_surface.c |  3 +++
 src/amd/common/ac_surface.h |  3 +++
 src/amd/vulkan/radv_image.c | 25 +++++++------------------
 3 files changed, 13 insertions(+), 18 deletions(-)

diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
index 79011c992c6..10648d1324e 100644
--- a/src/amd/common/ac_surface.c
+++ b/src/amd/common/ac_surface.c
@@ -1425,6 +1425,9 @@ static int gfx9_compute_miptree(struct ac_addrlib *addrlib, const struct radeon_
       }
    }
 
+   surf->u.gfx9.base_mip_width = mip_info[0].pitch;
+   surf->u.gfx9.base_mip_height = mip_info[0].height;
+
    if (in->flags.depth) {
       assert(in->swizzleMode != ADDR_SW_LINEAR);
 
diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h
index eafe114f230..630f626500f 100644
--- a/src/amd/common/ac_surface.h
+++ b/src/amd/common/ac_surface.h
@@ -166,6 +166,9 @@ struct gfx9_surf_layout {
    /* Mipmap level pitch in elements. Only valid for LINEAR. */
    uint16_t pitch[RADEON_SURF_MAX_LEVELS];
 
+   uint16_t base_mip_width;
+   uint16_t base_mip_height;
+
    uint64_t stencil_offset; /* separate stencil */
 
    uint8_t dcc_block_width;
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index b7d22b1c535..ebd74d0f157 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -1655,26 +1655,15 @@ radv_image_view_init(struct radv_image_view *iview,
 		 *
 		 * This means that mip2 will be missing texels.
 		 *
-		 * Fix this by calculating the base mip's width and height, then convert that, and round it
-		 * back up to get the level 0 size.
-		 * Clamp the converted size between the original values, and next power of two, which
-		 * means we don't oversize the image.
+		 * Fix it by taking the actual extent addrlib assigned to the base mip level.
 		 */
-		 if (device->physical_device->rad_info.chip_class >= GFX9 &&
+		if (device->physical_device->rad_info.chip_class >= GFX9 &&
 		     vk_format_is_compressed(image->vk_format) &&
-		     !vk_format_is_compressed(iview->vk_format)) {
-			 unsigned lvl_width  = radv_minify(image->info.width , range->baseMipLevel);
-			 unsigned lvl_height = radv_minify(image->info.height, range->baseMipLevel);
-
-			 lvl_width = round_up_u32(lvl_width * view_bw, img_bw);
-			 lvl_height = round_up_u32(lvl_height * view_bh, img_bh);
-
-			 lvl_width <<= range->baseMipLevel;
-			 lvl_height <<= range->baseMipLevel;
-
-			 iview->extent.width = CLAMP(lvl_width, iview->extent.width, iview->image->planes[0].surface.u.gfx9.surf_pitch);
-			 iview->extent.height = CLAMP(lvl_height, iview->extent.height, iview->image->planes[0].surface.u.gfx9.surf_height);
-		 }
+		     !vk_format_is_compressed(iview->vk_format) &&
+		     iview->image->info.levels > 1) {
+			iview->extent.width = iview->image->planes[0].surface.u.gfx9.base_mip_width;
+			iview->extent.height = iview->image->planes[0].surface.u.gfx9.base_mip_height;
+		}
 	}
 
 	iview->base_layer = range->baseArrayLayer;



More information about the mesa-commit mailing list