llvmpipe: Introduce a custom typing system.
[mesa.git] / src / gallium / drivers / llvmpipe / lp_test_blend.c
1 /**************************************************************************
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
40 #include <stdlib.h>
41 #include <stdio.h>
42
43 #include <llvm-c/Core.h>
44 #include <llvm-c/Analysis.h>
45 #include <llvm-c/ExecutionEngine.h>
46 #include <llvm-c/Target.h>
47 #include <llvm-c/BitWriter.h>
48 #include <llvm-c/Transforms/Scalar.h>
49
50 #include "pipe/p_state.h"
51 #include "util/u_format.h"
52 #include "util/u_math.h"
53
54 #include "lp_bld.h"
55 #include "lp_bld_arit.h"
56
57
58 unsigned verbose = 0;
59
60
61 typedef void (*blend_test_ptr_t)(const float *src, const float *dst, const float *const_, float *res);
62
63
64 static LLVMValueRef
65 add_blend_test(LLVMModuleRef module,
66 const struct pipe_blend_state *blend)
67 {
68 union lp_type type;
69
70 LLVMTypeRef args[4];
71 LLVMValueRef func;
72 LLVMValueRef src_ptr;
73 LLVMValueRef dst_ptr;
74 LLVMValueRef const_ptr;
75 LLVMValueRef res_ptr;
76 LLVMBasicBlockRef block;
77 LLVMBuilderRef builder;
78 LLVMValueRef src;
79 LLVMValueRef dst;
80 LLVMValueRef const_;
81 LLVMValueRef res;
82
83 type.value = 0;
84 type.kind = LP_TYPE_FLOAT;
85 type.sign = TRUE;
86 type.norm = TRUE;
87 type.width = 32;
88 type.length = 4;
89
90 args[0] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
91 args[1] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
92 args[2] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
93 args[3] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
94 func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidType(), args, 4, 0));
95 LLVMSetFunctionCallConv(func, LLVMCCallConv);
96 src_ptr = LLVMGetParam(func, 0);
97 dst_ptr = LLVMGetParam(func, 1);
98 const_ptr = LLVMGetParam(func, 2);
99 res_ptr = LLVMGetParam(func, 3);
100
101 block = LLVMAppendBasicBlock(func, "entry");
102 builder = LLVMCreateBuilder();
103 LLVMPositionBuilderAtEnd(builder, block);
104
105 src = LLVMBuildLoad(builder, src_ptr, "src");
106 dst = LLVMBuildLoad(builder, dst_ptr, "dst");
107 const_ = LLVMBuildLoad(builder, const_ptr, "const");
108
109 res = lp_build_blend(builder, blend, type, src, dst, const_, 3);
110
111 LLVMSetValueName(res, "res");
112
113 LLVMBuildStore(builder, res, res_ptr);
114
115 LLVMBuildRetVoid(builder);
116
117 LLVMDisposeBuilder(builder);
118 return func;
119 }
120
121
122 static void
123 random_color(float *color)
124 {
125 color[0] = (float)((double)random()/(double)RAND_MAX);
126 color[1] = (float)((double)random()/(double)RAND_MAX);
127 color[2] = (float)((double)random()/(double)RAND_MAX);
128 color[3] = (float)((double)random()/(double)RAND_MAX);
129 }
130
131
132 /** Add and limit result to ceiling of 1.0 */
133 #define ADD_SAT(R, A, B) \
134 do { \
135 R = (A) + (B); if (R > 1.0f) R = 1.0f; \
136 } while (0)
137
138 /** Subtract and limit result to floor of 0.0 */
139 #define SUB_SAT(R, A, B) \
140 do { \
141 R = (A) - (B); if (R < 0.0f) R = 0.0f; \
142 } while (0)
143
144
145 static void
146 compute_blend_ref_term(unsigned rgb_factor,
147 unsigned alpha_factor,
148 const float *factor,
149 const float *src,
150 const float *dst,
151 const float *const_,
152 float *term)
153 {
154 float temp;
155
156 switch (rgb_factor) {
157 case PIPE_BLENDFACTOR_ONE:
158 term[0] = factor[0]; /* R */
159 term[1] = factor[1]; /* G */
160 term[2] = factor[2]; /* B */
161 break;
162 case PIPE_BLENDFACTOR_SRC_COLOR:
163 term[0] = factor[0] * src[0]; /* R */
164 term[1] = factor[1] * src[1]; /* G */
165 term[2] = factor[2] * src[2]; /* B */
166 break;
167 case PIPE_BLENDFACTOR_SRC_ALPHA:
168 term[0] = factor[0] * src[3]; /* R */
169 term[1] = factor[1] * src[3]; /* G */
170 term[2] = factor[2] * src[3]; /* B */
171 break;
172 case PIPE_BLENDFACTOR_DST_COLOR:
173 term[0] = factor[0] * dst[0]; /* R */
174 term[1] = factor[1] * dst[1]; /* G */
175 term[2] = factor[2] * dst[2]; /* B */
176 break;
177 case PIPE_BLENDFACTOR_DST_ALPHA:
178 term[0] = factor[0] * dst[3]; /* R */
179 term[1] = factor[1] * dst[3]; /* G */
180 term[2] = factor[2] * dst[3]; /* B */
181 break;
182 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
183 temp = MIN2(src[3], 1.0f - dst[3]);
184 term[0] = factor[0] * temp; /* R */
185 term[1] = factor[1] * temp; /* G */
186 term[2] = factor[2] * temp; /* B */
187 break;
188 case PIPE_BLENDFACTOR_CONST_COLOR:
189 term[0] = factor[0] * const_[0]; /* R */
190 term[1] = factor[1] * const_[1]; /* G */
191 term[2] = factor[2] * const_[2]; /* B */
192 break;
193 case PIPE_BLENDFACTOR_CONST_ALPHA:
194 term[0] = factor[0] * const_[3]; /* R */
195 term[1] = factor[1] * const_[3]; /* G */
196 term[2] = factor[2] * const_[3]; /* B */
197 break;
198 case PIPE_BLENDFACTOR_SRC1_COLOR:
199 assert(0); /* to do */
200 break;
201 case PIPE_BLENDFACTOR_SRC1_ALPHA:
202 assert(0); /* to do */
203 break;
204 case PIPE_BLENDFACTOR_ZERO:
205 term[0] = 0.0f; /* R */
206 term[1] = 0.0f; /* G */
207 term[2] = 0.0f; /* B */
208 break;
209 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
210 term[0] = factor[0] * (1.0f - src[0]); /* R */
211 term[1] = factor[1] * (1.0f - src[1]); /* G */
212 term[2] = factor[2] * (1.0f - src[2]); /* B */
213 break;
214 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
215 term[0] = factor[0] * (1.0f - src[3]); /* R */
216 term[1] = factor[1] * (1.0f - src[3]); /* G */
217 term[2] = factor[2] * (1.0f - src[3]); /* B */
218 break;
219 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
220 term[0] = factor[0] * (1.0f - dst[3]); /* R */
221 term[1] = factor[1] * (1.0f - dst[3]); /* G */
222 term[2] = factor[2] * (1.0f - dst[3]); /* B */
223 break;
224 case PIPE_BLENDFACTOR_INV_DST_COLOR:
225 term[0] = factor[0] * (1.0f - dst[0]); /* R */
226 term[1] = factor[1] * (1.0f - dst[1]); /* G */
227 term[2] = factor[2] * (1.0f - dst[2]); /* B */
228 break;
229 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
230 term[0] = factor[0] * (1.0f - const_[0]); /* R */
231 term[1] = factor[1] * (1.0f - const_[1]); /* G */
232 term[2] = factor[2] * (1.0f - const_[2]); /* B */
233 break;
234 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
235 term[0] = factor[0] * (1.0f - const_[3]); /* R */
236 term[1] = factor[1] * (1.0f - const_[3]); /* G */
237 term[2] = factor[2] * (1.0f - const_[3]); /* B */
238 break;
239 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
240 assert(0); /* to do */
241 break;
242 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
243 assert(0); /* to do */
244 break;
245 default:
246 assert(0);
247 }
248
249 /*
250 * Compute src/first term A
251 */
252 switch (alpha_factor) {
253 case PIPE_BLENDFACTOR_ONE:
254 term[3] = factor[3]; /* A */
255 break;
256 case PIPE_BLENDFACTOR_SRC_COLOR:
257 case PIPE_BLENDFACTOR_SRC_ALPHA:
258 term[3] = factor[3] * src[3]; /* A */
259 break;
260 case PIPE_BLENDFACTOR_DST_COLOR:
261 case PIPE_BLENDFACTOR_DST_ALPHA:
262 term[3] = factor[3] * dst[3]; /* A */
263 break;
264 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
265 term[3] = src[3]; /* A */
266 break;
267 case PIPE_BLENDFACTOR_CONST_COLOR:
268 case PIPE_BLENDFACTOR_CONST_ALPHA:
269 term[3] = factor[3] * const_[3]; /* A */
270 break;
271 case PIPE_BLENDFACTOR_ZERO:
272 term[3] = 0.0f; /* A */
273 break;
274 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
275 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
276 term[3] = factor[3] * (1.0f - src[3]); /* A */
277 break;
278 case PIPE_BLENDFACTOR_INV_DST_COLOR:
279 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
280 term[3] = factor[3] * (1.0f - dst[3]); /* A */
281 break;
282 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
283 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
284 term[3] = factor[3] * (1.0f - const_[3]);
285 break;
286 default:
287 assert(0);
288 }
289 }
290
291
292 static void
293 compute_blend_ref(const struct pipe_blend_state *blend,
294 const float *src,
295 const float *dst,
296 const float *const_,
297 float *res)
298 {
299 float src_term[4];
300 float dst_term[4];
301
302 compute_blend_ref_term(blend->rgb_src_factor, blend->alpha_src_factor, src, src, dst, const_, src_term);
303 compute_blend_ref_term(blend->rgb_dst_factor, blend->alpha_dst_factor, dst, src, dst, const_, dst_term);
304
305 /*
306 * Combine RGB terms
307 */
308 switch (blend->rgb_func) {
309 case PIPE_BLEND_ADD:
310 ADD_SAT(res[0], src_term[0], dst_term[0]); /* R */
311 ADD_SAT(res[1], src_term[1], dst_term[1]); /* G */
312 ADD_SAT(res[2], src_term[2], dst_term[2]); /* B */
313 break;
314 case PIPE_BLEND_SUBTRACT:
315 SUB_SAT(res[0], src_term[0], dst_term[0]); /* R */
316 SUB_SAT(res[1], src_term[1], dst_term[1]); /* G */
317 SUB_SAT(res[2], src_term[2], dst_term[2]); /* B */
318 break;
319 case PIPE_BLEND_REVERSE_SUBTRACT:
320 SUB_SAT(res[0], dst_term[0], src_term[0]); /* R */
321 SUB_SAT(res[1], dst_term[1], src_term[1]); /* G */
322 SUB_SAT(res[2], dst_term[2], src_term[2]); /* B */
323 break;
324 case PIPE_BLEND_MIN:
325 res[0] = MIN2(src_term[0], dst_term[0]); /* R */
326 res[1] = MIN2(src_term[1], dst_term[1]); /* G */
327 res[2] = MIN2(src_term[2], dst_term[2]); /* B */
328 break;
329 case PIPE_BLEND_MAX:
330 res[0] = MAX2(src_term[0], dst_term[0]); /* R */
331 res[1] = MAX2(src_term[1], dst_term[1]); /* G */
332 res[2] = MAX2(src_term[2], dst_term[2]); /* B */
333 break;
334 default:
335 assert(0);
336 }
337
338 /*
339 * Combine A terms
340 */
341 switch (blend->alpha_func) {
342 case PIPE_BLEND_ADD:
343 ADD_SAT(res[3], src_term[3], dst_term[3]); /* A */
344 break;
345 case PIPE_BLEND_SUBTRACT:
346 SUB_SAT(res[3], src_term[3], dst_term[3]); /* A */
347 break;
348 case PIPE_BLEND_REVERSE_SUBTRACT:
349 SUB_SAT(res[3], dst_term[3], src_term[3]); /* A */
350 break;
351 case PIPE_BLEND_MIN:
352 res[3] = MIN2(src_term[3], dst_term[3]); /* A */
353 break;
354 case PIPE_BLEND_MAX:
355 res[3] = MAX2(src_term[3], dst_term[3]); /* A */
356 break;
357 default:
358 assert(0);
359 }
360 }
361
362
363 static boolean
364 test_one(const struct pipe_blend_state *blend)
365 {
366 LLVMModuleRef module = NULL;
367 LLVMValueRef func = NULL;
368 LLVMExecutionEngineRef engine = NULL;
369 LLVMModuleProviderRef provider = NULL;
370 LLVMPassManagerRef pass = NULL;
371 char *error = NULL;
372 blend_test_ptr_t blend_test_ptr;
373 boolean success;
374 unsigned i, j;
375
376 module = LLVMModuleCreateWithName("test");
377
378 func = add_blend_test(module, blend);
379
380 if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
381 LLVMDumpModule(module);
382 abort();
383 }
384 LLVMDisposeMessage(error);
385
386 provider = LLVMCreateModuleProviderForExistingModule(module);
387 if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
388 fprintf(stderr, "%s\n", error);
389 LLVMDisposeMessage(error);
390 abort();
391 }
392
393 #if 0
394 pass = LLVMCreatePassManager();
395 LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
396 /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
397 * but there are more on SVN. */
398 LLVMAddConstantPropagationPass(pass);
399 LLVMAddInstructionCombiningPass(pass);
400 LLVMAddPromoteMemoryToRegisterPass(pass);
401 LLVMAddGVNPass(pass);
402 LLVMAddCFGSimplificationPass(pass);
403 LLVMRunPassManager(pass, module);
404 #else
405 (void)pass;
406 #endif
407
408 blend_test_ptr = (blend_test_ptr_t)LLVMGetPointerToGlobal(engine, func);
409
410 if(verbose >= 2)
411 LLVMDumpModule(module);
412
413 success = TRUE;
414 for(i = 0; i < 10; ++i) {
415 float src[4];
416 float dst[4];
417 float const_[4];
418 float ref[4];
419 float res[4];
420
421 random_color(src);
422 random_color(dst);
423 random_color(const_);
424
425 compute_blend_ref(blend, src, dst, const_, ref);
426
427 blend_test_ptr(src, dst, const_, res);
428
429 for(j = 0; j < 4; ++j)
430 if(res[j] != ref[j])
431 success = FALSE;
432
433 if (!success) {
434 fprintf(stderr, "FAILED\n");
435 fprintf(stderr, " Result: %f %f %f %f\n", res[0], res[1], res[2], res[3]);
436 fprintf(stderr, " %f %f %f %f\n", ref[0], ref[1], ref[2], ref[3]);
437 LLVMDumpModule(module);
438 LLVMWriteBitcodeToFile(module, "blend.bc");
439 fprintf(stderr, "blend.bc written\n");
440 abort();
441 break;
442 }
443 }
444
445 LLVMFreeMachineCodeForFunction(engine, func);
446
447 LLVMDisposeExecutionEngine(engine);
448 if(pass)
449 LLVMDisposePassManager(pass);
450
451 return success;
452 }
453
454
455 struct value_name_pair
456 {
457 unsigned value;
458 const char *name;
459 };
460
461
462 const struct value_name_pair
463 blend_factors[] = {
464 {PIPE_BLENDFACTOR_ZERO , "zero"},
465 {PIPE_BLENDFACTOR_ONE , "one"},
466 {PIPE_BLENDFACTOR_SRC_COLOR , "src_color"},
467 {PIPE_BLENDFACTOR_SRC_ALPHA , "src_alpha"},
468 {PIPE_BLENDFACTOR_DST_COLOR , "dst_color"},
469 {PIPE_BLENDFACTOR_DST_ALPHA , "dst_alpha"},
470 {PIPE_BLENDFACTOR_CONST_COLOR , "const_color"},
471 {PIPE_BLENDFACTOR_CONST_ALPHA , "const_alpha"},
472 #if 0
473 {PIPE_BLENDFACTOR_SRC1_COLOR , "src1_color"},
474 {PIPE_BLENDFACTOR_SRC1_ALPHA , "src1_alpha"},
475 #endif
476 {PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE , "src_alpha_saturate"},
477 {PIPE_BLENDFACTOR_INV_SRC_COLOR , "inv_src_color"},
478 {PIPE_BLENDFACTOR_INV_SRC_ALPHA , "inv_src_alpha"},
479 {PIPE_BLENDFACTOR_INV_DST_COLOR , "inv_dst_color"},
480 {PIPE_BLENDFACTOR_INV_DST_ALPHA , "inv_dst_alpha"},
481 {PIPE_BLENDFACTOR_INV_CONST_COLOR , "inv_const_color"},
482 {PIPE_BLENDFACTOR_INV_CONST_ALPHA , "inv_const_alpha"},
483 #if 0
484 {PIPE_BLENDFACTOR_INV_SRC1_COLOR , "inv_src1_color"},
485 {PIPE_BLENDFACTOR_INV_SRC1_ALPHA , "inv_src1_alpha"}
486 #endif
487 };
488
489
490 const struct value_name_pair
491 blend_funcs[] = {
492 {PIPE_BLEND_ADD , "add"},
493 {PIPE_BLEND_SUBTRACT , "sub"},
494 {PIPE_BLEND_REVERSE_SUBTRACT , "rev_sub"},
495 {PIPE_BLEND_MIN , "min"},
496 {PIPE_BLEND_MAX , "max"}
497 };
498
499
500 const unsigned num_funcs = sizeof(blend_funcs)/sizeof(blend_funcs[0]);
501 const unsigned num_factors = sizeof(blend_factors)/sizeof(blend_factors[0]);
502
503
504 static boolean
505 test_all(void)
506 {
507 const struct value_name_pair *rgb_func;
508 const struct value_name_pair *rgb_src_factor;
509 const struct value_name_pair *rgb_dst_factor;
510 const struct value_name_pair *alpha_func;
511 const struct value_name_pair *alpha_src_factor;
512 const struct value_name_pair *alpha_dst_factor;
513 struct pipe_blend_state blend;
514 bool success = TRUE;
515
516 for(rgb_func = blend_funcs; rgb_func < &blend_funcs[num_funcs]; ++rgb_func) {
517 for(alpha_func = blend_funcs; alpha_func < &blend_funcs[num_funcs]; ++alpha_func) {
518 for(rgb_src_factor = blend_factors; rgb_src_factor < &blend_factors[num_factors]; ++rgb_src_factor) {
519 for(rgb_dst_factor = blend_factors; rgb_dst_factor <= rgb_src_factor; ++rgb_dst_factor) {
520 for(alpha_src_factor = blend_factors; alpha_src_factor < &blend_factors[num_factors]; ++alpha_src_factor) {
521 for(alpha_dst_factor = blend_factors; alpha_dst_factor <= alpha_src_factor; ++alpha_dst_factor) {
522
523 if(rgb_dst_factor->value == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
524 alpha_dst_factor->value == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE)
525 continue;
526
527 if(verbose >= 1)
528 fprintf(stderr,
529 "%s=%s %s=%s %s=%s %s=%s %s=%s %s=%s ...\n",
530 "rgb_func", rgb_func->name,
531 "rgb_src_factor", rgb_src_factor->name,
532 "rgb_dst_factor", rgb_dst_factor->name,
533 "alpha_func", alpha_func->name,
534 "alpha_src_factor", alpha_src_factor->name,
535 "alpha_dst_factor", alpha_dst_factor->name);
536
537 memset(&blend, 0, sizeof blend);
538 blend.blend_enable = 1;
539 blend.rgb_func = rgb_func->value;
540 blend.rgb_src_factor = rgb_src_factor->value;
541 blend.rgb_dst_factor = rgb_dst_factor->value;
542 blend.alpha_func = alpha_func->value;
543 blend.alpha_src_factor = alpha_src_factor->value;
544 blend.alpha_dst_factor = alpha_dst_factor->value;
545
546 if(!test_one(&blend))
547 success = FALSE;
548
549 }
550 }
551 }
552 }
553 }
554 }
555
556 return success;
557 }
558
559
560 static boolean
561 test_some(unsigned long n)
562 {
563 const struct value_name_pair *rgb_func;
564 const struct value_name_pair *rgb_src_factor;
565 const struct value_name_pair *rgb_dst_factor;
566 const struct value_name_pair *alpha_func;
567 const struct value_name_pair *alpha_src_factor;
568 const struct value_name_pair *alpha_dst_factor;
569 struct pipe_blend_state blend;
570 unsigned long i;
571 bool success = TRUE;
572
573 for(i = 0; i < n; ++i) {
574 rgb_func = &blend_funcs[random() % num_funcs];
575 alpha_func = &blend_funcs[random() % num_funcs];
576 rgb_src_factor = &blend_factors[random() % num_factors];
577 alpha_src_factor = &blend_factors[random() % num_factors];
578
579 do {
580 rgb_dst_factor = &blend_factors[random() % num_factors];
581 } while(rgb_dst_factor->value == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
582
583 do {
584 alpha_dst_factor = &blend_factors[random() % num_factors];
585 } while(alpha_dst_factor->value == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
586
587 if(verbose >= 1)
588 fprintf(stderr,
589 "%s=%s %s=%s %s=%s %s=%s %s=%s %s=%s ...\n",
590 "rgb_func", rgb_func->name,
591 "rgb_src_factor", rgb_src_factor->name,
592 "rgb_dst_factor", rgb_dst_factor->name,
593 "alpha_func", alpha_func->name,
594 "alpha_src_factor", alpha_src_factor->name,
595 "alpha_dst_factor", alpha_dst_factor->name);
596
597 memset(&blend, 0, sizeof blend);
598 blend.blend_enable = 1;
599 blend.rgb_func = rgb_func->value;
600 blend.rgb_src_factor = rgb_src_factor->value;
601 blend.rgb_dst_factor = rgb_dst_factor->value;
602 blend.alpha_func = alpha_func->value;
603 blend.alpha_src_factor = alpha_src_factor->value;
604 blend.alpha_dst_factor = alpha_dst_factor->value;
605
606 if(!test_one(&blend))
607 success = FALSE;
608
609 }
610
611 return success;
612 }
613
614
615 int main(int argc, char **argv)
616 {
617 unsigned long n = 1000;
618 unsigned i;
619 boolean success;
620
621 for(i = 1; i < argc; ++i) {
622 if(strcmp(argv[i], "-v") == 0)
623 ++verbose;
624 else
625 n = atoi(argv[i]);
626 }
627
628 if(n)
629 success = test_some(n);
630 else
631 success = test_all();
632
633 return success ? 0 : 1;
634 }