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