From 65c00ba7cbdcebef3fd7a1efcb95b5bdb480e9dc Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sat, 20 Aug 2022 21:47:57 -0400 Subject: [PATCH] ail: Add unit tests for miptree layouts The equations for calculating miptree offsets are complicated, nonobvious, and full of subtle footguns. Worse, the driver doesn't control the offsets -- it must simply agree with the offsets implicitly calculated in the hardware. The CTS doesn't adequately exercise all the corner cases. Make sure we have unit tests that do. The tests themselves are generated by instrumenting agxdecode to scan GPU memory after uploading test patterns in a variety of layout with a Metal application. Thank you to Asahi Lina and Dougall Johnson for the reverse-engineering that led to this. The tests selected here are a subset of those used for the reverse-engineering. The full set may be found in Lina's tilecalc repo: https://github.com/asahilina/tilecalc Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/layout/meson.build | 19 + src/asahi/layout/tests/test-layout.cpp | 1301 ++++++++++++++++++++++++ 2 files changed, 1320 insertions(+) create mode 100644 src/asahi/layout/tests/test-layout.cpp diff --git a/src/asahi/layout/meson.build b/src/asahi/layout/meson.build index 918a6a20cbc..6b1bac9f8a9 100644 --- a/src/asahi/layout/meson.build +++ b/src/asahi/layout/meson.build @@ -31,3 +31,22 @@ libasahi_layout = static_library( gnu_symbol_visibility : 'hidden', build_by_default : false, ) + +if with_tests + test( + 'asahi_layout_tests', + executable( + 'asahi_layout_tests', + files( + 'tests/test-layout.cpp', + ), + c_args : [c_msvc_compat_args, no_override_init_args], + gnu_symbol_visibility : 'hidden', + include_directories : [inc_include, inc_src], + dependencies: [idep_gtest, idep_mesautil], + link_with : [libasahi_layout], + ), + suite : ['asahi'], + protocol : gtest_test_protocol, + ) +endif diff --git a/src/asahi/layout/tests/test-layout.cpp b/src/asahi/layout/tests/test-layout.cpp new file mode 100644 index 00000000000..2d2d2740bb9 --- /dev/null +++ b/src/asahi/layout/tests/test-layout.cpp @@ -0,0 +1,1301 @@ +/* + * Copyright (C) 2022 Alyssa Rosenzweig + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include "layout.h" + +TEST(Miptree, SmokeTestBuffer) +{ + struct ail_layout layout = { + .width_px = 81946, + .height_px = 1, + .depth_px = 1, + .levels = 1, + .tiling = AIL_TILING_LINEAR, + .format = PIPE_FORMAT_R8_UINT, + }; + + ail_make_miptree(&layout); + + EXPECT_EQ(layout.size_B, ALIGN_POT(81946, 0x4000)); +} + +/* + * Test miptree layouts. All test cases in this file are extracted from memory + * dumps of a test pattern ran through Metal. + */ +struct miptest { + enum pipe_format format; + uint32_t width, height; + uint8_t levels; + uint32_t offsets[16]; +}; + +static struct miptest miptests[] = { + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 1024, + 1024, + 10, + { + 0, + 0x400000, + 0x500000, + 0x540000, + 0x550000, + 0x554000, + 0x555000, + 0x555400, + 0x555500, + 0x555580 + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 1023, + 1024, + 10, + { + 0, + 0x400000, + 0x500000, + 0x540000, + 0x550000, + 0x554000, + 0x555000, + 0x555400, + 0x555500, + 0x555580 + }, + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 961, + 1024, + 10, + { + 0x0, + 0x400000, + 0x500000, + 0x540000, + 0x550000, + 0x554000, + 0x555000, + 0x555400, + 0x555500, + 0x555580, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 960, + 1024, + 10, + { + 0x0, + 0x3C0000, + 0x4D0000, + 0x51C000, + 0x530000, + 0x534000, + 0x535000, + 0x535400, + 0x535500, + 0x535580, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 959, + 1024, + 10, + { + 0x0, + 0x3C0000, + 0x4D0000, + 0x51C000, + 0x530000, + 0x534000, + 0x535000, + 0x535400, + 0x535500, + 0x535580, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 897, + 1024, + 10, + { + 0x0, + 0x3C0000, + 0x4D0000, + 0x51C000, + 0x530000, + 0x534000, + 0x535000, + 0x535400, + 0x535500, + 0x535580, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 896, + 1024, + 10, + { + 0x0, + 0x380000, + 0x460000, + 0x4A8000, + 0x4BC000, + 0x4C0000, + 0x4C1000, + 0x4C1400, + 0x4C1500, + 0x4C1580, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 895, + 1024, + 10, + { + 0x0, + 0x380000, + 0x460000, + 0x4A8000, + 0x4BC000, + 0x4C0000, + 0x4C1000, + 0x4C1400, + 0x4C1500, + 0x4C1580, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 512, + 4096, + 12, + { + 0, + 0x800000, + 0xA00000, + 0xA80000, + 0xAA0000, + 0xAA8000, + 0xAAA000, + 0xAAA800, + 0xAAAA00, + 0xAAAA80, + 0xAAAB00, + 0xAAAB80 + }, + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 717, + 717, + 10, + { + 0, + 0x240000, + 0x2D0000, + 0x2F4000, + 0x308000, + 0x30C000, + 0x30D000, + 0x30D400, + 0x30D500, + 0x30D580 + }, + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 1024, + 717, + 10, + { + 0, + 0x300000, + 0x3C0000, + 0x3F0000, + 0x404000, + 0x408000, + 0x409000, + 0x409400, + 0x409500, + 0x409580 + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 717, + 1024, + 10, + { + 0, + 0x300000, + 0x3C0000, + 0x3F0000, + 0x404000, + 0x408000, + 0x409000, + 0x409400, + 0x409500, + 0x409580 + } + }, + { + PIPE_FORMAT_R8_UNORM, + 286, + 166, + 8, + { + 0, + 0x18000, + 0x20000, + 0x22000, + 0x22800, + 0x22A00, + 0x22A80, + 0x22B00 + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 644, + 3995, + 12, + { + 0, + 0xAD4000, + 0xE1C000, + 0xF10000, + 0xF5C000, + 0xF6C000, + 0xF70000, + 0xF71000, + 0xF71400, + 0xF71500, + 0xF71580, + 0xF71600 + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 286, + 166, + 8, + { + 0, + 0x3C000, + 0x58000, + 0x60000, + 0x62000, + 0x62800, + 0x62A00, + 0x62A80 + } + }, + /* Notice unaligned case gets aligned *first* and then mipped second. + * This explains some of the weirdness + */ + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 320, + 192, + 9, + { + 0x0, + 0x3C000, + 0x58000, + 0x60000, + 0x62000, + 0x62800, + 0x62A00, + 0x62A80, + 0x62B00, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 256, + 192, + 8, + { + 0x0, + 0x30000, + 0x44000, + 0x48000, + 0x49000, + 0x49400, + 0x49500, + 0x49580, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 256, + 191, + 8, + { + 0x0, + 0x30000, + 0x44000, + 0x48000, + 0x49000, + 0x49400, + 0x49500, + 0x49580, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 256, + 129, + 8, + { + 0x0, + 0x30000, + 0x44000, + 0x46000, + 0x46800, + 0x46A00, + 0x46A80, + 0x46B00, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 128, + 65, + 8, + { + 0x0, + 0x10000, + 0x12000, + 0x12800, + 0x12A00, + 0x12A80, + 0x12B00, + 0x12B80, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 64, + 128, + 7, + { + 0x0, + 0x8000, + 0xA000, + 0xA800, + 0xAA00, + 0xAA80, + 0xAB00, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 127, + 64, + 7, + { + 0x0, + 0x8000, + 0xA000, + 0xA800, + 0xAA00, + 0xAA80, + 0xAB00, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 96, + 64, + 7, + { + 0x0, + 0x8000, + 0xA000, + 0xA800, + 0xAA00, + 0xAA80, + 0xAB00, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 66, + 64, + 7, + { + 0x0, + 0x8000, + 0xA000, + 0xA800, + 0xAA00, + 0xAA80, + 0xAB00, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 64, + 65, + 7, + { + 0x0, + 0x8000, + 0x9000, + 0x9400, + 0x9500, + 0x9580, + 0x9600, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 65, + 64, + 7, + { + 0x0, + 0x8000, + 0x9000, + 0x9400, + 0x9500, + 0x9580, + 0x9600, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 64, + 64, + 6, + { + 0x0, + 0x4000, + 0x5000, + 0x5400, + 0x5500, + 0x5580, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 256, + 128, + 8, + { + 0x0, + 0x20000, + 0x28000, + 0x2A000, + 0x2A800, + 0x2AA00, + 0x2AA80, + 0x2AB00, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 33, + 29, + 6, + { + 0x0, + 0x2000, + 0x2800, + 0x2A00, + 0x2A80, + 0x2B00, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 33, + 32, + 6, + { + 0x0, + 0x2000, + 0x2800, + 0x2A00, + 0x2A80, + 0x2B00, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 64, + 32, + 7, + { + 0x0, + 0x2000, + 0x2800, + 0x2A00, + 0x2A80, + 0x2B00, + 0x2B80, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 128, + 16, + 8, + { + 0x0, + 0x2000, + 0x2800, + 0x2A00, + 0x2A80, + 0x2B00, + 0x2B80, + 0x2C00, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 256, + 8, + 9, + { + 0x0, + 0x2000, + 0x2800, + 0x2A00, + 0x2A80, + 0x2B00, + 0x2B80, + 0x2C00, + 0x2C80, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 512, + 4, + 10, + { + 0x0, + 0x2000, + 0x2800, + 0x2A00, + 0x2B00, + 0x2B80, + 0x2C00, + 0x2C80, + 0x2D00, + 0x2D80, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 32, + 32, + 6, + { + 0x0, + 0x1000, + 0x1400, + 0x1500, + 0x1580, + 0x1600, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 64, + 16, + 7, + { + 0x0, + 0x1000, + 0x1400, + 0x1500, + 0x1580, + 0x1600, + 0x1680, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 32, + 29, + 6, + { + 0x0, + 0x1000, + 0x1400, + 0x1500, + 0x1580, + 0x1600, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 15, + 1, + 4, + { + 0x0, + 0x80, + 0x100, + 0x180, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 31, + 1, + 4, + { + 0x0, + 0x80, + 0x100, + 0x180, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 63, + 1, + 4, + { + 0x0, + 0x100, + 0x180, + 0x200, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 8, + 7, + 4, + { + 0x0, + 0x100, + 0x180, + 0x200, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 1024, + 64, + 10, + { + 0x0, + 0x40000, + 0x50000, + 0x54000, + 0x55000, + 0x55400, + 0x55500, + 0x55580, + 0x55600, + 0x55680, + } + }, + { + PIPE_FORMAT_R8G8B8A8_UNORM, + 47, + 27, + 6, + { + 0x0, + 0x2000, + 0x2800, + 0x2A00, + 0x2A80, + 0x2B00, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 64, + 32, + 6, + { + 0x0, + 0x4000, + 0x5000, + 0x5400, + 0x5500, + 0x5580, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 32, + 64, + 6, + { + 0x0, + 0x4000, + 0x5000, + 0x5400, + 0x5500, + 0x5580, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 292, + 164, + 9, + { + 0x0, + 0x78000, + 0xA0000, + 0xB0000, + 0xB4000, + 0xB5000, + 0xB5400, + 0xB5500, + 0xB5580, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 284, + 916, + 10, + { + 0x0, + 0x244000, + 0x318000, + 0x360000, + 0x370000, + 0x374000, + 0x375000, + 0x375400, + 0x375500, + 0x375580, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 60, + 3, + 6, + { + 0x0, + 0x800, + 0xA00, + 0xA80, + 0xB00, + 0xB80, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 60, + 16, + 6, + { + 0x0, + 0x2000, + 0x2800, + 0x2A00, + 0x2A80, + 0x2B00, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 60, + 920, + 10, + { + 0x0, + 0x80000, + 0xA0000, + 0xA8000, + 0xAA000, + 0xAA800, + 0xAAA00, + 0xAAA80, + 0xAAB00, + 0xAAB80, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 128, + 128, + 7, + { + 0x0, + 0x20000, + 0x28000, + 0x2A000, + 0x2A800, + 0x2AA00, + 0x2AA80, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 64, + 64, + 6, + { + 0x0, + 0x8000, + 0xA000, + 0xA800, + 0xAA00, + 0xAA80, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 60, + 16, + 6, + { + 0x0, + 0x2000, + 0x2800, + 0x2A00, + 0x2A80, + 0x2B00, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 8, + 16, + 4, + { + 0x0, + 0x400, + 0x500, + 0x580, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 4, + 16, + 4, + { + 0x0, + 0x200, + 0x280, + 0x300, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 32, + 16, + 5, + { + 0x0, + 0x1000, + 0x1400, + 0x1500, + 0x1580, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 1024, + 1024, + 10, + { + 0x0, + 0x800000, + 0xA00000, + 0xA80000, + 0xAA0000, + 0xAA8000, + 0xAAA000, + 0xAAA800, + 0xAAAA00, + 0xAAAA80, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 917, + 285, + 10, + { + 0x0, + 0x21C000, + 0x2D0000, + 0x308000, + 0x31C000, + 0x320000, + 0x321000, + 0x321400, + 0x321500, + 0x321580, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 153, + 777, + 10, + { + 0x0, + 0x12C000, + 0x1AC000, + 0x1CC000, + 0x1D4000, + 0x1D6000, + 0x1D6800, + 0x1D6A00, + 0x1D6A80, + 0x1D6B00, + } + }, + { + PIPE_FORMAT_R16G16B16A16_UNORM, + 4995, + 791, + 13, + { + 0x0, + 0x1EDC000, + 0x2760000, + 0x29B4000, + 0x2A60000, + 0x2A94000, + 0x2AA4000, + 0x2AA8000, + 0x2AA9000, + 0x2AA9400, + 0x2AA9500, + 0x2AA9580, + 0x2AA9600, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 64, + 32, + 6, + { + 0x0, + 0x400, + 0x500, + 0x580, + 0x600, + 0x680, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 32, + 64, + 6, + { + 0x0, + 0x400, + 0x500, + 0x580, + 0x600, + 0x680, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 292, + 164, + 9, + { + 0x0, + 0x10000, + 0x14000, + 0x15000, + 0x15400, + 0x15500, + 0x15580, + 0x15600, + 0x15680, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 284, + 916, + 10, + { + 0x0, + 0x40000, + 0x50000, + 0x54000, + 0x55000, + 0x55400, + 0x55500, + 0x55580, + 0x55600, + 0x55680, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 60, + 3, + 6, + { + 0x0, + 0x80, + 0x100, + 0x180, + 0x200, + 0x280, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 60, + 16, + 6, + { + 0x0, + 0x200, + 0x280, + 0x300, + 0x380, + 0x400, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 60, + 920, + 10, + { + 0x0, + 0x8000, + 0xA000, + 0xA800, + 0xAA00, + 0xAA80, + 0xAB00, + 0xAB80, + 0xAC00, + 0xAC80, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 128, + 128, + 7, + { + 0x0, + 0x2000, + 0x2800, + 0x2A00, + 0x2A80, + 0x2B00, + 0x2B80, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 64, + 64, + 6, + { + 0x0, + 0x800, + 0xA00, + 0xA80, + 0xB00, + 0xB80, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 60, + 16, + 6, + { + 0x0, + 0x200, + 0x280, + 0x300, + 0x380, + 0x400, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 8, + 16, + 4, + { + 0x0, + 0x80, + 0x100, + 0x180, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 4, + 16, + 4, + { + 0x0, + 0x80, + 0x100, + 0x180, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 32, + 16, + 5, + { + 0x0, + 0x100, + 0x180, + 0x200, + 0x280, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 1024, + 1024, + 10, + { + 0x0, + 0x80000, + 0xA0000, + 0xA8000, + 0xAA000, + 0xAA800, + 0xAAA00, + 0xAAA80, + 0xAAB00, + 0xAAB80, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 917, + 285, + 10, + { + 0x0, + 0x30000, + 0x44000, + 0x48000, + 0x49000, + 0x49400, + 0x49500, + 0x49580, + 0x49600, + 0x49680, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 153, + 777, + 10, + { + 0x0, + 0x20000, + 0x28000, + 0x2A000, + 0x2A800, + 0x2AA00, + 0x2AA80, + 0x2AB00, + 0x2AB80, + 0x2AC00, + } + }, + { + PIPE_FORMAT_ETC2_RGB8, + 4995, + 791, + 13, + { + 0x0, + 0x230000, + 0x2E4000, + 0x318000, + 0x328000, + 0x32C000, + 0x32D000, + 0x32D400, + 0x32D500, + 0x32D580, + 0x32D600, + 0x32D680, + 0x32D700, + } + }, +}; + +TEST(Miptree, Tests2D) +{ + for (unsigned i = 0; i < ARRAY_SIZE(miptests); ++i) { + struct miptest test = miptests[i]; + + struct ail_layout layout = { + .width_px = test.width, + .height_px = test.height, + .depth_px = 1, + .levels = test.levels, + .tiling = AIL_TILING_TWIDDLED, + .format = test.format, + }; + + ail_make_miptree(&layout); + + for (unsigned l = 0; l < test.levels; ++l) { + EXPECT_EQ(ail_get_level_offset_B(&layout, l), test.offsets[l]) << + test.width << "x" << test.height << " " << + util_format_short_name(test.format) << + " texture has wrong offset at level " << l << + ", off by " << + test.offsets[l] - ail_get_level_offset_B(&layout, l); + } + } +}