diff --git a/src/freedreno/common/freedreno_dev_info.h b/src/freedreno/common/freedreno_dev_info.h index ca9939b3e77..aa1077774af 100644 --- a/src/freedreno/common/freedreno_dev_info.h +++ b/src/freedreno/common/freedreno_dev_info.h @@ -188,6 +188,11 @@ struct fd_dev_info { bool has_attachment_shading_rate; + /* Whether mipmaps below certain threshold can use LINEAR tiling when higher + * levels use UBWC, + */ + bool has_ubwc_linear_mipmap_fallback; + struct { uint32_t PC_POWER_CNTL; uint32_t TPL1_DBG_ECO_CNTL; diff --git a/src/freedreno/common/freedreno_devices.py b/src/freedreno/common/freedreno_devices.py index 2a1ae806764..2de719458c7 100644 --- a/src/freedreno/common/freedreno_devices.py +++ b/src/freedreno/common/freedreno_devices.py @@ -427,6 +427,7 @@ a6xx_gen4 = A6XXProps( has_scalar_alu = True, has_isam_v = True, has_ssbo_imm_offsets = True, + has_ubwc_linear_mipmap_fallback = True, # TODO: there seems to be a quirk where at least rcp can't be in an # early preamble. a660 at least is affected. #has_early_preamble = True, @@ -857,6 +858,7 @@ a7xx_base = A6XXProps( has_ssbo_imm_offsets = True, has_early_preamble = True, has_attachment_shading_rate = True, + has_ubwc_linear_mipmap_fallback = True, ) a7xx_gen1 = A7XXProps( diff --git a/src/freedreno/fdl/fd6_layout.c b/src/freedreno/fdl/fd6_layout.c index 1bfb5b8e150..5ef183703f2 100644 --- a/src/freedreno/fdl/fd6_layout.c +++ b/src/freedreno/fdl/fd6_layout.c @@ -11,6 +11,10 @@ #include "freedreno_layout.h" +#include "adreno_pm4.xml.h" +#include "adreno_common.xml.h" +#include "a6xx.xml.h" + static bool is_r8g8(const struct fdl_layout *layout) { @@ -135,7 +139,18 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info, if (ubwc_blockwidth == 0) layout->ubwc = false; - if (layout->ubwc || util_format_is_depth_or_stencil(format)) + if (width0 < FDL_MIN_UBWC_WIDTH) { + layout->ubwc = false; + /* Linear D/S is not supported by HW. */ + if (!util_format_is_depth_or_stencil(format)) + layout->tile_mode = TILE6_LINEAR; + } + + /* Linear D/S is not supported by HW. */ + if (util_format_is_depth_or_stencil(format)) + layout->tile_all = true; + + if (layout->ubwc && !info->a6xx.has_ubwc_linear_mipmap_fallback) layout->tile_all = true; /* in layer_first layout, the level (slice) contains just one @@ -203,7 +218,7 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info, 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); + enum a6xx_tile_mode tile_mode = fdl_tile_mode(layout, level); uint32_t pitch = fdl_pitch(layout, level); uint32_t height = u_minify(height0, level); @@ -260,7 +275,7 @@ fdl6_layout(struct fdl_layout *layout, const struct fd_dev_info *info, layout->size += slice->size0 * depth * layers_in_level; - if (layout->ubwc) { + if (layout->ubwc && tile_mode != TILE6_LINEAR) { /* with UBWC every level is aligned to 4K */ layout->size = align64(layout->size, 4096); diff --git a/src/freedreno/fdl/fd6_layout_test.c b/src/freedreno/fdl/fd6_layout_test.c index 28f030ebae5..d45cec660e0 100644 --- a/src/freedreno/fdl/fd6_layout_test.c +++ b/src/freedreno/fdl/fd6_layout_test.c @@ -12,7 +12,7 @@ #include static const struct testcase - testcases[] = + testcases_a630[] = { /* A straightforward first testcase, linear, with an obvious format. */ { @@ -963,6 +963,270 @@ static const struct testcase }, }; +/* has_ubwc_linear_mipmap_fallback is supported started from A6XX gen4. */ +static const struct testcase + testcases_a660[] = + { + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = true, + .width0 = 1024, + .height0 = 1, + .slices = + { + {.offset = 0, .pitch = 4096}, + {.offset = 65536, .pitch = 2048}, + {.offset = 98304, .pitch = 1024}, + {.offset = 114688, .pitch = 512}, + {.offset = 122880, .pitch = 256}, + {.offset = 126976, .pitch = 256}, + {.offset = 131072, .pitch = 256}, + {.offset = 135168, .pitch = 256}, + {.offset = 135424, .pitch = 256}, + {.offset = 135680, .pitch = 256}, + {.offset = 135936, .pitch = 256}, + }, + .ubwc_slices = + { + {.offset = 0, .pitch = 64}, + {.offset = 4096, .pitch = 64}, + {.offset = 8192, .pitch = 64}, + {.offset = 12288, .pitch = 64}, + {.offset = 16384, .pitch = 64}, + {.offset = 20480, .pitch = 64}, + {.offset = 24576, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + }, + }, + }, + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = true, + .width0 = 2049, + .height0 = 128, + .slices = + { + {.offset = 0, .pitch = 8448}, + {.offset = 1081344, .pitch = 4352}, + {.offset = 1359872, .pitch = 2304}, + {.offset = 1433600, .pitch = 1280}, + {.offset = 1454080, .pitch = 768}, + {.offset = 1466368, .pitch = 512}, + {.offset = 1474560, .pitch = 256}, + {.offset = 1478656, .pitch = 256}, + {.offset = 1482752, .pitch = 256}, + {.offset = 1483008, .pitch = 256}, + {.offset = 1483264, .pitch = 256}, + {.offset = 1483520, .pitch = 256}, + }, + .ubwc_slices = + { + {.offset = 0, .pitch = 256}, + {.offset = 16384, .pitch = 128}, + {.offset = 24576, .pitch = 64}, + {.offset = 28672, .pitch = 64}, + {.offset = 32768, .pitch = 64}, + {.offset = 36864, .pitch = 64}, + {.offset = 40960, .pitch = 64}, + {.offset = 45056, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + }, + }, + }, + + /* UBWC: Height comes from POT-aligned level 0. */ + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = true, + .width0 = 1024, + .height0 = 1025, + .slices = + { + {.offset = 0, .pitch = 4096}, + {.offset = 4259840, .pitch = 2048}, + {.offset = 5308416, .pitch = 1024}, + {.offset = 5570560, .pitch = 512}, + {.offset = 5636096, .pitch = 256}, + {.offset = 5652480, .pitch = 256}, + {.offset = 5660672, .pitch = 256}, + {.offset = 5664768, .pitch = 256}, + {.offset = 5666816, .pitch = 256}, + {.offset = 5667840, .pitch = 256}, + {.offset = 5668352, .pitch = 256}, + }, + .ubwc_slices = + { + {.offset = 0, .pitch = 64}, + {.offset = 32768, .pitch = 64}, + {.offset = 49152, .pitch = 64}, + {.offset = 57344, .pitch = 64}, + {.offset = 61440, .pitch = 64}, + {.offset = 65536, .pitch = 64}, + {.offset = 69632, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + }, + }, + }, + + /* UBWC: Get at minimum height of a level across cpps */ + { + .format = PIPE_FORMAT_R16_UINT, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = true, + .width0 = 16384, + .height0 = 1, + .slices = + { + {.offset = 0, .pitch = 32768}, + {.offset = 524288, .pitch = 16384}, + {.offset = 786432, .pitch = 8192}, + {.offset = 917504, .pitch = 4096}, + {.offset = 983040, .pitch = 2048}, + {.offset = 1015808, .pitch = 1024}, + {.offset = 1032192, .pitch = 512}, + {.offset = 1040384, .pitch = 256}, + {.offset = 1044480, .pitch = 256}, + {.offset = 1048576, .pitch = 256}, + {.offset = 1052672, .pitch = 256}, + {.offset = 1056768, .pitch = 256}, + {.offset = 1057024, .pitch = 256}, + {.offset = 1057280, .pitch = 256}, + {.offset = 1057536, .pitch = 256}, + }, + .ubwc_slices = + { + {.offset = 0, .pitch = 1024}, + {.offset = 65536, .pitch = 512}, + {.offset = 98304, .pitch = 256}, + {.offset = 114688, .pitch = 128}, + {.offset = 122880, .pitch = 64}, + {.offset = 126976, .pitch = 64}, + {.offset = 131072, .pitch = 64}, + {.offset = 135168, .pitch = 64}, + {.offset = 139264, .pitch = 64}, + {.offset = 143360, .pitch = 64}, + {.offset = 147456, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + }, + }, + }, + { + .format = PIPE_FORMAT_R8G8B8A8_UNORM, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = true, + .width0 = 16384, + .height0 = 1, + .slices = + { + {.offset = 0, .pitch = 65536}, + {.offset = 1048576, .pitch = 32768}, + {.offset = 1572864, .pitch = 16384}, + {.offset = 1835008, .pitch = 8192}, + {.offset = 1966080, .pitch = 4096}, + {.offset = 2031616, .pitch = 2048}, + {.offset = 2064384, .pitch = 1024}, + {.offset = 2080768, .pitch = 512}, + {.offset = 2088960, .pitch = 256}, + {.offset = 2093056, .pitch = 256}, + {.offset = 2097152, .pitch = 256}, + {.offset = 2101248, .pitch = 256}, + {.offset = 2101504, .pitch = 256}, + {.offset = 2101760, .pitch = 256}, + {.offset = 2102016, .pitch = 256}, + }, + .ubwc_slices = + { + {.offset = 0, .pitch = 1024}, + {.offset = 65536, .pitch = 512}, + {.offset = 98304, .pitch = 256}, + {.offset = 114688, .pitch = 128}, + {.offset = 122880, .pitch = 64}, + {.offset = 126976, .pitch = 64}, + {.offset = 131072, .pitch = 64}, + {.offset = 135168, .pitch = 64}, + {.offset = 139264, .pitch = 64}, + {.offset = 143360, .pitch = 64}, + {.offset = 147456, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + }, + }, + }, + { + .format = PIPE_FORMAT_R32G32B32A32_FLOAT, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = true, + .width0 = 16384, + .height0 = 1, + .slices = + { + {.offset = 0, .pitch = 262144}, + {.offset = 4194304, .pitch = 131072}, + {.offset = 6291456, .pitch = 65536}, + {.offset = 7340032, .pitch = 32768}, + {.offset = 7864320, .pitch = 16384}, + {.offset = 8126464, .pitch = 8192}, + {.offset = 8257536, .pitch = 4096}, + {.offset = 8323072, .pitch = 2048}, + {.offset = 8355840, .pitch = 1024}, + {.offset = 8372224, .pitch = 1024}, + {.offset = 8388608, .pitch = 1024}, + {.offset = 8404992, .pitch = 1024}, + {.offset = 8406016, .pitch = 1024}, + {.offset = 8407040, .pitch = 1024}, + {.offset = 8408064, .pitch = 1024}, + }, + .ubwc_slices = + { + {.offset = 0, .pitch = 4096}, + {.offset = 262144, .pitch = 2048}, + {.offset = 393216, .pitch = 1024}, + {.offset = 458752, .pitch = 512}, + {.offset = 491520, .pitch = 256}, + {.offset = 507904, .pitch = 128}, + {.offset = 516096, .pitch = 64}, + {.offset = 520192, .pitch = 64}, + {.offset = 524288, .pitch = 64}, + {.offset = 528384, .pitch = 64}, + {.offset = 532480, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + {.offset = 0, .pitch = 64}, + }, + }, + }, + }; + int main(int argc, char **argv) { @@ -971,8 +1235,16 @@ main(int argc, char **argv) struct fd_dev_id a630_dev_id = { .gpu_id = 630, }; - for (int i = 0; i < ARRAY_SIZE(testcases); i++) { - if (!fdl_test_layout(&testcases[i], &a630_dev_id)) + for (int i = 0; i < ARRAY_SIZE(testcases_a630); i++) { + if (!fdl_test_layout(&testcases_a630[i], &a630_dev_id)) + ret = 1; + } + + struct fd_dev_id a660_dev_id = { + .gpu_id = 660, + }; + for (int i = 0; i < ARRAY_SIZE(testcases_a660); i++) { + if (!fdl_test_layout(&testcases_a660[i], &a660_dev_id)) ret = 1; } diff --git a/src/freedreno/fdl/freedreno_layout.h b/src/freedreno/fdl/freedreno_layout.h index 1b078a8bbda..d9fe919aa5e 100644 --- a/src/freedreno/fdl/freedreno_layout.h +++ b/src/freedreno/fdl/freedreno_layout.h @@ -224,7 +224,7 @@ fdl_tile_mode(const struct fdl_layout *layout, int level) static inline bool fdl_ubwc_enabled(const struct fdl_layout *layout, int level) { - return layout->ubwc; + return layout->ubwc && !fdl_level_linear(layout, level); } const char *fdl_tile_mode_desc(const struct fdl_layout *layout, int level);