xref: /aosp_15_r20/external/mesa3d/src/panfrost/lib/tests/test-blend.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_blend.h"
25 
26 /* A test consists of a given blend mode and its translated form */
27 struct test {
28    const char *label;
29    struct pan_blend_equation eq;
30    unsigned constant_mask;
31    bool reads_dest;
32    bool opaque;
33    bool fixed_function;
34    bool alpha_zero_nop;
35    bool alpha_one_store;
36    uint32_t hardware;
37 };
38 
39 /* clang-format off */
40 #define RGBA(key, value) \
41    .rgb_ ## key = value, \
42    .alpha_ ## key = value
43 
44 static const struct test blend_tests[] = {
45    {
46       "Replace",
47       {
48          .blend_enable = false,
49          .color_mask = 0xF,
50       },
51       .constant_mask = 0x0,
52       .reads_dest = false,
53       .opaque = true,
54       .fixed_function = true,
55       .alpha_zero_nop = false,
56       .alpha_one_store = false,
57       .hardware = 0xF0122122
58    },
59    {
60       "Alpha",
61       {
62          .blend_enable = true,
63          .color_mask = 0xF,
64 
65          RGBA(func, PIPE_BLEND_ADD),
66          RGBA(src_factor, PIPE_BLENDFACTOR_SRC_ALPHA),
67          RGBA(dst_factor, PIPE_BLENDFACTOR_INV_SRC_ALPHA),
68       },
69       .constant_mask = 0x0,
70       .reads_dest = true,
71       .opaque = false,
72       .fixed_function = true,
73       .alpha_zero_nop = true,
74       .alpha_one_store = true,
75       .hardware = 0xF0503503
76    },
77    {
78       "Additive",
79       {
80          .blend_enable = true,
81          .color_mask = 0xF,
82 
83          RGBA(func, PIPE_BLEND_ADD),
84          RGBA(src_factor, PIPE_BLENDFACTOR_ONE),
85          RGBA(dst_factor, PIPE_BLENDFACTOR_ONE),
86       },
87       .constant_mask = 0x0,
88       .reads_dest = true,
89       .opaque = false,
90       .fixed_function = true,
91       .alpha_zero_nop = false,
92       .alpha_one_store = false,
93       .hardware = 0xF0932932 /* equivalently 0xF0923923 */
94    },
95    {
96       "Additive-Alpha",
97       {
98          .blend_enable = true,
99          .color_mask = 0xF,
100 
101          RGBA(func, PIPE_BLEND_ADD),
102          RGBA(src_factor, PIPE_BLENDFACTOR_SRC_ALPHA),
103          RGBA(dst_factor, PIPE_BLENDFACTOR_ONE),
104       },
105       .constant_mask = 0x0,
106       .reads_dest = true,
107       .opaque = false,
108       .fixed_function = true,
109       .alpha_zero_nop = true,
110       .alpha_one_store = false,
111       .hardware = 0xF0523523
112    },
113    {
114       "Subtractive",
115       {
116          .blend_enable = true,
117          .color_mask = 0xF,
118 
119          RGBA(func, PIPE_BLEND_SUBTRACT),
120          RGBA(src_factor, PIPE_BLENDFACTOR_ONE),
121          RGBA(dst_factor, PIPE_BLENDFACTOR_ONE),
122       },
123       .constant_mask = 0x0,
124       .reads_dest = true,
125       .opaque = false,
126       .fixed_function = true,
127       .alpha_zero_nop = false,
128       .alpha_one_store = false,
129       .hardware = 0xF09B29B2 /* equivalently 0xF09A39A3 */
130    },
131    {
132       "Subtractive-Alpha",
133       {
134          .blend_enable = true,
135          .color_mask = 0xF,
136 
137          RGBA(func, PIPE_BLEND_SUBTRACT),
138          RGBA(src_factor, PIPE_BLENDFACTOR_SRC_ALPHA),
139          RGBA(dst_factor, PIPE_BLENDFACTOR_ONE),
140       },
141       .constant_mask = 0x0,
142       .reads_dest = true,
143       .opaque = false,
144       .fixed_function = true,
145       .alpha_zero_nop = false,
146       .alpha_one_store = false,
147       .hardware = 0xF052B52b /* equivalently 0xF05A35A3 */
148    },
149    {
150       "Modulate",
151       {
152          .blend_enable = true,
153          .color_mask = 0xF,
154 
155          RGBA(func, PIPE_BLEND_ADD),
156          RGBA(src_factor, PIPE_BLENDFACTOR_ZERO),
157          RGBA(dst_factor, PIPE_BLENDFACTOR_SRC_COLOR),
158       },
159       .constant_mask = 0x0,
160       .reads_dest = true,
161       .opaque = false,
162       .fixed_function = true,
163       .alpha_zero_nop = false,
164       .alpha_one_store = false,
165       .hardware = 0xF0231231 /* equivalently 0xF0321321 */
166    },
167    {
168       "Replace masked",
169       {
170          .blend_enable = false,
171          .color_mask = 0x3,
172       },
173       .constant_mask = 0x0,
174       .reads_dest = true,
175       .opaque = false,
176       .fixed_function = true,
177       .alpha_zero_nop = false,
178       .alpha_one_store = false,
179       .hardware = 0x30122122
180    },
181    {
182       "Modulate masked",
183       {
184          .blend_enable = true,
185          .color_mask = 0xA,
186 
187          RGBA(func, PIPE_BLEND_ADD),
188          RGBA(src_factor, PIPE_BLENDFACTOR_ZERO),
189          RGBA(dst_factor, PIPE_BLENDFACTOR_SRC_COLOR),
190       },
191       .constant_mask = 0x0,
192       .reads_dest = true,
193       .opaque = false,
194       .fixed_function = true,
195       .alpha_zero_nop = false,
196       .alpha_one_store = false,
197       .hardware = 0xA0231231 /* equivalently 0xA0321321 */
198    },
199    {
200       "src*dst + dst*src",
201       {
202          .blend_enable = true,
203          .color_mask = 0xF,
204 
205          RGBA(func, PIPE_BLEND_ADD),
206          RGBA(src_factor, PIPE_BLENDFACTOR_DST_COLOR),
207          RGBA(dst_factor, PIPE_BLENDFACTOR_SRC_COLOR),
208       },
209       .constant_mask = 0x0,
210       .reads_dest = true,
211       .opaque = false,
212       .fixed_function = true,
213       .alpha_zero_nop = false,
214       .alpha_one_store = false,
215       .hardware = 0xF0431431 /* 0 + dest * (2*src) */
216    },
217    {
218       "Mixed src*dst + dst*src masked I",
219       {
220          .blend_enable = true,
221          .color_mask = 0xC,
222 
223          .rgb_func = PIPE_BLEND_ADD,
224          .rgb_src_factor = PIPE_BLENDFACTOR_ONE,
225          .rgb_dst_factor= PIPE_BLENDFACTOR_ZERO,
226 
227          .alpha_func = PIPE_BLEND_ADD,
228          .alpha_src_factor = PIPE_BLENDFACTOR_DST_COLOR,
229          .alpha_dst_factor= PIPE_BLENDFACTOR_SRC_COLOR,
230       },
231       .constant_mask = 0x0,
232       .reads_dest = true,
233       .opaque = false,
234       .fixed_function = true,
235       .alpha_zero_nop = false,
236       .alpha_one_store = false,
237       .hardware = 0xC0431132 /* 0 + dest * (2*src); equivalent 0xC0431122 */
238    },
239    {
240       "Mixed src*dst + dst*src masked II",
241       {
242          .blend_enable = true,
243          .color_mask = 0xC,
244 
245          .rgb_func = PIPE_BLEND_ADD,
246          .rgb_src_factor = PIPE_BLENDFACTOR_ONE,
247          .rgb_dst_factor = PIPE_BLENDFACTOR_ZERO,
248 
249          .alpha_func = PIPE_BLEND_ADD,
250          .alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA,
251          .alpha_dst_factor= PIPE_BLENDFACTOR_SRC_COLOR,
252       },
253       .constant_mask = 0x0,
254       .reads_dest = true,
255       .opaque = false,
256       .fixed_function = true,
257       .alpha_zero_nop = false,
258       .alpha_one_store = false,
259       .hardware = 0xC0431132 /* 0 + dest * (2*src); equivalent 0xC0431122 */
260    },
261    {
262       "Mixed src*dst + dst*src masked III",
263       {
264          .blend_enable = true,
265          .color_mask = 0xC,
266 
267          .rgb_func = PIPE_BLEND_ADD,
268          .rgb_src_factor = PIPE_BLENDFACTOR_ONE,
269          .rgb_dst_factor = PIPE_BLENDFACTOR_ZERO,
270 
271          .alpha_func = PIPE_BLEND_ADD,
272          .alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA,
273          .alpha_dst_factor= PIPE_BLENDFACTOR_SRC_ALPHA,
274       },
275       .constant_mask = 0x0,
276       .reads_dest = true,
277       .opaque = false,
278       .fixed_function = true,
279       .alpha_zero_nop = false,
280       .alpha_one_store = false,
281       .hardware = 0xC0431132 /* 0 + dest * (2*src); equivalent 0xC0431122 */
282    }
283 };
284 /* clang-format on */
285 
286 #define ASSERT_EQ(x, y)                                                        \
287    do {                                                                        \
288       if (x == y) {                                                            \
289          nr_pass++;                                                            \
290       } else {                                                                 \
291          nr_fail++;                                                            \
292          fprintf(stderr, "%s: Assertion failed %s (%x) != %s (%x)\n", T.label, \
293                  #x, x, #y, y);                                                \
294       }                                                                        \
295    } while (0)
296 
297 int
main(int argc,const char ** argv)298 main(int argc, const char **argv)
299 {
300    unsigned nr_pass = 0, nr_fail = 0;
301 
302    for (unsigned i = 0; i < ARRAY_SIZE(blend_tests); ++i) {
303       struct test T = blend_tests[i];
304       ASSERT_EQ(T.constant_mask, pan_blend_constant_mask(T.eq));
305       ASSERT_EQ(T.reads_dest, pan_blend_reads_dest(T.eq));
306       ASSERT_EQ(T.opaque, pan_blend_is_opaque(T.eq));
307       ASSERT_EQ(T.fixed_function, pan_blend_can_fixed_function(T.eq, true));
308       ASSERT_EQ(T.alpha_zero_nop, pan_blend_alpha_zero_nop(T.eq));
309       ASSERT_EQ(T.alpha_one_store, pan_blend_alpha_one_store(T.eq));
310 
311       if (pan_blend_can_fixed_function(T.eq, true)) {
312          ASSERT_EQ(T.hardware, pan_pack_blend(T.eq));
313       }
314    }
315 
316    printf("Passed %u/%u\n", nr_pass, nr_pass + nr_fail);
317    return nr_fail ? 1 : 0;
318 }
319