From 673acc3d011d70a1f9e1599454f407523f306fcb Mon Sep 17 00:00:00 2001 From: Lucas Fryzek Date: Fri, 26 May 2023 14:52:54 -0400 Subject: [PATCH] v3dv: Update texture padding logic to match v3d changes Piglit tests for v3d highlighted issues with the padding computation when allocating memory for slices. This change moves the fixes from v3d to v3dv. Reviewed-by: Iago Toral Quiroga Part-of: --- src/broadcom/vulkan/v3dv_image.c | 55 ++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_image.c b/src/broadcom/vulkan/v3dv_image.c index 8e9227d..5474d37 100644 --- a/src/broadcom/vulkan/v3dv_image.c +++ b/src/broadcom/vulkan/v3dv_image.c @@ -70,6 +70,27 @@ v3d_get_ub_pad(uint32_t cpp, uint32_t height) return 0; } +/** + * Computes the dimension with required padding for mip levels. + * + * This padding is required for width and height dimensions when the mip + * level is greater than 1, and for the depth dimension when the mip level + * is greater than 0. This function expects to be passed a mip level >= 1. + * + * Note: Hardware documentation seems to suggest that the third argument + * should be the utile dimensions, but through testing it was found that + * the block dimension should be used instead. + */ +static uint32_t +v3d_get_dimension_mpad(uint32_t dimension, uint32_t level, uint32_t block_dimension) +{ + assert(level >= 1); + uint32_t pot_dim = u_minify(dimension, 1); + pot_dim = util_next_power_of_two(DIV_ROUND_UP(pot_dim, block_dimension)); + uint32_t padded_dim = block_dimension * pot_dim; + return u_minify(padded_dim, level - 1); +} + static void v3d_setup_plane_slices(struct v3dv_image *image, uint8_t plane, uint32_t plane_offset) @@ -82,15 +103,6 @@ v3d_setup_plane_slices(struct v3dv_image *image, uint8_t plane, uint32_t height = image->planes[plane].height; uint32_t depth = image->vk.extent.depth; - /* Note that power-of-two padding is based on level 1. These are not - * equivalent to just util_next_power_of_two(dimension), because at a - * level 0 dimension of 9, the level 1 power-of-two padded value is 4, - * not 8. - */ - uint32_t pot_width = 2 * util_next_power_of_two(u_minify(width, 1)); - uint32_t pot_height = 2 * util_next_power_of_two(u_minify(height, 1)); - uint32_t pot_depth = 2 * util_next_power_of_two(u_minify(depth, 1)); - uint32_t utile_w = v3d_utile_width(image->planes[plane].cpp); uint32_t utile_h = v3d_utile_height(image->planes[plane].cpp); uint32_t uif_block_w = utile_w * 2; @@ -99,6 +111,21 @@ v3d_setup_plane_slices(struct v3dv_image *image, uint8_t plane, uint32_t block_width = vk_format_get_blockwidth(image->vk.format); uint32_t block_height = vk_format_get_blockheight(image->vk.format); + /* Note that power-of-two padding is based on level 1. These are not + * equivalent to just util_next_power_of_two(dimension), because at a + * level 0 dimension of 9, the level 1 power-of-two padded value is 4, + * not 8. Additionally the pot padding is based on the block size. + */ + uint32_t pot_width = 2 * v3d_get_dimension_mpad(width, + 1, + block_width); + uint32_t pot_height = 2 * v3d_get_dimension_mpad(height, + 1, + block_height); + uint32_t pot_depth = 2 * v3d_get_dimension_mpad(depth, + 1, + 1); + assert(image->vk.samples == VK_SAMPLE_COUNT_1_BIT || image->vk.samples == VK_SAMPLE_COUNT_4_BIT); bool msaa = image->vk.samples != VK_SAMPLE_COUNT_1_BIT; @@ -138,16 +165,6 @@ v3d_setup_plane_slices(struct v3dv_image *image, uint8_t plane, level_width = DIV_ROUND_UP(level_width, block_width); level_height = DIV_ROUND_UP(level_height, block_height); - /* Converting to the block size may have made it so the level_width - * and level height are no longer a POT for mip levels > 1, therefore - * if this is a mip level greater than 1 we set level_width and - * level_height to the next power of two - */ - if (i > 1) { - level_width = util_next_power_of_two(level_width); - level_height = util_next_power_of_two(level_height); - } - if (!image->tiled) { slice->tiling = V3D_TILING_RASTER; if (image->vk.image_type == VK_IMAGE_TYPE_1D) -- 2.7.4