From fc50fb35b0526a10da5e5fe72d4291c5175a9759 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Mon, 14 Oct 2024 13:30:31 +0200 Subject: [PATCH] tu,freedreno: Enable linear mipmap tail for UBWC images There is no point in using UBWC for last small mip levels, it's an additional overhead for memory and likely less performant. Additionaly this change fixes multi-planar formats with `noubwc`. Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/common/freedreno_dev_info.h | 5 + src/freedreno/common/freedreno_devices.py | 2 + src/freedreno/fdl/fd6_layout.c | 21 +- src/freedreno/fdl/fd6_layout_test.c | 278 +++++++++++++++++++++- src/freedreno/fdl/freedreno_layout.h | 2 +- 5 files changed, 301 insertions(+), 7 deletions(-) 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);