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