gallivm,llvmpipe,draw: Support multiple constant buffers.
[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 #include "util/u_memory.h"
40
41 #include "gallivm/lp_bld_init.h"
42 #include "gallivm/lp_bld_type.h"
43 #include "gallivm/lp_bld_debug.h"
44 #include "lp_bld_blend.h"
45 #include "lp_test.h"
46
47
48 typedef void (*blend_test_ptr_t)(const void *src, const void *dst, const void *con, void *res);
49
50
51 void
52 write_tsv_header(FILE *fp)
53 {
54 fprintf(fp,
55 "result\t"
56 "cycles_per_channel\t"
57 "type\t"
58 "sep_func\t"
59 "sep_src_factor\t"
60 "sep_dst_factor\t"
61 "rgb_func\t"
62 "rgb_src_factor\t"
63 "rgb_dst_factor\t"
64 "alpha_func\t"
65 "alpha_src_factor\t"
66 "alpha_dst_factor\n");
67
68 fflush(fp);
69 }
70
71
72 static void
73 write_tsv_row(FILE *fp,
74 const struct pipe_blend_state *blend,
75 struct lp_type type,
76 double cycles,
77 boolean success)
78 {
79 fprintf(fp, "%s\t", success ? "pass" : "fail");
80
81 fprintf(fp, "%.1f\t", cycles / type.length);
82
83 fprintf(fp, "%s%u%sx%u\t",
84 type.floating ? "f" : (type.fixed ? "h" : (type.sign ? "s" : "u")),
85 type.width,
86 type.norm ? "n" : "",
87 type.length);
88
89 fprintf(fp,
90 "%s\t%s\t%s\t",
91 blend->rt[0].rgb_func != blend->rt[0].alpha_func ? "true" : "false",
92 blend->rt[0].rgb_src_factor != blend->rt[0].alpha_src_factor ? "true" : "false",
93 blend->rt[0].rgb_dst_factor != blend->rt[0].alpha_dst_factor ? "true" : "false");
94
95 fprintf(fp,
96 "%s\t%s\t%s\t%s\t%s\t%s\n",
97 util_dump_blend_func(blend->rt[0].rgb_func, TRUE),
98 util_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE),
99 util_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE),
100 util_dump_blend_func(blend->rt[0].alpha_func, TRUE),
101 util_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE),
102 util_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE));
103
104 fflush(fp);
105 }
106
107
108 static void
109 dump_blend_type(FILE *fp,
110 const struct pipe_blend_state *blend,
111 struct lp_type type)
112 {
113 fprintf(fp, " type=%s%u%sx%u",
114 type.floating ? "f" : (type.fixed ? "h" : (type.sign ? "s" : "u")),
115 type.width,
116 type.norm ? "n" : "",
117 type.length);
118
119 fprintf(fp,
120 " %s=%s %s=%s %s=%s %s=%s %s=%s %s=%s",
121 "rgb_func", util_dump_blend_func(blend->rt[0].rgb_func, TRUE),
122 "rgb_src_factor", util_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE),
123 "rgb_dst_factor", util_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE),
124 "alpha_func", util_dump_blend_func(blend->rt[0].alpha_func, TRUE),
125 "alpha_src_factor", util_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE),
126 "alpha_dst_factor", util_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE));
127
128 fprintf(fp, " ...\n");
129 fflush(fp);
130 }
131
132
133 static LLVMValueRef
134 add_blend_test(struct gallivm_state *gallivm,
135 const struct pipe_blend_state *blend,
136 struct lp_type type)
137 {
138 LLVMModuleRef module = gallivm->module;
139 LLVMContextRef context = gallivm->context;
140 LLVMTypeRef vec_type;
141 LLVMTypeRef args[4];
142 LLVMValueRef func;
143 LLVMValueRef src_ptr;
144 LLVMValueRef dst_ptr;
145 LLVMValueRef const_ptr;
146 LLVMValueRef res_ptr;
147 LLVMBasicBlockRef block;
148 LLVMBuilderRef builder;
149 const enum pipe_format format = PIPE_FORMAT_R8G8B8A8_UNORM;
150 const unsigned rt = 0;
151 const unsigned char swizzle[4] = { 0, 1, 2, 3 };
152 LLVMValueRef src;
153 LLVMValueRef dst;
154 LLVMValueRef con;
155 LLVMValueRef res;
156
157 vec_type = lp_build_vec_type(gallivm, type);
158
159 args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0);
160 func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidTypeInContext(context), args, 4, 0));
161 LLVMSetFunctionCallConv(func, LLVMCCallConv);
162 src_ptr = LLVMGetParam(func, 0);
163 dst_ptr = LLVMGetParam(func, 1);
164 const_ptr = LLVMGetParam(func, 2);
165 res_ptr = LLVMGetParam(func, 3);
166
167 block = LLVMAppendBasicBlockInContext(context, func, "entry");
168 builder = gallivm->builder;
169 LLVMPositionBuilderAtEnd(builder, block);
170
171 src = LLVMBuildLoad(builder, src_ptr, "src");
172 dst = LLVMBuildLoad(builder, dst_ptr, "dst");
173 con = LLVMBuildLoad(builder, const_ptr, "const");
174
175 res = lp_build_blend_aos(gallivm, blend, &format, type, rt, src, NULL, dst, NULL, con, NULL, swizzle, 4);
176
177 lp_build_name(res, "res");
178
179 LLVMBuildStore(builder, res, res_ptr);
180
181 LLVMBuildRetVoid(builder);;
182
183 return func;
184 }
185
186
187 static void
188 compute_blend_ref_term(unsigned rgb_factor,
189 unsigned alpha_factor,
190 const double *factor,
191 const double *src,
192 const double *dst,
193 const double *con,
194 double *term)
195 {
196 double temp;
197
198 switch (rgb_factor) {
199 case PIPE_BLENDFACTOR_ONE:
200 term[0] = factor[0]; /* R */
201 term[1] = factor[1]; /* G */
202 term[2] = factor[2]; /* B */
203 break;
204 case PIPE_BLENDFACTOR_SRC_COLOR:
205 term[0] = factor[0] * src[0]; /* R */
206 term[1] = factor[1] * src[1]; /* G */
207 term[2] = factor[2] * src[2]; /* B */
208 break;
209 case PIPE_BLENDFACTOR_SRC_ALPHA:
210 term[0] = factor[0] * src[3]; /* R */
211 term[1] = factor[1] * src[3]; /* G */
212 term[2] = factor[2] * src[3]; /* B */
213 break;
214 case PIPE_BLENDFACTOR_DST_COLOR:
215 term[0] = factor[0] * dst[0]; /* R */
216 term[1] = factor[1] * dst[1]; /* G */
217 term[2] = factor[2] * dst[2]; /* B */
218 break;
219 case PIPE_BLENDFACTOR_DST_ALPHA:
220 term[0] = factor[0] * dst[3]; /* R */
221 term[1] = factor[1] * dst[3]; /* G */
222 term[2] = factor[2] * dst[3]; /* B */
223 break;
224 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
225 temp = MIN2(src[3], 1.0f - dst[3]);
226 term[0] = factor[0] * temp; /* R */
227 term[1] = factor[1] * temp; /* G */
228 term[2] = factor[2] * temp; /* B */
229 break;
230 case PIPE_BLENDFACTOR_CONST_COLOR:
231 term[0] = factor[0] * con[0]; /* R */
232 term[1] = factor[1] * con[1]; /* G */
233 term[2] = factor[2] * con[2]; /* B */
234 break;
235 case PIPE_BLENDFACTOR_CONST_ALPHA:
236 term[0] = factor[0] * con[3]; /* R */
237 term[1] = factor[1] * con[3]; /* G */
238 term[2] = factor[2] * con[3]; /* B */
239 break;
240 case PIPE_BLENDFACTOR_SRC1_COLOR:
241 assert(0); /* to do */
242 break;
243 case PIPE_BLENDFACTOR_SRC1_ALPHA:
244 assert(0); /* to do */
245 break;
246 case PIPE_BLENDFACTOR_ZERO:
247 term[0] = 0.0f; /* R */
248 term[1] = 0.0f; /* G */
249 term[2] = 0.0f; /* B */
250 break;
251 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
252 term[0] = factor[0] * (1.0f - src[0]); /* R */
253 term[1] = factor[1] * (1.0f - src[1]); /* G */
254 term[2] = factor[2] * (1.0f - src[2]); /* B */
255 break;
256 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
257 term[0] = factor[0] * (1.0f - src[3]); /* R */
258 term[1] = factor[1] * (1.0f - src[3]); /* G */
259 term[2] = factor[2] * (1.0f - src[3]); /* B */
260 break;
261 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
262 term[0] = factor[0] * (1.0f - dst[3]); /* R */
263 term[1] = factor[1] * (1.0f - dst[3]); /* G */
264 term[2] = factor[2] * (1.0f - dst[3]); /* B */
265 break;
266 case PIPE_BLENDFACTOR_INV_DST_COLOR:
267 term[0] = factor[0] * (1.0f - dst[0]); /* R */
268 term[1] = factor[1] * (1.0f - dst[1]); /* G */
269 term[2] = factor[2] * (1.0f - dst[2]); /* B */
270 break;
271 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
272 term[0] = factor[0] * (1.0f - con[0]); /* R */
273 term[1] = factor[1] * (1.0f - con[1]); /* G */
274 term[2] = factor[2] * (1.0f - con[2]); /* B */
275 break;
276 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
277 term[0] = factor[0] * (1.0f - con[3]); /* R */
278 term[1] = factor[1] * (1.0f - con[3]); /* G */
279 term[2] = factor[2] * (1.0f - con[3]); /* B */
280 break;
281 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
282 assert(0); /* to do */
283 break;
284 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
285 assert(0); /* to do */
286 break;
287 default:
288 assert(0);
289 }
290
291 /*
292 * Compute src/first term A
293 */
294 switch (alpha_factor) {
295 case PIPE_BLENDFACTOR_ONE:
296 term[3] = factor[3]; /* A */
297 break;
298 case PIPE_BLENDFACTOR_SRC_COLOR:
299 case PIPE_BLENDFACTOR_SRC_ALPHA:
300 term[3] = factor[3] * src[3]; /* A */
301 break;
302 case PIPE_BLENDFACTOR_DST_COLOR:
303 case PIPE_BLENDFACTOR_DST_ALPHA:
304 term[3] = factor[3] * dst[3]; /* A */
305 break;
306 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
307 term[3] = src[3]; /* A */
308 break;
309 case PIPE_BLENDFACTOR_CONST_COLOR:
310 case PIPE_BLENDFACTOR_CONST_ALPHA:
311 term[3] = factor[3] * con[3]; /* A */
312 break;
313 case PIPE_BLENDFACTOR_ZERO:
314 term[3] = 0.0f; /* A */
315 break;
316 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
317 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
318 term[3] = factor[3] * (1.0f - src[3]); /* A */
319 break;
320 case PIPE_BLENDFACTOR_INV_DST_COLOR:
321 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
322 term[3] = factor[3] * (1.0f - dst[3]); /* A */
323 break;
324 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
325 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
326 term[3] = factor[3] * (1.0f - con[3]);
327 break;
328 default:
329 assert(0);
330 }
331 }
332
333
334 static void
335 compute_blend_ref(const struct pipe_blend_state *blend,
336 const double *src,
337 const double *dst,
338 const double *con,
339 double *res)
340 {
341 double src_term[4];
342 double dst_term[4];
343
344 compute_blend_ref_term(blend->rt[0].rgb_src_factor, blend->rt[0].alpha_src_factor,
345 src, src, dst, con, src_term);
346 compute_blend_ref_term(blend->rt[0].rgb_dst_factor, blend->rt[0].alpha_dst_factor,
347 dst, src, dst, con, dst_term);
348
349 /*
350 * Combine RGB terms
351 */
352 switch (blend->rt[0].rgb_func) {
353 case PIPE_BLEND_ADD:
354 res[0] = src_term[0] + dst_term[0]; /* R */
355 res[1] = src_term[1] + dst_term[1]; /* G */
356 res[2] = src_term[2] + dst_term[2]; /* B */
357 break;
358 case PIPE_BLEND_SUBTRACT:
359 res[0] = src_term[0] - dst_term[0]; /* R */
360 res[1] = src_term[1] - dst_term[1]; /* G */
361 res[2] = src_term[2] - dst_term[2]; /* B */
362 break;
363 case PIPE_BLEND_REVERSE_SUBTRACT:
364 res[0] = dst_term[0] - src_term[0]; /* R */
365 res[1] = dst_term[1] - src_term[1]; /* G */
366 res[2] = dst_term[2] - src_term[2]; /* B */
367 break;
368 case PIPE_BLEND_MIN:
369 res[0] = MIN2(src_term[0], dst_term[0]); /* R */
370 res[1] = MIN2(src_term[1], dst_term[1]); /* G */
371 res[2] = MIN2(src_term[2], dst_term[2]); /* B */
372 break;
373 case PIPE_BLEND_MAX:
374 res[0] = MAX2(src_term[0], dst_term[0]); /* R */
375 res[1] = MAX2(src_term[1], dst_term[1]); /* G */
376 res[2] = MAX2(src_term[2], dst_term[2]); /* B */
377 break;
378 default:
379 assert(0);
380 }
381
382 /*
383 * Combine A terms
384 */
385 switch (blend->rt[0].alpha_func) {
386 case PIPE_BLEND_ADD:
387 res[3] = src_term[3] + dst_term[3]; /* A */
388 break;
389 case PIPE_BLEND_SUBTRACT:
390 res[3] = src_term[3] - dst_term[3]; /* A */
391 break;
392 case PIPE_BLEND_REVERSE_SUBTRACT:
393 res[3] = dst_term[3] - src_term[3]; /* A */
394 break;
395 case PIPE_BLEND_MIN:
396 res[3] = MIN2(src_term[3], dst_term[3]); /* A */
397 break;
398 case PIPE_BLEND_MAX:
399 res[3] = MAX2(src_term[3], dst_term[3]); /* A */
400 break;
401 default:
402 assert(0);
403 }
404 }
405
406
407 PIPE_ALIGN_STACK
408 static boolean
409 test_one(unsigned verbose,
410 FILE *fp,
411 const struct pipe_blend_state *blend,
412 struct lp_type type)
413 {
414 struct gallivm_state *gallivm;
415 LLVMValueRef func = NULL;
416 blend_test_ptr_t blend_test_ptr;
417 boolean success;
418 const unsigned n = LP_TEST_NUM_SAMPLES;
419 int64_t cycles[LP_TEST_NUM_SAMPLES];
420 double cycles_avg = 0.0;
421 unsigned i, j;
422 const unsigned stride = lp_type_width(type)/8;
423
424 if(verbose >= 1)
425 dump_blend_type(stdout, blend, type);
426
427 gallivm = gallivm_create();
428
429 func = add_blend_test(gallivm, blend, type);
430
431 gallivm_compile_module(gallivm);
432
433 blend_test_ptr = (blend_test_ptr_t)gallivm_jit_function(gallivm, func);
434
435 success = TRUE;
436
437 {
438 uint8_t *src, *dst, *con, *res, *ref;
439 src = align_malloc(stride, stride);
440 dst = align_malloc(stride, stride);
441 con = align_malloc(stride, stride);
442 res = align_malloc(stride, stride);
443 ref = align_malloc(stride, stride);
444
445 for(i = 0; i < n && success; ++i) {
446 int64_t start_counter = 0;
447 int64_t end_counter = 0;
448
449 random_vec(type, src);
450 random_vec(type, dst);
451 random_vec(type, con);
452
453 {
454 double fsrc[LP_MAX_VECTOR_LENGTH];
455 double fdst[LP_MAX_VECTOR_LENGTH];
456 double fcon[LP_MAX_VECTOR_LENGTH];
457 double fref[LP_MAX_VECTOR_LENGTH];
458
459 read_vec(type, src, fsrc);
460 read_vec(type, dst, fdst);
461 read_vec(type, con, fcon);
462
463 for(j = 0; j < type.length; j += 4)
464 compute_blend_ref(blend, fsrc + j, fdst + j, fcon + j, fref + j);
465
466 write_vec(type, ref, fref);
467 }
468
469 start_counter = rdtsc();
470 blend_test_ptr(src, dst, con, res);
471 end_counter = rdtsc();
472
473 cycles[i] = end_counter - start_counter;
474
475 if(!compare_vec(type, res, ref)) {
476 success = FALSE;
477
478 if(verbose < 1)
479 dump_blend_type(stderr, blend, type);
480 fprintf(stderr, "MISMATCH\n");
481
482 fprintf(stderr, " Src: ");
483 dump_vec(stderr, type, src);
484 fprintf(stderr, "\n");
485
486 fprintf(stderr, " Dst: ");
487 dump_vec(stderr, type, dst);
488 fprintf(stderr, "\n");
489
490 fprintf(stderr, " Con: ");
491 dump_vec(stderr, type, con);
492 fprintf(stderr, "\n");
493
494 fprintf(stderr, " Res: ");
495 dump_vec(stderr, type, res);
496 fprintf(stderr, "\n");
497
498 fprintf(stderr, " Ref: ");
499 dump_vec(stderr, type, ref);
500 fprintf(stderr, "\n");
501 }
502 }
503 align_free(src);
504 align_free(dst);
505 align_free(con);
506 align_free(res);
507 align_free(ref);
508 }
509
510 /*
511 * Unfortunately the output of cycle counter is not very reliable as it comes
512 * -- sometimes we get outliers (due IRQs perhaps?) which are
513 * better removed to avoid random or biased data.
514 */
515 {
516 double sum = 0.0, sum2 = 0.0;
517 double avg, std;
518 unsigned m;
519
520 for(i = 0; i < n; ++i) {
521 sum += cycles[i];
522 sum2 += cycles[i]*cycles[i];
523 }
524
525 avg = sum/n;
526 std = sqrtf((sum2 - n*avg*avg)/n);
527
528 m = 0;
529 sum = 0.0;
530 for(i = 0; i < n; ++i) {
531 if(fabs(cycles[i] - avg) <= 4.0*std) {
532 sum += cycles[i];
533 ++m;
534 }
535 }
536
537 cycles_avg = sum/m;
538
539 }
540
541 if(fp)
542 write_tsv_row(fp, blend, type, cycles_avg, success);
543
544 gallivm_free_function(gallivm, func, blend_test_ptr);
545
546 gallivm_destroy(gallivm);
547
548 return success;
549 }
550
551
552 const unsigned
553 blend_factors[] = {
554 PIPE_BLENDFACTOR_ZERO,
555 PIPE_BLENDFACTOR_ONE,
556 PIPE_BLENDFACTOR_SRC_COLOR,
557 PIPE_BLENDFACTOR_SRC_ALPHA,
558 PIPE_BLENDFACTOR_DST_COLOR,
559 PIPE_BLENDFACTOR_DST_ALPHA,
560 PIPE_BLENDFACTOR_CONST_COLOR,
561 PIPE_BLENDFACTOR_CONST_ALPHA,
562 #if 0
563 PIPE_BLENDFACTOR_SRC1_COLOR,
564 PIPE_BLENDFACTOR_SRC1_ALPHA,
565 #endif
566 PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE,
567 PIPE_BLENDFACTOR_INV_SRC_COLOR,
568 PIPE_BLENDFACTOR_INV_SRC_ALPHA,
569 PIPE_BLENDFACTOR_INV_DST_COLOR,
570 PIPE_BLENDFACTOR_INV_DST_ALPHA,
571 PIPE_BLENDFACTOR_INV_CONST_COLOR,
572 PIPE_BLENDFACTOR_INV_CONST_ALPHA,
573 #if 0
574 PIPE_BLENDFACTOR_INV_SRC1_COLOR,
575 PIPE_BLENDFACTOR_INV_SRC1_ALPHA,
576 #endif
577 };
578
579
580 const unsigned
581 blend_funcs[] = {
582 PIPE_BLEND_ADD,
583 PIPE_BLEND_SUBTRACT,
584 PIPE_BLEND_REVERSE_SUBTRACT,
585 PIPE_BLEND_MIN,
586 PIPE_BLEND_MAX
587 };
588
589
590 const struct lp_type blend_types[] = {
591 /* float, fixed, sign, norm, width, len */
592 { TRUE, FALSE, TRUE, FALSE, 32, 4 }, /* f32 x 4 */
593 { FALSE, FALSE, FALSE, TRUE, 8, 16 }, /* u8n x 16 */
594 };
595
596
597 const unsigned num_funcs = sizeof(blend_funcs)/sizeof(blend_funcs[0]);
598 const unsigned num_factors = sizeof(blend_factors)/sizeof(blend_factors[0]);
599 const unsigned num_types = sizeof(blend_types)/sizeof(blend_types[0]);
600
601
602 boolean
603 test_all(unsigned verbose, FILE *fp)
604 {
605 const unsigned *rgb_func;
606 const unsigned *rgb_src_factor;
607 const unsigned *rgb_dst_factor;
608 const unsigned *alpha_func;
609 const unsigned *alpha_src_factor;
610 const unsigned *alpha_dst_factor;
611 struct pipe_blend_state blend;
612 const struct lp_type *type;
613 boolean success = TRUE;
614
615 for(rgb_func = blend_funcs; rgb_func < &blend_funcs[num_funcs]; ++rgb_func) {
616 for(alpha_func = blend_funcs; alpha_func < &blend_funcs[num_funcs]; ++alpha_func) {
617 for(rgb_src_factor = blend_factors; rgb_src_factor < &blend_factors[num_factors]; ++rgb_src_factor) {
618 for(rgb_dst_factor = blend_factors; rgb_dst_factor <= rgb_src_factor; ++rgb_dst_factor) {
619 for(alpha_src_factor = blend_factors; alpha_src_factor < &blend_factors[num_factors]; ++alpha_src_factor) {
620 for(alpha_dst_factor = blend_factors; alpha_dst_factor <= alpha_src_factor; ++alpha_dst_factor) {
621 for(type = blend_types; type < &blend_types[num_types]; ++type) {
622
623 if(*rgb_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
624 *alpha_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE)
625 continue;
626
627 memset(&blend, 0, sizeof blend);
628 blend.rt[0].blend_enable = 1;
629 blend.rt[0].rgb_func = *rgb_func;
630 blend.rt[0].rgb_src_factor = *rgb_src_factor;
631 blend.rt[0].rgb_dst_factor = *rgb_dst_factor;
632 blend.rt[0].alpha_func = *alpha_func;
633 blend.rt[0].alpha_src_factor = *alpha_src_factor;
634 blend.rt[0].alpha_dst_factor = *alpha_dst_factor;
635 blend.rt[0].colormask = PIPE_MASK_RGBA;
636
637 if(!test_one(verbose, fp, &blend, *type))
638 success = FALSE;
639
640 }
641 }
642 }
643 }
644 }
645 }
646 }
647
648 return success;
649 }
650
651
652 boolean
653 test_some(unsigned verbose, FILE *fp,
654 unsigned long n)
655 {
656 const unsigned *rgb_func;
657 const unsigned *rgb_src_factor;
658 const unsigned *rgb_dst_factor;
659 const unsigned *alpha_func;
660 const unsigned *alpha_src_factor;
661 const unsigned *alpha_dst_factor;
662 struct pipe_blend_state blend;
663 const struct lp_type *type;
664 unsigned long i;
665 boolean success = TRUE;
666
667 for(i = 0; i < n; ++i) {
668 rgb_func = &blend_funcs[rand() % num_funcs];
669 alpha_func = &blend_funcs[rand() % num_funcs];
670 rgb_src_factor = &blend_factors[rand() % num_factors];
671 alpha_src_factor = &blend_factors[rand() % num_factors];
672
673 do {
674 rgb_dst_factor = &blend_factors[rand() % num_factors];
675 } while(*rgb_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
676
677 do {
678 alpha_dst_factor = &blend_factors[rand() % num_factors];
679 } while(*alpha_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
680
681 type = &blend_types[rand() % num_types];
682
683 memset(&blend, 0, sizeof blend);
684 blend.rt[0].blend_enable = 1;
685 blend.rt[0].rgb_func = *rgb_func;
686 blend.rt[0].rgb_src_factor = *rgb_src_factor;
687 blend.rt[0].rgb_dst_factor = *rgb_dst_factor;
688 blend.rt[0].alpha_func = *alpha_func;
689 blend.rt[0].alpha_src_factor = *alpha_src_factor;
690 blend.rt[0].alpha_dst_factor = *alpha_dst_factor;
691 blend.rt[0].colormask = PIPE_MASK_RGBA;
692
693 if(!test_one(verbose, fp, &blend, *type))
694 success = FALSE;
695 }
696
697 return success;
698 }
699
700
701 boolean
702 test_single(unsigned verbose, FILE *fp)
703 {
704 printf("no test_single()");
705 return TRUE;
706 }