xref: /aosp_15_r20/external/mesa3d/src/panfrost/lib/tests/test-clear.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (C) 2021 Collabora, Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #include "pan_texture.h"
25 #include "pan_util.h"
26 
27 /* A test consists of a render target format, clear colour, dither state, and
28  * translated form. Dither state matters when the tilebuffer format is more
29  * precise than the final format. */
30 struct test {
31    enum pipe_format format;
32    bool dithered;
33    union pipe_color_union colour;
34    uint32_t packed[4];
35 };
36 
37 #define RRRR(r)                                                                \
38    {                                                                           \
39       r, r, r, r                                                               \
40    }
41 #define RGRG(r, g)                                                             \
42    {                                                                           \
43       r, g, r, g                                                               \
44    }
45 #define F(r, g, b, a)                                                          \
46    {                                                                           \
47       .f = { r, g, b, a }                                                      \
48    }
49 #define UI(r, g, b, a)                                                         \
50    {                                                                           \
51       .ui = { r, g, b, a }                                                     \
52    }
53 #define D (true)
54 #define _ (false)
55 
56 /* clang-format off */
57 static const struct test clear_tests[] = {
58    /* Basic tests */
59    { PIPE_FORMAT_R8G8B8A8_UNORM,    D, F(0.0,   0.0, 0.0, 0.0),   RRRR(0x00000000) },
60    { PIPE_FORMAT_R8G8B8A8_UNORM,    _, F(0.0,   0.0, 0.0, 0.0),   RRRR(0x00000000) },
61    { PIPE_FORMAT_R8G8B8A8_UNORM,    D, F(1.0,   0.0, 0.0, 1.0),   RRRR(0xFF0000FF) },
62    { PIPE_FORMAT_R8G8B8A8_UNORM,    _, F(1.0,   0.0, 0.0, 1.0),   RRRR(0xFF0000FF) },
63    { PIPE_FORMAT_B8G8R8A8_UNORM,    D, F(1.0,   0.0, 0.0, 1.0),   RRRR(0xFF0000FF) },
64    { PIPE_FORMAT_B8G8R8A8_UNORM,    _, F(1.0,   0.0, 0.0, 1.0),   RRRR(0xFF0000FF) },
65    { PIPE_FORMAT_R8G8B8A8_UNORM,    D, F(0.664, 0.0, 0.0, 0.0),   RRRR(0x000000A9) },
66    { PIPE_FORMAT_R8G8B8A8_UNORM,    _, F(0.664, 0.0, 0.0, 0.0),   RRRR(0x000000A9) },
67    { PIPE_FORMAT_R4G4B4A4_UNORM,    D, F(0.664, 0.0, 0.0, 0.0),   RRRR(0x0000009F) },
68    { PIPE_FORMAT_R4G4B4A4_UNORM,    _, F(0.664, 0.0, 0.0, 0.0),   RRRR(0x000000A0) },
69 
70    /* Test rounding to nearest even. The values are cherrypicked to multiply
71     * out to a fractional part of 0.5. The first test should round down and
72     * second test should round up. */
73 
74    { PIPE_FORMAT_R4G4B4A4_UNORM,    D, F(0.41875, 0.0, 0.0, 1.0), RRRR(0xF0000064) },
75    { PIPE_FORMAT_R4G4B4A4_UNORM,    D, F(0.40625, 0.0, 0.0, 1.0), RRRR(0xF0000062) },
76 
77    /* Testing rounding direction when dithering is disabled. The packed value
78     * is what gets rounded. This behaves as round-to-even with the cutoff point
79     * at 2^-m + 2^-n for an m:n representation. */
80 
81    { PIPE_FORMAT_R4G4B4A4_UNORM,    _, F(0.03125, 0.0, 0.0, 1.0),  RRRR(0xF0000000) },
82    { PIPE_FORMAT_R4G4B4A4_UNORM,    _, F(0.03125, 0.0, 0.0, 1.0),  RRRR(0xF0000000) },
83    { PIPE_FORMAT_R4G4B4A4_UNORM,    _, F(0.03333, 0.0, 0.0, 1.0),  RRRR(0xF0000000) },
84    { PIPE_FORMAT_R4G4B4A4_UNORM,    _, F(0.03334, 0.0, 0.0, 1.0),  RRRR(0xF0000010) },
85    { PIPE_FORMAT_R4G4B4A4_UNORM,    _, F(0.09375, 0.0, 0.0, 1.0),  RRRR(0xF0000010) },
86 
87    /* Check all the special formats with different edge cases */
88 
89    { PIPE_FORMAT_R4G4B4A4_UNORM,    D, F(0.127, 2.4, -1.0, 0.5), RRRR(0x7800F01E) },
90    { PIPE_FORMAT_R5G5B5A1_UNORM,    D, F(0.127, 2.4, -1.0, 0.5), RRRR(0x400F807E) },
91    { PIPE_FORMAT_R5G6B5_UNORM,      D, F(0.127, 2.4, -1.0, 0.5), RRRR(0x000FC07E) },
92    { PIPE_FORMAT_R10G10B10A2_UNORM, D, F(0.127, 2.4, -1.0, 0.5), RRRR(0x800FFC82) },
93    { PIPE_FORMAT_R8G8B8A8_SRGB,     D, F(0.127, 2.4, -1.0, 0.5), RRRR(0x8000FF64) },
94 
95    { PIPE_FORMAT_R4G4B4A4_UNORM,    D, F(0.718, 0.18, 1.0, 2.0), RRRR(0xF0F02BAC) },
96    { PIPE_FORMAT_R5G6B5_UNORM,      D, F(0.718, 0.18, 1.0, 2.0), RRRR(0x3E02D6C8) },
97    { PIPE_FORMAT_R5G5B5A1_UNORM,    D, F(0.718, 0.18, 1.0, 2.0), RRRR(0xBE02CEC8) },
98    { PIPE_FORMAT_R10G10B10A2_UNORM, D, F(0.718, 0.18, 1.0, 2.0), RRRR(0xFFF2E2DF) },
99    { PIPE_FORMAT_R8G8B8A8_SRGB,     D, F(0.718, 0.18, 1.0, 2.0), RRRR(0xFFFF76DC) },
100 
101    /* Check that values are padded when dithering is disabled */
102 
103    { PIPE_FORMAT_R4G4B4A4_UNORM,    _, F(0.718, 0.18, 1.0, 2.0), RRRR(0xF0F030B0) },
104    { PIPE_FORMAT_R5G6B5_UNORM,      _, F(0.718, 0.18, 1.0, 2.0), RRRR(0x3E02C2C0) },
105    { PIPE_FORMAT_R5G5B5A1_UNORM,    _, F(0.718, 0.18, 1.0, 2.0), RRRR(0xBE0302C0) },
106    { PIPE_FORMAT_R10G10B10A2_UNORM, _, F(0.718, 0.18, 1.0, 2.0), RRRR(0xFFF2E2DF) },
107    { PIPE_FORMAT_R8G8B8A8_SRGB,     _, F(0.718, 0.18, 1.0, 2.0), RRRR(0xFFFF76DC) },
108 
109    /* Check that blendable tilebuffer values are invariant under swizzling */
110 
111    { PIPE_FORMAT_B4G4R4A4_UNORM,    D, F(0.127, 2.4, -1.0, 0.5), RRRR(0x7800F01E) },
112    { PIPE_FORMAT_B5G5R5A1_UNORM,    D, F(0.127, 2.4, -1.0, 0.5), RRRR(0x400F807E) },
113    { PIPE_FORMAT_B5G6R5_UNORM,      D, F(0.127, 2.4, -1.0, 0.5), RRRR(0x000FC07E) },
114    { PIPE_FORMAT_B10G10R10A2_UNORM, D, F(0.127, 2.4, -1.0, 0.5), RRRR(0x800FFC82) },
115    { PIPE_FORMAT_B8G8R8A8_SRGB,     D, F(0.127, 2.4, -1.0, 0.5), RRRR(0x8000FF64) },
116 
117    { PIPE_FORMAT_B4G4R4A4_UNORM,    D, F(0.718, 0.18, 1.0, 2.0), RRRR(0xF0F02BAC) },
118    { PIPE_FORMAT_B5G6R5_UNORM,      D, F(0.718, 0.18, 1.0, 2.0), RRRR(0x3E02D6C8) },
119    { PIPE_FORMAT_B5G5R5A1_UNORM,    D, F(0.718, 0.18, 1.0, 2.0), RRRR(0xBE02CEC8) },
120    { PIPE_FORMAT_B10G10R10A2_UNORM, D, F(0.718, 0.18, 1.0, 2.0), RRRR(0xFFF2E2DF) },
121    { PIPE_FORMAT_B8G8R8A8_SRGB,     D, F(0.718, 0.18, 1.0, 2.0), RRRR(0xFFFF76DC) },
122 
123    { PIPE_FORMAT_B4G4R4A4_UNORM,    _, F(0.718, 0.18, 1.0, 2.0), RRRR(0xF0F030B0) },
124    { PIPE_FORMAT_B5G6R5_UNORM,      _, F(0.718, 0.18, 1.0, 2.0), RRRR(0x3E02C2C0) },
125    { PIPE_FORMAT_B5G5R5A1_UNORM,    _, F(0.718, 0.18, 1.0, 2.0), RRRR(0xBE0302C0) },
126    { PIPE_FORMAT_B10G10R10A2_UNORM, _, F(0.718, 0.18, 1.0, 2.0), RRRR(0xFFF2E2DF) },
127    { PIPE_FORMAT_B8G8R8A8_SRGB,     _, F(0.718, 0.18, 1.0, 2.0), RRRR(0xFFFF76DC) },
128 
129    /* Check raw formats, which are not invariant under swizzling. Raw formats
130     * cannot be dithered. */
131 
132    { PIPE_FORMAT_R8G8B8A8_UINT,   D, UI(0xCA, 0xFE, 0xBA, 0xBE), RRRR(0xBEBAFECA) },
133    { PIPE_FORMAT_R8G8B8A8_UINT,   _, UI(0xCA, 0xFE, 0xBA, 0xBE), RRRR(0xBEBAFECA) },
134 
135    { PIPE_FORMAT_B8G8R8A8_UINT,   D, UI(0xCA, 0xFE, 0xBA, 0xBE), RRRR(0xBECAFEBA) },
136    { PIPE_FORMAT_B8G8R8A8_UINT,   _, UI(0xCA, 0xFE, 0xBA, 0xBE), RRRR(0xBECAFEBA) },
137 
138    /* Check that larger raw formats are replicated correctly */
139 
140    { PIPE_FORMAT_R16G16B16A16_UINT, D, UI(0xCAFE, 0xBABE, 0xABAD, 0x1DEA),
141                                        RGRG(0xBABECAFE, 0x1DEAABAD) },
142 
143    { PIPE_FORMAT_R16G16B16A16_UINT, _, UI(0xCAFE, 0xBABE, 0xABAD, 0x1DEA),
144                                        RGRG(0xBABECAFE, 0x1DEAABAD) },
145 
146    { PIPE_FORMAT_R32G32B32A32_UINT, D,
147       UI(0xCAFEBABE, 0xABAD1DEA, 0xDEADBEEF, 0xABCDEF01),
148       { 0xCAFEBABE, 0xABAD1DEA, 0xDEADBEEF, 0xABCDEF01 } },
149 
150    { PIPE_FORMAT_R32G32B32A32_UINT, _,
151       UI(0xCAFEBABE, 0xABAD1DEA, 0xDEADBEEF, 0xABCDEF01),
152       { 0xCAFEBABE, 0xABAD1DEA, 0xDEADBEEF, 0xABCDEF01 } },
153 };
154 /* clang-format on */
155 
156 #define ASSERT_EQ(x, y)                                                                      \
157    do {                                                                                      \
158       if ((x[0] == y[0]) && (x[1] == y[1]) && (x[2] == y[2]) &&                              \
159           (x[3] == y[3])) {                                                                  \
160          nr_pass++;                                                                          \
161       } else {                                                                               \
162          nr_fail++;                                                                          \
163          fprintf(                                                                            \
164             stderr,                                                                          \
165             "%s%s: Assertion failed %s (%08X %08X %08X %08X) != %s (%08X %08X %08X %08X)\n", \
166             util_format_short_name(T.format), T.dithered ? " dithered" : "",                 \
167             #x, x[0], x[1], x[2], x[3], #y, y[0], y[1], y[2], y[3]);                         \
168       }                                                                                      \
169    } while (0)
170 
171 int
main(int argc,const char ** argv)172 main(int argc, const char **argv)
173 {
174    unsigned nr_pass = 0, nr_fail = 0;
175 
176    for (unsigned i = 0; i < ARRAY_SIZE(clear_tests); ++i) {
177       struct test T = clear_tests[i];
178       uint32_t packed[4];
179       pan_pack_color(panfrost_blendable_formats_v7, &packed[0], &T.colour,
180                      T.format, T.dithered);
181 
182       ASSERT_EQ(T.packed, packed);
183    }
184 
185    printf("Passed %u/%u\n", nr_pass, nr_pass + nr_fail);
186    return nr_fail ? 1 : 0;
187 }
188