diff --git a/src/gallium/drivers/v3d/v3d_resource.c b/src/gallium/drivers/v3d/v3d_resource.c index b93336a269d..b7298f56563 100644 --- a/src/gallium/drivers/v3d/v3d_resource.c +++ b/src/gallium/drivers/v3d/v3d_resource.c @@ -526,6 +526,27 @@ v3d_get_ub_pad(struct v3d_resource *rsc, 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_slices(struct v3d_resource *rsc, uint32_t winsys_stride, bool uif_top) @@ -534,14 +555,6 @@ v3d_setup_slices(struct v3d_resource *rsc, uint32_t winsys_stride, uint32_t width = prsc->width0; uint32_t height = prsc->height0; uint32_t depth = prsc->depth0; - /* 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 offset = 0; uint32_t utile_w = v3d_utile_width(rsc->cpp); uint32_t utile_h = v3d_utile_height(rsc->cpp); @@ -549,6 +562,21 @@ v3d_setup_slices(struct v3d_resource *rsc, uint32_t winsys_stride, uint32_t uif_block_h = utile_h * 2; uint32_t block_width = util_format_get_blockwidth(prsc->format); uint32_t block_height = util_format_get_blockheight(prsc->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); bool msaa = prsc->nr_samples > 1; /* MSAA textures/renderbuffers are always laid out as single-level diff --git a/src/gallium/drivers/v3d/v3dx_format_table.c b/src/gallium/drivers/v3d/v3dx_format_table.c index 9920aa85431..78f6d955be3 100644 --- a/src/gallium/drivers/v3d/v3dx_format_table.c +++ b/src/gallium/drivers/v3d/v3dx_format_table.c @@ -185,6 +185,36 @@ static const struct v3d_format format_table[] = { FORMAT(DXT3_SRGBA, NO, BC2, SWIZ_XYZW, 16, 0), FORMAT(DXT5_RGBA, NO, BC3, SWIZ_XYZW, 16, 0), FORMAT(DXT5_SRGBA, NO, BC3, SWIZ_XYZW, 16, 0), + + /* Compressed: ASTC */ + FORMAT(ASTC_4x4, NO, ASTC_4X4, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_4x4_SRGB, NO, ASTC_4X4, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_5x4, NO, ASTC_5X4, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_5x4_SRGB, NO, ASTC_5X4, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_5x5, NO, ASTC_5X5, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_5x5_SRGB, NO, ASTC_5X5, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_6x5, NO, ASTC_6X5, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_6x5_SRGB, NO, ASTC_6X5, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_6x6, NO, ASTC_6X6, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_6x6_SRGB, NO, ASTC_6X6, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_8x5, NO, ASTC_8X5, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_8x5_SRGB, NO, ASTC_8X5, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_8x6, NO, ASTC_8X6, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_8x6_SRGB, NO, ASTC_8X6, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_8x8, NO, ASTC_8X8, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_8x8_SRGB, NO, ASTC_8X8, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_10x5, NO, ASTC_10X5, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_10x5_SRGB, NO, ASTC_10X5, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_10x6, NO, ASTC_10X6, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_10x6_SRGB, NO, ASTC_10X6, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_10x8, NO, ASTC_10X8, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_10x8_SRGB, NO, ASTC_10X8, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_10x10, NO, ASTC_10X10, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_10x10_SRGB, NO, ASTC_10X10, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_12x10, NO, ASTC_12X10, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_12x10_SRGB, NO, ASTC_12X10, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_12x12, NO, ASTC_12X12, SWIZ_XYZW, 16, 1), + FORMAT(ASTC_12x12_SRGB, NO, ASTC_12X12, SWIZ_XYZW, 16, 1), }; const struct v3d_format *