Mesa (staging/20.2): radv: Fix 1D compressed mipmaps on GFX9.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Nov 2 16:09:39 UTC 2020


Module: Mesa
Branch: staging/20.2
Commit: 7ccf2cf839c0f414f871fef453e11150f5ba0806
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7ccf2cf839c0f414f871fef453e11150f5ba0806

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Wed Oct 21 03:35:26 2020 +0200

radv: Fix 1D compressed mipmaps on GFX9.

Partial rollback as GFX9 really requires height = 1 to work.

The two substantial parts of the fix remaining:

1) Deal with views with multiple levels.
2) Limit the expansion to the base mip pitch/height. On GFX9 this
   is exactly equal to the surf_pitch that was used before. I've
   done some investigation to make sure that on GFX10 this always
   results in the right physical layout.

Remaining stupid question is how the actual extents for bounds
checking never end up too low when the size gets clamped, but
this change and the previous change don't change that ...

Fixes: 1fb3e1fb708 "radv: Fix mipmap extent adjustment on GFX9+."
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7245>
(cherry picked from commit 29999e6b9d737cdab9510246bc5f780791f7c9dc)

---

 .pick_status.json           |  2 +-
 src/amd/vulkan/radv_image.c | 51 ++++++++++++++++++++++++++++++++++-----------
 2 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index b49b654e485..1e2fd4fadaa 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -1219,7 +1219,7 @@
         "description": "radv: Fix 1D compressed mipmaps on GFX9.",
         "nominated": true,
         "nomination_type": 1,
-        "resolution": 0,
+        "resolution": 1,
         "master_sha": null,
         "because_sha": "1fb3e1fb70844d1bd84bc61de6022b85e4d45374"
     },
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 6c3836242c7..3cd5a29698c 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -1597,6 +1597,11 @@ radv_image_view_init(struct radv_image_view *iview,
 	iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
 	iview->multiple_planes = vk_format_get_plane_count(image->vk_format) > 1 && iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT;
 
+	iview->base_layer = range->baseArrayLayer;
+	iview->layer_count = radv_get_layerCount(image, range);
+	iview->base_mip = range->baseMipLevel;
+	iview->level_count = radv_get_levelCount(image, range);
+
 	iview->vk_format = pCreateInfo->format;
 
 	/* If the image has an Android external format, pCreateInfo->format will be
@@ -1652,22 +1657,44 @@ radv_image_view_init(struct radv_image_view *iview,
 		 *
 		 * This means that mip2 will be missing texels.
 		 *
-		 * Fix it by taking the actual extent addrlib assigned to the base mip level.
+		 * 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 the physical extent
+		 * of the base mipmap.
+		 *
+		 * On GFX10 we have to take care to not go over the physical extent
+		 * of the base mipmap as otherwise the GPU computes a different layout.
+		 * Note that the GPU does use the same base-mip dimensions for both a
+		 * block compatible format and the compressed format, so even if we take
+		 * the plain converted dimensions the physical layout is correct.
 		 */
 		if (device->physical_device->rad_info.chip_class >= GFX9 &&
-		     vk_format_is_compressed(image->vk_format) &&
-		     !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;
-		}
+		    vk_format_is_compressed(image->vk_format) &&
+		    !vk_format_is_compressed(iview->vk_format)) {
+			/* If we have multiple levels in the view we should ideally take the last level,
+			 * but the mip calculation has a max(..., 1) so walking back to the base mip in an
+			 * useful way is hard. */
+			if (iview->level_count > 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;
+			} else {
+				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.base_mip_width);
+				iview->extent.height = CLAMP(lvl_height, iview->extent.height,
+							     iview->image->planes[0].surface.u.gfx9.base_mip_height);
+			}
+		 }
 	}
 
-	iview->base_layer = range->baseArrayLayer;
-	iview->layer_count = radv_get_layerCount(image, range);
-	iview->base_mip = range->baseMipLevel;
-	iview->level_count = radv_get_levelCount(image, range);
-
 	bool disable_compression = extra_create_info ? extra_create_info->disable_compression: false;
 	for (unsigned i = 0; i < (iview->multiple_planes ? vk_format_get_plane_count(image->vk_format) : 1); ++i) {
 		VkFormat format = vk_format_get_plane_format(iview->vk_format, i);



More information about the mesa-commit mailing list