From: Dave Airlie <[email protected]> This ports a fix from amdvlk, to fix the sizing for mip levels when block compressed images are viewed using uncompressed views.
Fixes: dEQP-VK.image.texel_view_compatible.graphic.extended*bc* Fixes: e38685cc62e 'Revert "radv: disable support for VEGA for now."' Signed-off-by: Dave Airlie <[email protected]> --- src/amd/vulkan/radv_image.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 40e6dfc3af..a8b40909cf 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -1067,6 +1067,46 @@ radv_image_view_init(struct radv_image_view *iview, 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)); + /* 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 SRD 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 start mip's ceil(texels/blocks) width and height and then go up the chain + * to pad the base mip's width and height to account for this. A result lower than the base mip's + * indicates a non-power-of-two texture, and the result should be clamped to its extentElements. + * Otherwise, if the mip is aligned to block multiples, the result will be equal to extentElements. If + * there is no suitable width or height, the actualExtentElements is chosen. The application is in + * charge of making sure the math works out properly if they do this (allowed by Vulkan), otherwise we + * assume it's an internal view and the copy shaders will prevent accessing out-of-bounds pixels. + */ + if (device->physical_device->rad_info.chip_class >= GFX9 && + vk_format_is_compressed(image->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 * vk_format_get_blockwidth(iview->vk_format), + vk_format_get_blockwidth(image->vk_format)); + lvl_height = round_up_u32(lvl_height * vk_format_get_blockheight(iview->vk_format), + vk_format_get_blockheight(image->vk_format)); + + iview->extent.width = MAX2(iview->extent.width, lvl_width << range->baseMipLevel); + iview->extent.height = MAX2(iview->extent.height, lvl_height << range->baseMipLevel); + } } iview->base_layer = range->baseArrayLayer; -- 2.14.3 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
