blob: e49b70559825c095b56c393dbe970e4d1744ae31 [file] [log] [blame]
José Fonseca7d043162009-08-01 17:59:19 +01001/**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29/**
30 * @file
31 * Unit tests for blend LLVM IR generation
32 *
33 * @author Jose Fonseca <jfonseca@vmware.com>
34 *
35 * Blend computation code derived from code written by
36 * @author Brian Paul <brian@vmware.com>
37 */
38
39
Zack Rusinc61bf362010-02-08 18:05:22 -050040#include "gallivm/lp_bld_type.h"
41#include "gallivm/lp_bld_blend.h"
42#include "gallivm/lp_bld_debug.h"
José Fonsecae6ebebc2009-08-07 01:20:01 +010043#include "lp_test.h"
José Fonseca7d043162009-08-01 17:59:19 +010044
45
José Fonseca2529ed52009-08-09 12:39:38 +010046enum vector_mode
47{
48 AoS = 0,
49 SoA = 1
50};
51
52
José Fonseca5940ba22009-08-04 02:10:35 +010053typedef void (*blend_test_ptr_t)(const void *src, const void *dst, const void *con, void *res);
José Fonsecab94e22e2009-08-03 19:35:28 +010054
55
José Fonsecae6ebebc2009-08-07 01:20:01 +010056void
José Fonsecaa77084e2009-08-04 11:52:54 +010057write_tsv_header(FILE *fp)
58{
59 fprintf(fp,
60 "result\t"
José Fonsecab07d19a2009-08-08 20:38:01 +010061 "cycles_per_channel\t"
José Fonseca2529ed52009-08-09 12:39:38 +010062 "mode\t"
José Fonsecaa77084e2009-08-04 11:52:54 +010063 "type\t"
José Fonseca1165c302009-08-04 13:39:28 +010064 "sep_func\t"
65 "sep_src_factor\t"
66 "sep_dst_factor\t"
José Fonsecaa77084e2009-08-04 11:52:54 +010067 "rgb_func\t"
68 "rgb_src_factor\t"
69 "rgb_dst_factor\t"
70 "alpha_func\t"
71 "alpha_src_factor\t"
72 "alpha_dst_factor\n");
73
74 fflush(fp);
75}
76
77
78static void
79write_tsv_row(FILE *fp,
80 const struct pipe_blend_state *blend,
José Fonseca2529ed52009-08-09 12:39:38 +010081 enum vector_mode mode,
José Fonsecab4835ea2009-09-14 11:05:06 +010082 struct lp_type type,
José Fonsecaa77084e2009-08-04 11:52:54 +010083 double cycles,
84 boolean success)
85{
86 fprintf(fp, "%s\t", success ? "pass" : "fail");
87
José Fonseca2529ed52009-08-09 12:39:38 +010088 if (mode == AoS) {
89 fprintf(fp, "%.1f\t", cycles / type.length);
90 fprintf(fp, "aos\t");
91 }
92
93 if (mode == SoA) {
94 fprintf(fp, "%.1f\t", cycles / (4 * type.length));
95 fprintf(fp, "soa\t");
96 }
José Fonsecaa77084e2009-08-04 11:52:54 +010097
98 fprintf(fp, "%s%u%sx%u\t",
99 type.floating ? "f" : (type.fixed ? "h" : (type.sign ? "s" : "u")),
100 type.width,
101 type.norm ? "n" : "",
102 type.length);
103
104 fprintf(fp,
José Fonseca1165c302009-08-04 13:39:28 +0100105 "%s\t%s\t%s\t",
Roland Scheidegger99e28d42010-01-25 16:35:56 +0100106 blend->rt[0].rgb_func != blend->rt[0].alpha_func ? "true" : "false",
107 blend->rt[0].rgb_src_factor != blend->rt[0].alpha_src_factor ? "true" : "false",
108 blend->rt[0].rgb_dst_factor != blend->rt[0].alpha_dst_factor ? "true" : "false");
José Fonseca1165c302009-08-04 13:39:28 +0100109
110 fprintf(fp,
José Fonsecaa77084e2009-08-04 11:52:54 +0100111 "%s\t%s\t%s\t%s\t%s\t%s\n",
Roland Scheidegger99e28d42010-01-25 16:35:56 +0100112 debug_dump_blend_func(blend->rt[0].rgb_func, TRUE),
113 debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE),
114 debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE),
115 debug_dump_blend_func(blend->rt[0].alpha_func, TRUE),
116 debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE),
117 debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE));
José Fonsecaa77084e2009-08-04 11:52:54 +0100118
119 fflush(fp);
120}
121
122
123static void
124dump_blend_type(FILE *fp,
125 const struct pipe_blend_state *blend,
José Fonseca2529ed52009-08-09 12:39:38 +0100126 enum vector_mode mode,
José Fonsecab4835ea2009-09-14 11:05:06 +0100127 struct lp_type type)
José Fonsecaa77084e2009-08-04 11:52:54 +0100128{
José Fonseca2529ed52009-08-09 12:39:38 +0100129 fprintf(fp, "%s", mode ? "soa" : "aos");
José Fonsecaa77084e2009-08-04 11:52:54 +0100130
131 fprintf(fp, " type=%s%u%sx%u",
132 type.floating ? "f" : (type.fixed ? "h" : (type.sign ? "s" : "u")),
133 type.width,
134 type.norm ? "n" : "",
135 type.length);
136
José Fonseca2529ed52009-08-09 12:39:38 +0100137 fprintf(fp,
138 " %s=%s %s=%s %s=%s %s=%s %s=%s %s=%s",
Roland Scheidegger99e28d42010-01-25 16:35:56 +0100139 "rgb_func", debug_dump_blend_func(blend->rt[0].rgb_func, TRUE),
140 "rgb_src_factor", debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE),
141 "rgb_dst_factor", debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE),
142 "alpha_func", debug_dump_blend_func(blend->rt[0].alpha_func, TRUE),
143 "alpha_src_factor", debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE),
144 "alpha_dst_factor", debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE));
José Fonseca2529ed52009-08-09 12:39:38 +0100145
José Fonseca3130b992009-08-08 23:15:05 +0100146 fprintf(fp, " ...\n");
José Fonsecaa77084e2009-08-04 11:52:54 +0100147 fflush(fp);
148}
149
150
José Fonseca7d043162009-08-01 17:59:19 +0100151static LLVMValueRef
152add_blend_test(LLVMModuleRef module,
José Fonsecaede73252009-08-03 00:01:27 +0100153 const struct pipe_blend_state *blend,
José Fonseca2529ed52009-08-09 12:39:38 +0100154 enum vector_mode mode,
José Fonsecab4835ea2009-09-14 11:05:06 +0100155 struct lp_type type)
José Fonseca7d043162009-08-01 17:59:19 +0100156{
José Fonsecab94e22e2009-08-03 19:35:28 +0100157 LLVMTypeRef ret_type;
José Fonsecaede73252009-08-03 00:01:27 +0100158 LLVMTypeRef vec_type;
José Fonseca7d043162009-08-01 17:59:19 +0100159 LLVMTypeRef args[4];
160 LLVMValueRef func;
161 LLVMValueRef src_ptr;
162 LLVMValueRef dst_ptr;
163 LLVMValueRef const_ptr;
164 LLVMValueRef res_ptr;
165 LLVMBasicBlockRef block;
166 LLVMBuilderRef builder;
José Fonseca7d043162009-08-01 17:59:19 +0100167
José Fonsecab94e22e2009-08-03 19:35:28 +0100168 ret_type = LLVMInt64Type();
José Fonsecaede73252009-08-03 00:01:27 +0100169 vec_type = lp_build_vec_type(type);
José Fonseca272dadb2009-08-02 13:52:40 +0100170
José Fonsecaede73252009-08-03 00:01:27 +0100171 args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0);
José Fonseca5940ba22009-08-04 02:10:35 +0100172 func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidType(), args, 4, 0));
José Fonseca7d043162009-08-01 17:59:19 +0100173 LLVMSetFunctionCallConv(func, LLVMCCallConv);
174 src_ptr = LLVMGetParam(func, 0);
175 dst_ptr = LLVMGetParam(func, 1);
176 const_ptr = LLVMGetParam(func, 2);
177 res_ptr = LLVMGetParam(func, 3);
178
179 block = LLVMAppendBasicBlock(func, "entry");
180 builder = LLVMCreateBuilder();
181 LLVMPositionBuilderAtEnd(builder, block);
182
José Fonseca2529ed52009-08-09 12:39:38 +0100183 if (mode == AoS) {
184 LLVMValueRef src;
185 LLVMValueRef dst;
186 LLVMValueRef con;
187 LLVMValueRef res;
José Fonseca7d043162009-08-01 17:59:19 +0100188
José Fonseca2529ed52009-08-09 12:39:38 +0100189 src = LLVMBuildLoad(builder, src_ptr, "src");
190 dst = LLVMBuildLoad(builder, dst_ptr, "dst");
191 con = LLVMBuildLoad(builder, const_ptr, "const");
José Fonseca7d043162009-08-01 17:59:19 +0100192
José Fonseca2529ed52009-08-09 12:39:38 +0100193 res = lp_build_blend_aos(builder, blend, type, src, dst, con, 3);
José Fonseca7d043162009-08-01 17:59:19 +0100194
José Fonseca5999ebf2009-08-18 20:23:35 +0100195 lp_build_name(res, "res");
José Fonseca2529ed52009-08-09 12:39:38 +0100196
197 LLVMBuildStore(builder, res, res_ptr);
198 }
199
200 if (mode == SoA) {
201 LLVMValueRef src[4];
202 LLVMValueRef dst[4];
203 LLVMValueRef con[4];
204 LLVMValueRef res[4];
José Fonseca2529ed52009-08-09 12:39:38 +0100205 unsigned i;
206
207 for(i = 0; i < 4; ++i) {
208 LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
José Fonseca5999ebf2009-08-18 20:23:35 +0100209 src[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, src_ptr, &index, 1, ""), "");
210 dst[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dst_ptr, &index, 1, ""), "");
211 con[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
212 lp_build_name(src[i], "src.%c", "rgba"[i]);
213 lp_build_name(con[i], "con.%c", "rgba"[i]);
214 lp_build_name(dst[i], "dst.%c", "rgba"[i]);
José Fonseca2529ed52009-08-09 12:39:38 +0100215 }
216
217 lp_build_blend_soa(builder, blend, type, src, dst, con, res);
218
219 for(i = 0; i < 4; ++i) {
220 LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
José Fonseca5999ebf2009-08-18 20:23:35 +0100221 lp_build_name(res[i], "res.%c", "rgba"[i]);
José Fonseca2529ed52009-08-09 12:39:38 +0100222 LLVMBuildStore(builder, res[i], LLVMBuildGEP(builder, res_ptr, &index, 1, ""));
223 }
224 }
José Fonseca7d043162009-08-01 17:59:19 +0100225
José Fonseca5940ba22009-08-04 02:10:35 +0100226 LLVMBuildRetVoid(builder);;
José Fonseca7d043162009-08-01 17:59:19 +0100227
228 LLVMDisposeBuilder(builder);
229 return func;
230}
231
232
José Fonseca7d043162009-08-01 17:59:19 +0100233/** Add and limit result to ceiling of 1.0 */
234#define ADD_SAT(R, A, B) \
235do { \
236 R = (A) + (B); if (R > 1.0f) R = 1.0f; \
237} while (0)
238
239/** Subtract and limit result to floor of 0.0 */
240#define SUB_SAT(R, A, B) \
241do { \
242 R = (A) - (B); if (R < 0.0f) R = 0.0f; \
243} while (0)
244
245
246static void
247compute_blend_ref_term(unsigned rgb_factor,
248 unsigned alpha_factor,
José Fonsecae6ebebc2009-08-07 01:20:01 +0100249 const double *factor,
250 const double *src,
251 const double *dst,
252 const double *con,
253 double *term)
José Fonseca7d043162009-08-01 17:59:19 +0100254{
José Fonsecae6ebebc2009-08-07 01:20:01 +0100255 double temp;
José Fonseca7d043162009-08-01 17:59:19 +0100256
257 switch (rgb_factor) {
258 case PIPE_BLENDFACTOR_ONE:
259 term[0] = factor[0]; /* R */
260 term[1] = factor[1]; /* G */
261 term[2] = factor[2]; /* B */
262 break;
263 case PIPE_BLENDFACTOR_SRC_COLOR:
264 term[0] = factor[0] * src[0]; /* R */
265 term[1] = factor[1] * src[1]; /* G */
266 term[2] = factor[2] * src[2]; /* B */
267 break;
268 case PIPE_BLENDFACTOR_SRC_ALPHA:
269 term[0] = factor[0] * src[3]; /* R */
270 term[1] = factor[1] * src[3]; /* G */
271 term[2] = factor[2] * src[3]; /* B */
272 break;
273 case PIPE_BLENDFACTOR_DST_COLOR:
274 term[0] = factor[0] * dst[0]; /* R */
275 term[1] = factor[1] * dst[1]; /* G */
276 term[2] = factor[2] * dst[2]; /* B */
277 break;
278 case PIPE_BLENDFACTOR_DST_ALPHA:
279 term[0] = factor[0] * dst[3]; /* R */
280 term[1] = factor[1] * dst[3]; /* G */
281 term[2] = factor[2] * dst[3]; /* B */
282 break;
283 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
284 temp = MIN2(src[3], 1.0f - dst[3]);
285 term[0] = factor[0] * temp; /* R */
286 term[1] = factor[1] * temp; /* G */
287 term[2] = factor[2] * temp; /* B */
288 break;
289 case PIPE_BLENDFACTOR_CONST_COLOR:
José Fonsecaede73252009-08-03 00:01:27 +0100290 term[0] = factor[0] * con[0]; /* R */
291 term[1] = factor[1] * con[1]; /* G */
292 term[2] = factor[2] * con[2]; /* B */
José Fonseca7d043162009-08-01 17:59:19 +0100293 break;
294 case PIPE_BLENDFACTOR_CONST_ALPHA:
José Fonsecaede73252009-08-03 00:01:27 +0100295 term[0] = factor[0] * con[3]; /* R */
296 term[1] = factor[1] * con[3]; /* G */
297 term[2] = factor[2] * con[3]; /* B */
José Fonseca7d043162009-08-01 17:59:19 +0100298 break;
299 case PIPE_BLENDFACTOR_SRC1_COLOR:
300 assert(0); /* to do */
301 break;
302 case PIPE_BLENDFACTOR_SRC1_ALPHA:
303 assert(0); /* to do */
304 break;
305 case PIPE_BLENDFACTOR_ZERO:
306 term[0] = 0.0f; /* R */
307 term[1] = 0.0f; /* G */
308 term[2] = 0.0f; /* B */
309 break;
310 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
311 term[0] = factor[0] * (1.0f - src[0]); /* R */
312 term[1] = factor[1] * (1.0f - src[1]); /* G */
313 term[2] = factor[2] * (1.0f - src[2]); /* B */
314 break;
315 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
316 term[0] = factor[0] * (1.0f - src[3]); /* R */
317 term[1] = factor[1] * (1.0f - src[3]); /* G */
318 term[2] = factor[2] * (1.0f - src[3]); /* B */
319 break;
320 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
321 term[0] = factor[0] * (1.0f - dst[3]); /* R */
322 term[1] = factor[1] * (1.0f - dst[3]); /* G */
323 term[2] = factor[2] * (1.0f - dst[3]); /* B */
324 break;
325 case PIPE_BLENDFACTOR_INV_DST_COLOR:
326 term[0] = factor[0] * (1.0f - dst[0]); /* R */
327 term[1] = factor[1] * (1.0f - dst[1]); /* G */
328 term[2] = factor[2] * (1.0f - dst[2]); /* B */
329 break;
330 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
José Fonsecaede73252009-08-03 00:01:27 +0100331 term[0] = factor[0] * (1.0f - con[0]); /* R */
332 term[1] = factor[1] * (1.0f - con[1]); /* G */
333 term[2] = factor[2] * (1.0f - con[2]); /* B */
José Fonseca7d043162009-08-01 17:59:19 +0100334 break;
335 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
José Fonsecaede73252009-08-03 00:01:27 +0100336 term[0] = factor[0] * (1.0f - con[3]); /* R */
337 term[1] = factor[1] * (1.0f - con[3]); /* G */
338 term[2] = factor[2] * (1.0f - con[3]); /* B */
José Fonseca7d043162009-08-01 17:59:19 +0100339 break;
340 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
341 assert(0); /* to do */
342 break;
343 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
344 assert(0); /* to do */
345 break;
346 default:
347 assert(0);
348 }
349
350 /*
351 * Compute src/first term A
352 */
353 switch (alpha_factor) {
354 case PIPE_BLENDFACTOR_ONE:
355 term[3] = factor[3]; /* A */
356 break;
357 case PIPE_BLENDFACTOR_SRC_COLOR:
358 case PIPE_BLENDFACTOR_SRC_ALPHA:
359 term[3] = factor[3] * src[3]; /* A */
360 break;
361 case PIPE_BLENDFACTOR_DST_COLOR:
362 case PIPE_BLENDFACTOR_DST_ALPHA:
363 term[3] = factor[3] * dst[3]; /* A */
364 break;
365 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
366 term[3] = src[3]; /* A */
367 break;
368 case PIPE_BLENDFACTOR_CONST_COLOR:
369 case PIPE_BLENDFACTOR_CONST_ALPHA:
José Fonsecaede73252009-08-03 00:01:27 +0100370 term[3] = factor[3] * con[3]; /* A */
José Fonseca7d043162009-08-01 17:59:19 +0100371 break;
372 case PIPE_BLENDFACTOR_ZERO:
373 term[3] = 0.0f; /* A */
374 break;
375 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
376 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
377 term[3] = factor[3] * (1.0f - src[3]); /* A */
378 break;
379 case PIPE_BLENDFACTOR_INV_DST_COLOR:
380 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
381 term[3] = factor[3] * (1.0f - dst[3]); /* A */
382 break;
383 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
384 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
José Fonsecaede73252009-08-03 00:01:27 +0100385 term[3] = factor[3] * (1.0f - con[3]);
José Fonseca7d043162009-08-01 17:59:19 +0100386 break;
387 default:
388 assert(0);
389 }
390}
391
392
393static void
394compute_blend_ref(const struct pipe_blend_state *blend,
José Fonsecae6ebebc2009-08-07 01:20:01 +0100395 const double *src,
396 const double *dst,
397 const double *con,
398 double *res)
José Fonseca7d043162009-08-01 17:59:19 +0100399{
José Fonsecae6ebebc2009-08-07 01:20:01 +0100400 double src_term[4];
401 double dst_term[4];
José Fonseca7d043162009-08-01 17:59:19 +0100402
Roland Scheidegger99e28d42010-01-25 16:35:56 +0100403 compute_blend_ref_term(blend->rt[0].rgb_src_factor, blend->rt[0].alpha_src_factor,
404 src, src, dst, con, src_term);
405 compute_blend_ref_term(blend->rt[0].rgb_dst_factor, blend->rt[0].alpha_dst_factor,
406 dst, src, dst, con, dst_term);
José Fonseca7d043162009-08-01 17:59:19 +0100407
408 /*
409 * Combine RGB terms
410 */
Roland Scheidegger99e28d42010-01-25 16:35:56 +0100411 switch (blend->rt[0].rgb_func) {
José Fonseca7d043162009-08-01 17:59:19 +0100412 case PIPE_BLEND_ADD:
413 ADD_SAT(res[0], src_term[0], dst_term[0]); /* R */
414 ADD_SAT(res[1], src_term[1], dst_term[1]); /* G */
415 ADD_SAT(res[2], src_term[2], dst_term[2]); /* B */
416 break;
417 case PIPE_BLEND_SUBTRACT:
418 SUB_SAT(res[0], src_term[0], dst_term[0]); /* R */
419 SUB_SAT(res[1], src_term[1], dst_term[1]); /* G */
420 SUB_SAT(res[2], src_term[2], dst_term[2]); /* B */
421 break;
422 case PIPE_BLEND_REVERSE_SUBTRACT:
423 SUB_SAT(res[0], dst_term[0], src_term[0]); /* R */
424 SUB_SAT(res[1], dst_term[1], src_term[1]); /* G */
425 SUB_SAT(res[2], dst_term[2], src_term[2]); /* B */
426 break;
427 case PIPE_BLEND_MIN:
428 res[0] = MIN2(src_term[0], dst_term[0]); /* R */
429 res[1] = MIN2(src_term[1], dst_term[1]); /* G */
430 res[2] = MIN2(src_term[2], dst_term[2]); /* B */
431 break;
432 case PIPE_BLEND_MAX:
433 res[0] = MAX2(src_term[0], dst_term[0]); /* R */
434 res[1] = MAX2(src_term[1], dst_term[1]); /* G */
435 res[2] = MAX2(src_term[2], dst_term[2]); /* B */
436 break;
437 default:
438 assert(0);
439 }
440
441 /*
442 * Combine A terms
443 */
Roland Scheidegger99e28d42010-01-25 16:35:56 +0100444 switch (blend->rt[0].alpha_func) {
José Fonseca7d043162009-08-01 17:59:19 +0100445 case PIPE_BLEND_ADD:
446 ADD_SAT(res[3], src_term[3], dst_term[3]); /* A */
447 break;
448 case PIPE_BLEND_SUBTRACT:
449 SUB_SAT(res[3], src_term[3], dst_term[3]); /* A */
450 break;
451 case PIPE_BLEND_REVERSE_SUBTRACT:
452 SUB_SAT(res[3], dst_term[3], src_term[3]); /* A */
453 break;
454 case PIPE_BLEND_MIN:
455 res[3] = MIN2(src_term[3], dst_term[3]); /* A */
456 break;
457 case PIPE_BLEND_MAX:
458 res[3] = MAX2(src_term[3], dst_term[3]); /* A */
459 break;
460 default:
461 assert(0);
462 }
463}
464
465
José Fonseca26c78a42010-01-12 12:15:24 +0000466PIPE_ALIGN_STACK
José Fonseca7d043162009-08-01 17:59:19 +0100467static boolean
José Fonsecae6ebebc2009-08-07 01:20:01 +0100468test_one(unsigned verbose,
469 FILE *fp,
José Fonsecaa77084e2009-08-04 11:52:54 +0100470 const struct pipe_blend_state *blend,
José Fonseca2529ed52009-08-09 12:39:38 +0100471 enum vector_mode mode,
José Fonsecab4835ea2009-09-14 11:05:06 +0100472 struct lp_type type)
José Fonseca7d043162009-08-01 17:59:19 +0100473{
474 LLVMModuleRef module = NULL;
475 LLVMValueRef func = NULL;
476 LLVMExecutionEngineRef engine = NULL;
477 LLVMModuleProviderRef provider = NULL;
478 LLVMPassManagerRef pass = NULL;
479 char *error = NULL;
480 blend_test_ptr_t blend_test_ptr;
481 boolean success;
José Fonseca9aafa1f2009-10-22 19:02:04 +0100482 const unsigned n = LP_TEST_NUM_SAMPLES;
483 int64_t cycles[LP_TEST_NUM_SAMPLES];
José Fonsecaa77084e2009-08-04 11:52:54 +0100484 double cycles_avg = 0.0;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100485 unsigned i, j;
José Fonseca7d043162009-08-01 17:59:19 +0100486
José Fonsecaa77084e2009-08-04 11:52:54 +0100487 if(verbose >= 1)
José Fonseca2529ed52009-08-09 12:39:38 +0100488 dump_blend_type(stdout, blend, mode, type);
José Fonsecaa77084e2009-08-04 11:52:54 +0100489
José Fonseca7d043162009-08-01 17:59:19 +0100490 module = LLVMModuleCreateWithName("test");
491
José Fonseca2529ed52009-08-09 12:39:38 +0100492 func = add_blend_test(module, blend, mode, type);
José Fonseca7d043162009-08-01 17:59:19 +0100493
494 if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
495 LLVMDumpModule(module);
José Fonseca7d043162009-08-01 17:59:19 +0100496 abort();
497 }
José Fonseca7ace0b12009-08-01 18:35:04 +0100498 LLVMDisposeMessage(error);
José Fonseca7d043162009-08-01 17:59:19 +0100499
500 provider = LLVMCreateModuleProviderForExistingModule(module);
501 if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
José Fonseca3130b992009-08-08 23:15:05 +0100502 if(verbose < 1)
José Fonseca2529ed52009-08-09 12:39:38 +0100503 dump_blend_type(stderr, blend, mode, type);
José Fonseca7d043162009-08-01 17:59:19 +0100504 fprintf(stderr, "%s\n", error);
505 LLVMDisposeMessage(error);
506 abort();
507 }
508
509#if 0
510 pass = LLVMCreatePassManager();
511 LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
512 /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
513 * but there are more on SVN. */
514 LLVMAddConstantPropagationPass(pass);
515 LLVMAddInstructionCombiningPass(pass);
516 LLVMAddPromoteMemoryToRegisterPass(pass);
517 LLVMAddGVNPass(pass);
518 LLVMAddCFGSimplificationPass(pass);
519 LLVMRunPassManager(pass, module);
520#else
521 (void)pass;
522#endif
523
José Fonseca7d043162009-08-01 17:59:19 +0100524 if(verbose >= 2)
525 LLVMDumpModule(module);
526
José Fonsecab19cb002009-08-07 09:51:04 +0100527 blend_test_ptr = (blend_test_ptr_t)LLVMGetPointerToGlobal(engine, func);
528
José Fonseca818d4442009-08-16 11:50:17 +0100529 if(verbose >= 2)
530 lp_disassemble(blend_test_ptr);
531
José Fonseca7d043162009-08-01 17:59:19 +0100532 success = TRUE;
José Fonsecab94e22e2009-08-03 19:35:28 +0100533 for(i = 0; i < n && success; ++i) {
José Fonseca2529ed52009-08-09 12:39:38 +0100534 if(mode == AoS) {
José Fonseca5dfd5ed2010-01-12 11:47:37 +0000535 PIPE_ALIGN_VAR(16) uint8_t src[LP_NATIVE_VECTOR_WIDTH/8];
536 PIPE_ALIGN_VAR(16) uint8_t dst[LP_NATIVE_VECTOR_WIDTH/8];
537 PIPE_ALIGN_VAR(16) uint8_t con[LP_NATIVE_VECTOR_WIDTH/8];
538 PIPE_ALIGN_VAR(16) uint8_t res[LP_NATIVE_VECTOR_WIDTH/8];
539 PIPE_ALIGN_VAR(16) uint8_t ref[LP_NATIVE_VECTOR_WIDTH/8];
José Fonseca2529ed52009-08-09 12:39:38 +0100540 int64_t start_counter = 0;
541 int64_t end_counter = 0;
José Fonseca5940ba22009-08-04 02:10:35 +0100542
José Fonseca2529ed52009-08-09 12:39:38 +0100543 random_vec(type, src);
544 random_vec(type, dst);
545 random_vec(type, con);
José Fonseca7d043162009-08-01 17:59:19 +0100546
José Fonseca2529ed52009-08-09 12:39:38 +0100547 {
548 double fsrc[LP_MAX_VECTOR_LENGTH];
549 double fdst[LP_MAX_VECTOR_LENGTH];
550 double fcon[LP_MAX_VECTOR_LENGTH];
551 double fref[LP_MAX_VECTOR_LENGTH];
José Fonsecae6ebebc2009-08-07 01:20:01 +0100552
José Fonseca2529ed52009-08-09 12:39:38 +0100553 read_vec(type, src, fsrc);
554 read_vec(type, dst, fdst);
555 read_vec(type, con, fcon);
José Fonseca7d043162009-08-01 17:59:19 +0100556
José Fonseca2529ed52009-08-09 12:39:38 +0100557 for(j = 0; j < type.length; j += 4)
558 compute_blend_ref(blend, fsrc + j, fdst + j, fcon + j, fref + j);
José Fonsecab19cb002009-08-07 09:51:04 +0100559
José Fonseca2529ed52009-08-09 12:39:38 +0100560 write_vec(type, ref, fref);
561 }
562
563 start_counter = rdtsc();
564 blend_test_ptr(src, dst, con, res);
565 end_counter = rdtsc();
566
567 cycles[i] = end_counter - start_counter;
568
569 if(!compare_vec(type, res, ref)) {
570 success = FALSE;
571
572 if(verbose < 1)
573 dump_blend_type(stderr, blend, mode, type);
574 fprintf(stderr, "MISMATCH\n");
575
576 fprintf(stderr, " Src: ");
577 dump_vec(stderr, type, src);
578 fprintf(stderr, "\n");
579
580 fprintf(stderr, " Dst: ");
581 dump_vec(stderr, type, dst);
582 fprintf(stderr, "\n");
583
584 fprintf(stderr, " Con: ");
585 dump_vec(stderr, type, con);
586 fprintf(stderr, "\n");
587
588 fprintf(stderr, " Res: ");
589 dump_vec(stderr, type, res);
590 fprintf(stderr, "\n");
591
592 fprintf(stderr, " Ref: ");
593 dump_vec(stderr, type, ref);
594 fprintf(stderr, "\n");
595 }
José Fonsecaede73252009-08-03 00:01:27 +0100596 }
José Fonsecaede73252009-08-03 00:01:27 +0100597
José Fonseca2529ed52009-08-09 12:39:38 +0100598 if(mode == SoA) {
599 const unsigned stride = type.length*type.width/8;
José Fonseca5dfd5ed2010-01-12 11:47:37 +0000600 PIPE_ALIGN_VAR(16) uint8_t src[4*LP_NATIVE_VECTOR_WIDTH/8];
601 PIPE_ALIGN_VAR(16) uint8_t dst[4*LP_NATIVE_VECTOR_WIDTH/8];
602 PIPE_ALIGN_VAR(16) uint8_t con[4*LP_NATIVE_VECTOR_WIDTH/8];
603 PIPE_ALIGN_VAR(16) uint8_t res[4*LP_NATIVE_VECTOR_WIDTH/8];
604 PIPE_ALIGN_VAR(16) uint8_t ref[4*LP_NATIVE_VECTOR_WIDTH/8];
José Fonseca2529ed52009-08-09 12:39:38 +0100605 int64_t start_counter = 0;
606 int64_t end_counter = 0;
607 boolean mismatch;
José Fonseca5940ba22009-08-04 02:10:35 +0100608
José Fonseca2529ed52009-08-09 12:39:38 +0100609 for(j = 0; j < 4; ++j) {
610 random_vec(type, src + j*stride);
611 random_vec(type, dst + j*stride);
612 random_vec(type, con + j*stride);
613 }
José Fonsecae6ebebc2009-08-07 01:20:01 +0100614
José Fonseca2529ed52009-08-09 12:39:38 +0100615 {
616 double fsrc[4];
617 double fdst[4];
618 double fcon[4];
619 double fref[4];
620 unsigned k;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100621
José Fonseca2529ed52009-08-09 12:39:38 +0100622 for(k = 0; k < type.length; ++k) {
623 for(j = 0; j < 4; ++j) {
624 fsrc[j] = read_elem(type, src + j*stride, k);
625 fdst[j] = read_elem(type, dst + j*stride, k);
626 fcon[j] = read_elem(type, con + j*stride, k);
627 }
José Fonsecae6ebebc2009-08-07 01:20:01 +0100628
José Fonseca2529ed52009-08-09 12:39:38 +0100629 compute_blend_ref(blend, fsrc, fdst, fcon, fref);
José Fonsecae6ebebc2009-08-07 01:20:01 +0100630
José Fonseca2529ed52009-08-09 12:39:38 +0100631 for(j = 0; j < 4; ++j)
632 write_elem(type, ref + j*stride, k, fref[j]);
633 }
634 }
José Fonsecae6ebebc2009-08-07 01:20:01 +0100635
José Fonseca2529ed52009-08-09 12:39:38 +0100636 start_counter = rdtsc();
637 blend_test_ptr(src, dst, con, res);
638 end_counter = rdtsc();
José Fonsecae6ebebc2009-08-07 01:20:01 +0100639
José Fonseca2529ed52009-08-09 12:39:38 +0100640 cycles[i] = end_counter - start_counter;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100641
José Fonseca2529ed52009-08-09 12:39:38 +0100642 mismatch = FALSE;
643 for (j = 0; j < 4; ++j)
644 if(!compare_vec(type, res + j*stride, ref + j*stride))
645 mismatch = TRUE;
646
647 if (mismatch) {
648 success = FALSE;
649
650 if(verbose < 1)
651 dump_blend_type(stderr, blend, mode, type);
652 fprintf(stderr, "MISMATCH\n");
653 for(j = 0; j < 4; ++j) {
654 char channel = "RGBA"[j];
655 fprintf(stderr, " Src%c: ", channel);
656 dump_vec(stderr, type, src + j*stride);
657 fprintf(stderr, "\n");
658
659 fprintf(stderr, " Dst%c: ", channel);
660 dump_vec(stderr, type, dst + j*stride);
661 fprintf(stderr, "\n");
662
663 fprintf(stderr, " Con%c: ", channel);
664 dump_vec(stderr, type, con + j*stride);
665 fprintf(stderr, "\n");
666
667 fprintf(stderr, " Res%c: ", channel);
668 dump_vec(stderr, type, res + j*stride);
669 fprintf(stderr, "\n");
670
671 fprintf(stderr, " Ref%c: ", channel);
672 dump_vec(stderr, type, ref + j*stride);
673 fprintf(stderr, "\n");
674 }
675 }
José Fonsecae6ebebc2009-08-07 01:20:01 +0100676 }
José Fonsecab94e22e2009-08-03 19:35:28 +0100677 }
José Fonseca7d043162009-08-01 17:59:19 +0100678
José Fonsecab94e22e2009-08-03 19:35:28 +0100679 /*
680 * Unfortunately the output of cycle counter is not very reliable as it comes
681 * -- sometimes we get outliers (due IRQs perhaps?) which are
682 * better removed to avoid random or biased data.
683 */
José Fonsecaa77084e2009-08-04 11:52:54 +0100684 {
José Fonsecab94e22e2009-08-03 19:35:28 +0100685 double sum = 0.0, sum2 = 0.0;
686 double avg, std;
687 unsigned m;
688
689 for(i = 0; i < n; ++i) {
690 sum += cycles[i];
691 sum2 += cycles[i]*cycles[i];
José Fonseca7d043162009-08-01 17:59:19 +0100692 }
José Fonsecab94e22e2009-08-03 19:35:28 +0100693
694 avg = sum/n;
695 std = sqrtf((sum2 - n*avg*avg)/n);
696
697 m = 0;
698 sum = 0.0;
699 for(i = 0; i < n; ++i) {
700 if(fabs(cycles[i] - avg) <= 4.0*std) {
701 sum += cycles[i];
702 ++m;
703 }
704 }
705
José Fonsecaa77084e2009-08-04 11:52:54 +0100706 cycles_avg = sum/m;
José Fonsecab94e22e2009-08-03 19:35:28 +0100707
José Fonsecaa77084e2009-08-04 11:52:54 +0100708 }
709
José Fonsecaa77084e2009-08-04 11:52:54 +0100710 if(fp)
José Fonseca2529ed52009-08-09 12:39:38 +0100711 write_tsv_row(fp, blend, mode, type, cycles_avg, success);
José Fonsecaa77084e2009-08-04 11:52:54 +0100712
José Fonsecab94e22e2009-08-03 19:35:28 +0100713 if (!success) {
José Fonseca3130b992009-08-08 23:15:05 +0100714 if(verbose < 2)
715 LLVMDumpModule(module);
José Fonsecab94e22e2009-08-03 19:35:28 +0100716 LLVMWriteBitcodeToFile(module, "blend.bc");
717 fprintf(stderr, "blend.bc written\n");
José Fonseca3130b992009-08-08 23:15:05 +0100718 fprintf(stderr, "Invoke as \"llc -o - blend.bc\"\n");
José Fonsecab94e22e2009-08-03 19:35:28 +0100719 abort();
José Fonseca7d043162009-08-01 17:59:19 +0100720 }
721
José Fonseca7ace0b12009-08-01 18:35:04 +0100722 LLVMFreeMachineCodeForFunction(engine, func);
723
José Fonseca7d043162009-08-01 17:59:19 +0100724 LLVMDisposeExecutionEngine(engine);
José Fonseca7ace0b12009-08-01 18:35:04 +0100725 if(pass)
726 LLVMDisposePassManager(pass);
José Fonseca7d043162009-08-01 17:59:19 +0100727
728 return success;
729}
730
731
José Fonsecaa77084e2009-08-04 11:52:54 +0100732const unsigned
José Fonseca7d043162009-08-01 17:59:19 +0100733blend_factors[] = {
José Fonsecaa77084e2009-08-04 11:52:54 +0100734 PIPE_BLENDFACTOR_ZERO,
735 PIPE_BLENDFACTOR_ONE,
736 PIPE_BLENDFACTOR_SRC_COLOR,
737 PIPE_BLENDFACTOR_SRC_ALPHA,
738 PIPE_BLENDFACTOR_DST_COLOR,
739 PIPE_BLENDFACTOR_DST_ALPHA,
740 PIPE_BLENDFACTOR_CONST_COLOR,
741 PIPE_BLENDFACTOR_CONST_ALPHA,
José Fonseca7d043162009-08-01 17:59:19 +0100742#if 0
José Fonsecaa77084e2009-08-04 11:52:54 +0100743 PIPE_BLENDFACTOR_SRC1_COLOR,
744 PIPE_BLENDFACTOR_SRC1_ALPHA,
José Fonseca7d043162009-08-01 17:59:19 +0100745#endif
José Fonsecaa77084e2009-08-04 11:52:54 +0100746 PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE,
747 PIPE_BLENDFACTOR_INV_SRC_COLOR,
748 PIPE_BLENDFACTOR_INV_SRC_ALPHA,
749 PIPE_BLENDFACTOR_INV_DST_COLOR,
750 PIPE_BLENDFACTOR_INV_DST_ALPHA,
751 PIPE_BLENDFACTOR_INV_CONST_COLOR,
752 PIPE_BLENDFACTOR_INV_CONST_ALPHA,
José Fonseca7d043162009-08-01 17:59:19 +0100753#if 0
José Fonsecaa77084e2009-08-04 11:52:54 +0100754 PIPE_BLENDFACTOR_INV_SRC1_COLOR,
755 PIPE_BLENDFACTOR_INV_SRC1_ALPHA,
José Fonseca7d043162009-08-01 17:59:19 +0100756#endif
757};
758
759
José Fonsecaa77084e2009-08-04 11:52:54 +0100760const unsigned
José Fonseca7d043162009-08-01 17:59:19 +0100761blend_funcs[] = {
José Fonsecaa77084e2009-08-04 11:52:54 +0100762 PIPE_BLEND_ADD,
763 PIPE_BLEND_SUBTRACT,
764 PIPE_BLEND_REVERSE_SUBTRACT,
765 PIPE_BLEND_MIN,
766 PIPE_BLEND_MAX
José Fonseca7d043162009-08-01 17:59:19 +0100767};
768
769
José Fonsecab4835ea2009-09-14 11:05:06 +0100770const struct lp_type blend_types[] = {
José Fonsecaede73252009-08-03 00:01:27 +0100771 /* float, fixed, sign, norm, width, len */
José Fonsecab4835ea2009-09-14 11:05:06 +0100772 { TRUE, FALSE, FALSE, TRUE, 32, 4 }, /* f32 x 4 */
773 { FALSE, FALSE, FALSE, TRUE, 8, 16 }, /* u8n x 16 */
José Fonsecaede73252009-08-03 00:01:27 +0100774};
775
776
José Fonseca7d043162009-08-01 17:59:19 +0100777const unsigned num_funcs = sizeof(blend_funcs)/sizeof(blend_funcs[0]);
778const unsigned num_factors = sizeof(blend_factors)/sizeof(blend_factors[0]);
José Fonsecaede73252009-08-03 00:01:27 +0100779const unsigned num_types = sizeof(blend_types)/sizeof(blend_types[0]);
José Fonseca7d043162009-08-01 17:59:19 +0100780
781
José Fonsecae6ebebc2009-08-07 01:20:01 +0100782boolean
783test_all(unsigned verbose, FILE *fp)
José Fonseca7d043162009-08-01 17:59:19 +0100784{
José Fonsecaa77084e2009-08-04 11:52:54 +0100785 const unsigned *rgb_func;
786 const unsigned *rgb_src_factor;
787 const unsigned *rgb_dst_factor;
788 const unsigned *alpha_func;
789 const unsigned *alpha_src_factor;
790 const unsigned *alpha_dst_factor;
José Fonseca7d043162009-08-01 17:59:19 +0100791 struct pipe_blend_state blend;
José Fonseca2529ed52009-08-09 12:39:38 +0100792 enum vector_mode mode;
José Fonsecab4835ea2009-09-14 11:05:06 +0100793 const struct lp_type *type;
José Fonseca7d043162009-08-01 17:59:19 +0100794 bool success = TRUE;
795
796 for(rgb_func = blend_funcs; rgb_func < &blend_funcs[num_funcs]; ++rgb_func) {
797 for(alpha_func = blend_funcs; alpha_func < &blend_funcs[num_funcs]; ++alpha_func) {
798 for(rgb_src_factor = blend_factors; rgb_src_factor < &blend_factors[num_factors]; ++rgb_src_factor) {
799 for(rgb_dst_factor = blend_factors; rgb_dst_factor <= rgb_src_factor; ++rgb_dst_factor) {
800 for(alpha_src_factor = blend_factors; alpha_src_factor < &blend_factors[num_factors]; ++alpha_src_factor) {
801 for(alpha_dst_factor = blend_factors; alpha_dst_factor <= alpha_src_factor; ++alpha_dst_factor) {
José Fonseca2529ed52009-08-09 12:39:38 +0100802 for(mode = 0; mode < 2; ++mode) {
803 for(type = blend_types; type < &blend_types[num_types]; ++type) {
José Fonseca7d043162009-08-01 17:59:19 +0100804
José Fonseca2529ed52009-08-09 12:39:38 +0100805 if(*rgb_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
806 *alpha_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE)
807 continue;
José Fonseca7d043162009-08-01 17:59:19 +0100808
José Fonseca2529ed52009-08-09 12:39:38 +0100809 memset(&blend, 0, sizeof blend);
Roland Scheidegger99e28d42010-01-25 16:35:56 +0100810 blend.rt[0].blend_enable = 1;
811 blend.rt[0].rgb_func = *rgb_func;
812 blend.rt[0].rgb_src_factor = *rgb_src_factor;
813 blend.rt[0].rgb_dst_factor = *rgb_dst_factor;
814 blend.rt[0].alpha_func = *alpha_func;
815 blend.rt[0].alpha_src_factor = *alpha_src_factor;
816 blend.rt[0].alpha_dst_factor = *alpha_dst_factor;
817 blend.rt[0].colormask = PIPE_MASK_RGBA;
José Fonseca7d043162009-08-01 17:59:19 +0100818
José Fonseca2529ed52009-08-09 12:39:38 +0100819 if(!test_one(verbose, fp, &blend, mode, *type))
820 success = FALSE;
José Fonseca7d043162009-08-01 17:59:19 +0100821
José Fonseca2529ed52009-08-09 12:39:38 +0100822 }
José Fonsecaede73252009-08-03 00:01:27 +0100823 }
José Fonseca7d043162009-08-01 17:59:19 +0100824 }
825 }
826 }
827 }
828 }
829 }
830
831 return success;
832}
833
834
José Fonsecae6ebebc2009-08-07 01:20:01 +0100835boolean
836test_some(unsigned verbose, FILE *fp, unsigned long n)
José Fonseca7d043162009-08-01 17:59:19 +0100837{
José Fonsecaa77084e2009-08-04 11:52:54 +0100838 const unsigned *rgb_func;
839 const unsigned *rgb_src_factor;
840 const unsigned *rgb_dst_factor;
841 const unsigned *alpha_func;
842 const unsigned *alpha_src_factor;
843 const unsigned *alpha_dst_factor;
José Fonseca7d043162009-08-01 17:59:19 +0100844 struct pipe_blend_state blend;
José Fonseca2529ed52009-08-09 12:39:38 +0100845 enum vector_mode mode;
José Fonsecab4835ea2009-09-14 11:05:06 +0100846 const struct lp_type *type;
José Fonseca7d043162009-08-01 17:59:19 +0100847 unsigned long i;
848 bool success = TRUE;
849
850 for(i = 0; i < n; ++i) {
José Fonseca459ea002009-09-16 10:39:06 +0100851 rgb_func = &blend_funcs[rand() % num_funcs];
852 alpha_func = &blend_funcs[rand() % num_funcs];
853 rgb_src_factor = &blend_factors[rand() % num_factors];
854 alpha_src_factor = &blend_factors[rand() % num_factors];
José Fonseca7d043162009-08-01 17:59:19 +0100855
856 do {
José Fonseca459ea002009-09-16 10:39:06 +0100857 rgb_dst_factor = &blend_factors[rand() % num_factors];
José Fonsecaa77084e2009-08-04 11:52:54 +0100858 } while(*rgb_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
José Fonseca7d043162009-08-01 17:59:19 +0100859
860 do {
José Fonseca459ea002009-09-16 10:39:06 +0100861 alpha_dst_factor = &blend_factors[rand() % num_factors];
José Fonsecaa77084e2009-08-04 11:52:54 +0100862 } while(*alpha_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
José Fonseca7d043162009-08-01 17:59:19 +0100863
José Fonseca459ea002009-09-16 10:39:06 +0100864 mode = rand() & 1;
José Fonseca7d043162009-08-01 17:59:19 +0100865
José Fonseca459ea002009-09-16 10:39:06 +0100866 type = &blend_types[rand() % num_types];
José Fonseca7d043162009-08-01 17:59:19 +0100867
José Fonseca2529ed52009-08-09 12:39:38 +0100868 memset(&blend, 0, sizeof blend);
Roland Scheidegger99e28d42010-01-25 16:35:56 +0100869 blend.rt[0].blend_enable = 1;
870 blend.rt[0].rgb_func = *rgb_func;
871 blend.rt[0].rgb_src_factor = *rgb_src_factor;
872 blend.rt[0].rgb_dst_factor = *rgb_dst_factor;
873 blend.rt[0].alpha_func = *alpha_func;
874 blend.rt[0].alpha_src_factor = *alpha_src_factor;
875 blend.rt[0].alpha_dst_factor = *alpha_dst_factor;
876 blend.rt[0].colormask = PIPE_MASK_RGBA;
José Fonseca2529ed52009-08-09 12:39:38 +0100877
878 if(!test_one(verbose, fp, &blend, mode, *type))
879 success = FALSE;
José Fonseca7d043162009-08-01 17:59:19 +0100880 }
881
882 return success;
883}