freedreno/a6xx: Set a level's pitch based on minified level0 pitch, not width0.

Found from piglit fbo-generatemipmaps failures, then tracked down with the
texturator test.  The piece that really revealed things was finding that
1024x1 linear RGBA8 on the older blob drivers would have a pitch of 5120
instead of 4096, and the following levels minified that pitch.

Fixes ~124 piglit tests (~8.5% of piglit failures) on cheza.

Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3987>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3987>
This commit is contained in:
Eric Anholt
2020-02-25 14:03:36 -08:00
committed by Marge Bot
parent 4b881d5270
commit 1618159772
2 changed files with 274 additions and 13 deletions

View File

@@ -63,6 +63,20 @@ static const struct {
#define RGB_TILE_HEIGHT_ALIGNMENT 16
#define UBWC_PLANE_SIZE_ALIGNMENT 4096
static int
fdl6_pitchalign(struct fdl_layout *layout, int ta, int level)
{
const struct util_format_description *format_desc =
util_format_description(layout->format);
uint32_t pitchalign = 64;
if (fdl_tile_mode(layout, level))
pitchalign = tile_alignment[ta].pitchalign;
if (format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC)
pitchalign *= util_format_get_blockwidth(layout->format);
return pitchalign;
}
/* NOTE: good way to test this is: (for example)
* piglit/bin/texelFetch fs sampler3D 100x100x8
*/
@@ -88,8 +102,6 @@ fdl6_layout(struct fdl_layout *layout,
if (tile_alignment[layout->cpp].ubwc_blockwidth == 0)
layout->ubwc = false;
const struct util_format_description *format_desc =
util_format_description(format);
int ta = layout->cpp;
/* The z16/r16 formats seem to not play by the normal tiling rules: */
@@ -110,6 +122,8 @@ fdl6_layout(struct fdl_layout *layout,
layout->base_align = 64;
}
uint32_t pitch0 = util_align_npot(width0, fdl6_pitchalign(layout, ta, 0));
for (uint32_t level = 0; level < mip_levels; level++) {
uint32_t depth = u_minify(depth0, level);
struct fdl_slice *slice = &layout->slices[level];
@@ -125,14 +139,9 @@ fdl6_layout(struct fdl_layout *layout,
width = u_minify(width0, level);
height = u_minify(height0, level);
}
uint32_t pitchalign;
if (tile_mode) {
pitchalign = tile_alignment[ta].pitchalign;
if (tile_mode)
height = align(height, tile_alignment[ta].heightalign);
} else {
pitchalign = 64;
}
/* The blits used for mem<->gmem work at a granularity of
* 32x32, which can cause faults due to over-fetch on the
@@ -144,11 +153,8 @@ fdl6_layout(struct fdl_layout *layout,
if (level == mip_levels - 1)
height = align(height, 32);
if (format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC)
slice->pitch =
util_align_npot(width, pitchalign * util_format_get_blockwidth(format));
else
slice->pitch = align(width, pitchalign);
slice->pitch = util_align_npot(u_minify(pitch0, level),
fdl6_pitchalign(layout, ta, level));
slice->offset = layout->size;
uint32_t blocks = util_format_get_nblocks(format,