From 1618159772a087b0914828bdcdfc0e95a2def350 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 25 Feb 2020 14:03:36 -0800 Subject: [PATCH] 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 Part-of: --- src/freedreno/fdl/fd6_layout.c | 32 ++-- src/freedreno/fdl/fd6_layout_test.c | 255 ++++++++++++++++++++++++++++ 2 files changed, 274 insertions(+), 13 deletions(-) diff --git a/src/freedreno/fdl/fd6_layout.c b/src/freedreno/fdl/fd6_layout.c index 82a04f688e7..3d4efb1d0a8 100644 --- a/src/freedreno/fdl/fd6_layout.c +++ b/src/freedreno/fdl/fd6_layout.c @@ -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, diff --git a/src/freedreno/fdl/fd6_layout_test.c b/src/freedreno/fdl/fd6_layout_test.c index c687029f5ee..0f31ebb3ca8 100644 --- a/src/freedreno/fdl/fd6_layout_test.c +++ b/src/freedreno/fdl/fd6_layout_test.c @@ -118,6 +118,261 @@ static const struct testcase testcases[] = { }, }, #endif + + /* A layout that we failed on (129 wide has a surprise level 1 pitch + * increase), and the sizes bracketing it. + */ + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = { + .width0 = 128, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 512 }, + { .offset = 512, .pitch = 256 }, + { .offset = 768, .pitch = 256 }, + { .offset = 1024, .pitch = 256 }, + { .offset = 1280, .pitch = 256 }, + { .offset = 1536, .pitch = 256 }, + { .offset = 1792, .pitch = 256 }, + { .offset = 2048, .pitch = 256 }, + }, + }, + }, + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = { + .width0 = 129, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 768 }, + { .offset = 768, .pitch = 512 }, + { .offset = 1280, .pitch = 256 }, + { .offset = 1536, .pitch = 256 }, + { .offset = 1792, .pitch = 256 }, + { .offset = 2048, .pitch = 256 }, + { .offset = 2304, .pitch = 256 }, + { .offset = 2560, .pitch = 256 }, + }, + }, + }, + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = { + .width0 = 130, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 768 }, + { .offset = 768, .pitch = 512 }, + { .offset = 1280, .pitch = 256 }, + { .offset = 1536, .pitch = 256 }, + { .offset = 1792, .pitch = 256 }, + { .offset = 2048, .pitch = 256 }, + { .offset = 2304, .pitch = 256 }, + { .offset = 2560, .pitch = 256 }, + }, + }, + }, + + /* The 129 failure seems to be across formats, let's test some cpps */ + { + .format = PIPE_FORMAT_R8_UNORM, + .layout = { + .width0 = 129, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 192 }, + { .offset = 192, .pitch = 128 }, + { .offset = 320, .pitch = 64 }, + { .offset = 384, .pitch = 64 }, + { .offset = 448, .pitch = 64 }, + { .offset = 512, .pitch = 64 }, + { .offset = 576, .pitch = 64 }, + { .offset = 640, .pitch = 64 }, + }, + }, + }, + { + .format = PIPE_FORMAT_R16_UINT, + .layout = { + .width0 = 129, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 384 }, + { .offset = 384, .pitch = 256 }, + { .offset = 640, .pitch = 128 }, + { .offset = 768, .pitch = 128 }, + { .offset = 896, .pitch = 128 }, + { .offset = 1024, .pitch = 128 }, + { .offset = 1152, .pitch = 128 }, + { .offset = 1280, .pitch = 128 }, + }, + }, + }, + { + .format = PIPE_FORMAT_R32G32B32A32_FLOAT, + .layout = { + .width0 = 129, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 3072 }, + { .offset = 3072, .pitch = 2048 }, + { .offset = 5120, .pitch = 1024 }, + { .offset = 6144, .pitch = 1024 }, + { .offset = 7168, .pitch = 1024 }, + { .offset = 8192, .pitch = 1024 }, + { .offset = 9216, .pitch = 1024 }, + { .offset = 10240, .pitch = 1024 }, + }, + }, + }, + + /* The 129 failure replicated at every +256 pixels wide. Pick one of + * them, and this time increase the height as a new variable as well. + */ + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = { + .width0 = 385, .height0 = 128, + .slices = { + { .offset = 0, .pitch = 1792 }, + { .offset = 229376, .pitch = 1024 }, + { .offset = 294912, .pitch = 512 }, + { .offset = 311296, .pitch = 256 }, + { .offset = 315392, .pitch = 256 }, + { .offset = 317440, .pitch = 256 }, + { .offset = 318464, .pitch = 256 }, + { .offset = 318976, .pitch = 256 }, + { .offset = 319232, .pitch = 256 }, + }, + }, + }, + + /* At 257-259 (and replicated every +256 pixels) we had another failure. */ + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = { + .width0 = 257, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 1280 }, + { .offset = 1280, .pitch = 768 }, + { .offset = 2048, .pitch = 512 }, + { .offset = 2560, .pitch = 256 }, + { .offset = 2816, .pitch = 256 }, + { .offset = 3072, .pitch = 256 }, + { .offset = 3328, .pitch = 256 }, + { .offset = 3584, .pitch = 256 }, + { .offset = 3840, .pitch = 256 }, + }, + }, + }, + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = { + .width0 = 258, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 1280 }, + { .offset = 1280, .pitch = 768 }, + { .offset = 2048, .pitch = 512 }, + { .offset = 2560, .pitch = 256 }, + { .offset = 2816, .pitch = 256 }, + { .offset = 3072, .pitch = 256 }, + { .offset = 3328, .pitch = 256 }, + { .offset = 3584, .pitch = 256 }, + { .offset = 3840, .pitch = 256 }, + }, + }, + }, + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = { + .width0 = 259, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 1280 }, + { .offset = 1280, .pitch = 768 }, + { .offset = 2048, .pitch = 512 }, + { .offset = 2560, .pitch = 256 }, + { .offset = 2816, .pitch = 256 }, + { .offset = 3072, .pitch = 256 }, + { .offset = 3328, .pitch = 256 }, + { .offset = 3584, .pitch = 256 }, + { .offset = 3840, .pitch = 256 }, + }, + }, + }, + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = { + .width0 = 260, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 1280 }, + { .offset = 1280, .pitch = 768 }, + { .offset = 2048, .pitch = 512 }, + { .offset = 2560, .pitch = 256 }, + { .offset = 2816, .pitch = 256 }, + { .offset = 3072, .pitch = 256 }, + { .offset = 3328, .pitch = 256 }, + { .offset = 3584, .pitch = 256 }, + { .offset = 3840, .pitch = 256 }, + }, + }, + }, + + /* And, again for the 257-9 failure, test a replica with a larger size*/ + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = { + .width0 = 513, .height0 = 32, + .slices = { + { .offset = 0, .pitch = 2304 }, + { .offset = 73728, .pitch = 1280 }, + { .offset = 94208, .pitch = 768 }, + { .offset = 100352, .pitch = 512 }, + { .offset = 102400, .pitch = 256 }, + { .offset = 102912, .pitch = 256 }, + { .offset = 103168, .pitch = 256 }, + { .offset = 103424, .pitch = 256 }, + { .offset = 103680, .pitch = 256 }, + { .offset = 103936, .pitch = 256 }, + }, + }, + }, + + /* Oh, look. The 513-517 failure extends up to 518 at the next texture + * level! + */ + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = { + .width0 = 518, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 2304 }, + { .offset = 2304, .pitch = 1280 }, + { .offset = 3584, .pitch = 768 }, + { .offset = 4352, .pitch = 512 }, + { .offset = 4864, .pitch = 256 }, + { .offset = 5120, .pitch = 256 }, + { .offset = 5376, .pitch = 256 }, + { .offset = 5632, .pitch = 256 }, + { .offset = 5888, .pitch = 256 }, + { .offset = 6144, .pitch = 256 }, + }, + }, + }, + + /* Tiled mode testing of the unusual 1/2-bytes-per-pixel pitch alignment */ + { + .format = PIPE_FORMAT_R8_UNORM, + .layout = { + .tile_mode = TILE6_3, + .width0 = 129, .height0 = 1, + .slices = { + { .offset = 0, .pitch = 256 }, + { .offset = 8192, .pitch = 128 }, + { .offset = 12288, .pitch = 128 }, + { .offset = 16384, .pitch = 128 }, + { .offset = 20480, .pitch = 64 }, + { .offset = 20544, .pitch = 64 }, + { .offset = 20608, .pitch = 64 }, + { .offset = 20672, .pitch = 64 }, + }, + }, + }, + }; static bool test_layout(const struct testcase *testcase) -- 2.30.2