summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-01-29 04:15:09 +0000
committerEmil Velikov <emil.l.velikov@gmail.com>2018-02-09 04:23:17 +0000
commit64ab67602be30caf654cfb1ac62bcf4d5083b4e9 (patch)
tree8435a3b2553ec02443bbcddd745eaf7c2d36b6d6
parente27f066126cc153aa327d281491be6356c86fa35 (diff)
radv/gfx9: fix block compression texture views. (v2)
This ports a fix from amdvlk, to fix the sizing for mip levels when block compressed images are viewed using uncompressed views. My original fix didn't power the clamping, but it looks like the clamping is required to stop the sizing going too large. Fixes: dEQP-VK.image.texel_view_compatible.graphic.extended*bc* Doesn't crash DOW3 anymore. Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Fixes: e38685cc62e 'Revert "radv: disable support for VEGA for now."' Signed-off-by: Dave Airlie <airlied@redhat.com> (cherry picked from commit f6cc15dccd54ff70be987457af790cac1c8fe5bb)
-rw-r--r--src/amd/vulkan/radv_image.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 0854a24d72b..417016afd0f 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -1048,10 +1048,55 @@ radv_image_view_init(struct radv_image_view *iview,
}
if (iview->vk_format != image->vk_format) {
- iview->extent.width = round_up_u32(iview->extent.width * vk_format_get_blockwidth(iview->vk_format),
- vk_format_get_blockwidth(image->vk_format));
- iview->extent.height = round_up_u32(iview->extent.height * vk_format_get_blockheight(iview->vk_format),
- vk_format_get_blockheight(image->vk_format));
+ unsigned view_bw = vk_format_get_blockwidth(iview->vk_format);
+ unsigned view_bh = vk_format_get_blockheight(iview->vk_format);
+ unsigned img_bw = vk_format_get_blockwidth(image->vk_format);
+ unsigned img_bh = vk_format_get_blockheight(image->vk_format);
+
+ iview->extent.width = round_up_u32(iview->extent.width * view_bw, img_bw);
+ iview->extent.height = round_up_u32(iview->extent.height * view_bh, img_bh);
+
+ /* Comment ported from amdvlk -
+ * If we have the following image:
+ * Uncompressed pixels Compressed block sizes (4x4)
+ * mip0: 22 x 22 6 x 6
+ * mip1: 11 x 11 3 x 3
+ * mip2: 5 x 5 2 x 2
+ * mip3: 2 x 2 1 x 1
+ * mip4: 1 x 1 1 x 1
+ *
+ * On GFX9 the descriptor is always programmed with the WIDTH and HEIGHT of the base level and the HW is
+ * calculating the degradation of the block sizes down the mip-chain as follows (straight-up
+ * divide-by-two integer math):
+ * mip0: 6x6
+ * mip1: 3x3
+ * mip2: 1x1
+ * mip3: 1x1
+ *
+ * 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.
+ */
+ if (device->physical_device->rad_info.chip_class >= GFX9 &&
+ vk_format_is_compressed(image->vk_format) &&
+ !vk_format_is_compressed(iview->vk_format)) {
+ unsigned rounded_img_w = util_next_power_of_two(iview->extent.width);
+ unsigned rounded_img_h = util_next_power_of_two(iview->extent.height);
+ 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, rounded_img_w);
+ iview->extent.height = CLAMP(lvl_height, iview->extent.height, rounded_img_h);
+ }
}
iview->base_layer = range->baseArrayLayer;