summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>2020-10-09 03:12:55 +0200
committerEric Engestrom <eric@engestrom.ch>2020-10-14 19:29:35 +0200
commit8e6aa247c197e518b84ef85f16e103d51030f3fb (patch)
tree9fd08786f9aaa52fb6473ab6f9feb84ecbc738a7
parentb6d88656306d14776c8c02a70a6c9cec0c226855 (diff)
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@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7090> (cherry picked from commit 1fb3e1fb70844d1bd84bc61de6022b85e4d45374)
-rw-r--r--.pick_status.json2
-rw-r--r--src/amd/common/ac_surface.c3
-rw-r--r--src/amd/common/ac_surface.h3
-rw-r--r--src/amd/vulkan/radv_image.c25
4 files changed, 14 insertions, 19 deletions
diff --git a/.pick_status.json b/.pick_status.json
index 8f328791965..67d7c21919c 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -5629,7 +5629,7 @@
"description": "radv: Fix mipmap extent adjustment on GFX9+.",
"nominated": true,
"nomination_type": 0,
- "resolution": 0,
+ "resolution": 1,
"master_sha": null,
"because_sha": null
},
diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
index a2e2ad8a5eb..23cf761a1f8 100644
--- a/src/amd/common/ac_surface.c
+++ b/src/amd/common/ac_surface.c
@@ -1477,6 +1477,9 @@ static int gfx9_compute_miptree(struct ac_addrlib *addrlib,
}
}
+ 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 e11e5a744de..d7476159f70 100644
--- a/src/amd/common/ac_surface.h
+++ b/src/amd/common/ac_surface.h
@@ -165,6 +165,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 */
/* Displayable DCC. This is always rb_aligned=0 and pipe_aligned=0.
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 440fe4939a8..2a1ba933e42 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -1735,26 +1735,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;