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