diff --git a/src/freedreno/ci/freedreno-a630-fails.txt b/src/freedreno/ci/freedreno-a630-fails.txt index 41e779d0ce2..c1be5994d51 100644 --- a/src/freedreno/ci/freedreno-a630-fails.txt +++ b/src/freedreno/ci/freedreno-a630-fails.txt @@ -377,7 +377,6 @@ spec@ext_transform_feedback@structs struct-array-elem run interface,Fail spec@ext_transform_feedback@tessellation triangle_fan flat_first,Fail spec@ext_transform_feedback@tessellation triangle_strip flat_first,Fail spec@glsl-1.30@execution@texelfetch fs sampler3d 1x129x9-98x129x9,Fail -spec@glsl-1.30@execution@texelfetch fs sampler3d 98x129x1-98x129x9,Fail spec@glsl-1.30@execution@texelfetch fs sampler3d 98x1x9-98x129x9,Fail spec@glsl-1.50@execution@compatibility@clipping@gs-clip-vertex-const-accept,Fail spec@glsl-1.50@execution@compatibility@clipping@gs-clip-vertex-different-from-position,Fail diff --git a/src/freedreno/fdl/fd6_layout.c b/src/freedreno/fdl/fd6_layout.c index 44d062e8320..dd09a3c6d54 100644 --- a/src/freedreno/fdl/fd6_layout.c +++ b/src/freedreno/fdl/fd6_layout.c @@ -188,20 +188,15 @@ fdl6_layout(struct fdl_layout *layout, enum pipe_format format, ubwc_height0 = align(DIV_ROUND_UP(ubwc_height0, ubwc_blockheight), ubwc_tile_height_alignment); + uint32_t min_3d_layer_size = 0; + for (uint32_t level = 0; level < mip_levels; level++) { uint32_t depth = u_minify(depth0, level); struct fdl_slice *slice = &layout->slices[level]; struct fdl_slice *ubwc_slice = &layout->ubwc_slices[level]; uint32_t tile_mode = fdl_tile_mode(layout, level); uint32_t pitch = fdl_pitch(layout, level); - uint32_t height; - - /* tiled levels of 3D textures are rounded up to PoT dimensions: */ - if (is_3d && tile_mode) { - height = u_minify(util_next_power_of_two(height0), level); - } else { - height = u_minify(height0, level); - } + uint32_t height = u_minify(height0, level); uint32_t nblocksy = util_format_get_nblocksy(format, height); if (tile_mode) @@ -219,17 +214,36 @@ fdl6_layout(struct fdl_layout *layout, enum pipe_format format, slice->offset = offset + layout->size; - /* 1d array and 2d array textures must all have the same layer size - * for each miplevel on a6xx. 3d textures can have different layer - * sizes for high levels, but the hw auto-sizer is buggy (or at least - * different than what this code does), so as soon as the layer size - * range gets into range, we stop reducing it. + /* 1d array and 2d array textures must all have the same layer size for + * each miplevel on a6xx. For 3D, the layer size automatically reduces + * until the value we specify in TEX_CONST_3_MIN_LAYERSZ, which is used to + * make sure that we follow alignment requirements after minification. */ if (is_3d) { - if (level < 1 || layout->slices[level - 1].size0 > 0xf000) { + if (level == 0) { slice->size0 = align(nblocksy * pitch, 4096); + } else if (min_3d_layer_size) { + slice->size0 = min_3d_layer_size; } else { - slice->size0 = layout->slices[level - 1].size0; + /* Note: level * 2 for minifying in both X and Y. */ + slice->size0 = u_minify(layout->slices[0].size0, level * 2); + + /* If this level didn't reduce the pitch by half, then fix it up, + * and this is the end of layer size reduction. + */ + uint32_t pitch = fdl_pitch(layout, level); + if (pitch != fdl_pitch(layout, level - 1) / 2) + min_3d_layer_size = slice->size0 = nblocksy * pitch; + + /* If the height is now less than the alignment requirement, then + * scale it up and let this be the minimum layer size. + */ + if (tile_mode && util_format_get_nblocksy(format, height) < heightalign) + min_3d_layer_size = slice->size0 = nblocksy * pitch; + + /* If the size would become un-page-aligned, stay aligned instead. */ + if (align(slice->size0, 4096) != slice->size0) + min_3d_layer_size = slice->size0 = align(slice->size0, 4096); } } else { slice->size0 = nblocksy * pitch; diff --git a/src/freedreno/fdl/fd6_layout_test.c b/src/freedreno/fdl/fd6_layout_test.c index 91639843df7..f4eda11355f 100644 --- a/src/freedreno/fdl/fd6_layout_test.c +++ b/src/freedreno/fdl/fd6_layout_test.c @@ -683,6 +683,243 @@ static const struct testcase }, }, }, + + /* Easy 32x32x32 3d case */ + { + .format = PIPE_FORMAT_R9G9B9E5_FLOAT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = false, + .width0 = 32, + .height0 = 32, + .depth0 = 32, + .slices = + { + {.offset = 0, .pitch = 256, .size0 = 8192}, + {.offset = 262144, .pitch = 256, .size0 = 4096}, + {.offset = 327680, .pitch = 256, .size0 = 4096}, + {.offset = 360448, .pitch = 256, .size0 = 4096}, + {.offset = 376832, .pitch = 256, .size0 = 4096}, + {.offset = 385024, .pitch = 256}, + }, + }, + }, + + /* Scale up a bit to 128x128x32 3d */ + { + .format = PIPE_FORMAT_R9G9B9E5_FLOAT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = false, + .width0 = 128, + .height0 = 128, + .depth0 = 32, + .slices = + { + {.offset = 0, .pitch = 512, .size0 = 65536}, + {.offset = 2097152, .pitch = 256, .size0 = 16384}, + {.offset = 2359296, .pitch = 256, .size0 = 8192}, + {.offset = 2424832, .pitch = 256, .size0 = 8192}, + {.offset = 2457600, .pitch = 256, .size0 = 8192}, + {.offset = 2473984, .pitch = 256}, + {.offset = 2482176, .pitch = 256}, + {.offset = 2490368, .pitch = 256}, + }, + }, + }, + + /* Changing width to 1 changes where minimum layer size happens. */ + { + .format = PIPE_FORMAT_R9G9B9E5_FLOAT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_LINEAR, + .ubwc = false, + .width0 = 1, + .height0 = 128, + .depth0 = 32, + .slices = + { + {.offset = 0, .pitch = 256, .size0 = 32768}, + {.offset = 1048576, .pitch = 256, .size0 = 16384}, + {.offset = 1310720, .pitch = 256, .size0 = 16384}, + {.offset = 1441792, .pitch = 256, .size0 = 16384}, + {.offset = 1507328, .pitch = 256, .size0 = 16384}, + {.offset = 1540096, .pitch = 256}, + {.offset = 1556480, .pitch = 256}, + {.offset = 1572864, .pitch = 256}, + }, + }, + }, + + /* And increasing width makes it happen later. */ + { + .format = PIPE_FORMAT_R9G9B9E5_FLOAT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = false, + .width0 = 1024, + .height0 = 128, + .depth0 = 32, + .slices = + { + {.offset = 0, .pitch = 4096, .size0 = 524288}, + {.offset = 16777216, .pitch = 2048, .size0 = 131072}, + {.offset = 18874368, .pitch = 1024, .size0 = 32768}, + {.offset = 19136512, .pitch = 512, .size0 = 8192}, + {.offset = 19169280, .pitch = 256, .size0 = 4096}, + {.offset = 19177472, .pitch = 256}, + {.offset = 19181568, .pitch = 256}, + {.offset = 19185664, .pitch = 256}, + {.offset = 19189760, .pitch = 256}, + {.offset = 19193856, .pitch = 256}, + {.offset = 19197952, .pitch = 256}, + }, + }, + }, + + /* NPOT height case that piglit was catching 3d texture failure in, we + * use a higher depth though to get more slice pitches detected from + * the blob. + */ + { + .format = PIPE_FORMAT_R9G9B9E5_FLOAT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = false, + .width0 = 128, + .height0 = 129, + .depth0 = 16, + .slices = + { + {.offset = 0, .pitch = 512, .size0 = 73728}, + {.offset = 1179648, .pitch = 256, .size0 = 20480}, + {.offset = 1343488, .pitch = 256, .size0 = 20480}, + {.offset = 1425408, .pitch = 256, .size0 = 20480}, + {.offset = 1466368, .pitch = 256}, + {.offset = 1486848, .pitch = 256}, + {.offset = 1507328, .pitch = 256}, + {.offset = 1527808, .pitch = 256}, + }, + }, + }, + + /* NPOT height case that my first 3d layout ideas failed on. */ + { + .format = PIPE_FORMAT_R9G9B9E5_FLOAT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = false, + .width0 = 128, + .height0 = 132, + .depth0 = 16, + .slices = + { + {.offset = 0, .pitch = 512, .size0 = 73728}, + {.offset = 1179648, .pitch = 256, .size0 = 20480}, + {.offset = 1343488, .pitch = 256, .size0 = 20480}, + {.offset = 1425408, .pitch = 256, .size0 = 20480}, + {.offset = 1466368, .pitch = 256}, + {.offset = 1486848, .pitch = 256}, + {.offset = 1507328, .pitch = 256}, + {.offset = 1527808, .pitch = 256}, + }, + }, + }, + + /* blob used MIN_LAYERSZ = 0x3000 here. + * + * This is an interesting case for 3d layout, since pitch stays NPOT for a while. + */ + { + .format = PIPE_FORMAT_R9G9B9E5_FLOAT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = false, + .width0 = 768, + .height0 = 32, + .depth0 = 128, + .slices = + { + {.offset = 0, .pitch = 3072, .size0 = 98304}, + {.offset = 12582912, .pitch = 1536, .size0 = 24576}, + {.offset = 14155776, .pitch = 768, .size0 = 12288}, + {.offset = 14548992, .pitch = 512, .size0 = 12288}, + {.offset = 14745600, .pitch = 256, .size0 = 12288}, + {.offset = 14843904, .pitch = 256, .size0 = 12288}, + {.offset = 14893056, .pitch = 256, .size0 = 12288}, + {.offset = 14917632, .pitch = 256}, + {.offset = 14929920, .pitch = 256}, + {.offset = 14942208, .pitch = 256}, + }, + }, + }, + + /* dEQP-GLES31.functional.copy_image.mixed.viewclass_128_bits_mixed.rgba32f_rg11_eac.texture3d_to_texture2d */ +#if 0 /* XXX: We disagree with the blob about level 0 size0, but the testcase passes. */ + { + .format = PIPE_FORMAT_R32G32B32A32_FLOAT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = false, + .width0 = 129, + .height0 = 129, + .depth0 = 17, + .slices = + { + {.offset = 0, .pitch = 3072, .size0 = 524288}, + {.offset = 8912896, .pitch = 2048, .size0 = 131072}, + {.offset = 9961472, .pitch = 1024, .size0 = 32768}, + {.offset = 10092544, .pitch = 1024, .size0 = 16384}, + {.offset = 10125312, .pitch = 1024}, + {.offset = 10141696, .pitch = 1024}, + {.offset = 10158080, .pitch = 1024}, + {.offset = 10174464, .pitch = 1024}, + }, + }, + }, +#endif + + /* Size minification issue found while looking at the above test. */ + { + .format = PIPE_FORMAT_R32G32B32A32_FLOAT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = false, + .width0 = 129, + .height0 = 9, + .depth0 = 8, + .slices = + { + {.offset = 0, .pitch = 3072, .size0 = 49152}, + {.offset = 393216, .pitch = 2048, .size0 = 32768}, + {.offset = 524288, .pitch = 1024, .size0 = 32768}, + {.offset = 589824, .pitch = 1024}, + {.offset = 622592, .pitch = 1024}, + {.offset = 655360, .pitch = 1024}, + {.offset = 688128, .pitch = 1024}, + {.offset = 720896, .pitch = 1024}, + }, + }, + }, + }; int