1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
31 * Unit tests for blend LLVM IR generation
33 * @author Jose Fonseca <jfonseca@vmware.com>
35 * Blend computation code derived from code written by
36 * @author Brian Paul <brian@vmware.com>
40 #include "gallivm/lp_bld_init.h"
41 #include "gallivm/lp_bld_type.h"
42 #include "gallivm/lp_bld_debug.h"
43 #include "lp_bld_blend.h"
54 typedef void (*blend_test_ptr_t
)(const void *src
, const void *dst
, const void *con
, void *res
);
57 static blend_test_ptr_t
58 voidptr_to_blend_test_ptr_t(void *p
)
71 write_tsv_header(FILE *fp
)
75 "cycles_per_channel\t"
86 "alpha_dst_factor\n");
93 write_tsv_row(FILE *fp
,
94 const struct pipe_blend_state
*blend
,
95 enum vector_mode mode
,
100 fprintf(fp
, "%s\t", success
? "pass" : "fail");
103 fprintf(fp
, "%.1f\t", cycles
/ type
.length
);
104 fprintf(fp
, "aos\t");
108 fprintf(fp
, "%.1f\t", cycles
/ (4 * type
.length
));
109 fprintf(fp
, "soa\t");
112 fprintf(fp
, "%s%u%sx%u\t",
113 type
.floating
? "f" : (type
.fixed
? "h" : (type
.sign
? "s" : "u")),
115 type
.norm
? "n" : "",
120 blend
->rt
[0].rgb_func
!= blend
->rt
[0].alpha_func
? "true" : "false",
121 blend
->rt
[0].rgb_src_factor
!= blend
->rt
[0].alpha_src_factor
? "true" : "false",
122 blend
->rt
[0].rgb_dst_factor
!= blend
->rt
[0].alpha_dst_factor
? "true" : "false");
125 "%s\t%s\t%s\t%s\t%s\t%s\n",
126 util_dump_blend_func(blend
->rt
[0].rgb_func
, TRUE
),
127 util_dump_blend_factor(blend
->rt
[0].rgb_src_factor
, TRUE
),
128 util_dump_blend_factor(blend
->rt
[0].rgb_dst_factor
, TRUE
),
129 util_dump_blend_func(blend
->rt
[0].alpha_func
, TRUE
),
130 util_dump_blend_factor(blend
->rt
[0].alpha_src_factor
, TRUE
),
131 util_dump_blend_factor(blend
->rt
[0].alpha_dst_factor
, TRUE
));
138 dump_blend_type(FILE *fp
,
139 const struct pipe_blend_state
*blend
,
140 enum vector_mode mode
,
143 fprintf(fp
, "%s", mode
? "soa" : "aos");
145 fprintf(fp
, " type=%s%u%sx%u",
146 type
.floating
? "f" : (type
.fixed
? "h" : (type
.sign
? "s" : "u")),
148 type
.norm
? "n" : "",
152 " %s=%s %s=%s %s=%s %s=%s %s=%s %s=%s",
153 "rgb_func", util_dump_blend_func(blend
->rt
[0].rgb_func
, TRUE
),
154 "rgb_src_factor", util_dump_blend_factor(blend
->rt
[0].rgb_src_factor
, TRUE
),
155 "rgb_dst_factor", util_dump_blend_factor(blend
->rt
[0].rgb_dst_factor
, TRUE
),
156 "alpha_func", util_dump_blend_func(blend
->rt
[0].alpha_func
, TRUE
),
157 "alpha_src_factor", util_dump_blend_factor(blend
->rt
[0].alpha_src_factor
, TRUE
),
158 "alpha_dst_factor", util_dump_blend_factor(blend
->rt
[0].alpha_dst_factor
, TRUE
));
160 fprintf(fp
, " ...\n");
166 add_blend_test(struct gallivm_state
*gallivm
,
167 const struct pipe_blend_state
*blend
,
168 enum vector_mode mode
,
171 LLVMModuleRef module
= gallivm
->module
;
172 LLVMContextRef context
= gallivm
->context
;
173 LLVMTypeRef vec_type
;
176 LLVMValueRef src_ptr
;
177 LLVMValueRef dst_ptr
;
178 LLVMValueRef const_ptr
;
179 LLVMValueRef res_ptr
;
180 LLVMBasicBlockRef block
;
181 LLVMBuilderRef builder
;
182 const enum pipe_format format
= PIPE_FORMAT_R8G8B8A8_UNORM
;
183 const unsigned rt
= 0;
184 const unsigned char swizzle
[4] = { 0, 1, 2, 3 };
186 vec_type
= lp_build_vec_type(gallivm
, type
);
188 args
[3] = args
[2] = args
[1] = args
[0] = LLVMPointerType(vec_type
, 0);
189 func
= LLVMAddFunction(module
, "test", LLVMFunctionType(LLVMVoidTypeInContext(context
), args
, 4, 0));
190 LLVMSetFunctionCallConv(func
, LLVMCCallConv
);
191 src_ptr
= LLVMGetParam(func
, 0);
192 dst_ptr
= LLVMGetParam(func
, 1);
193 const_ptr
= LLVMGetParam(func
, 2);
194 res_ptr
= LLVMGetParam(func
, 3);
196 block
= LLVMAppendBasicBlockInContext(context
, func
, "entry");
197 builder
= gallivm
->builder
;
198 LLVMPositionBuilderAtEnd(builder
, block
);
206 src
= LLVMBuildLoad(builder
, src_ptr
, "src");
207 dst
= LLVMBuildLoad(builder
, dst_ptr
, "dst");
208 con
= LLVMBuildLoad(builder
, const_ptr
, "const");
210 res
= lp_build_blend_aos(gallivm
, blend
, &format
, type
, rt
, src
, dst
, NULL
, con
, swizzle
);
212 lp_build_name(res
, "res");
214 LLVMBuildStore(builder
, res
, res_ptr
);
224 for(i
= 0; i
< 4; ++i
) {
225 LLVMValueRef index
= LLVMConstInt(LLVMInt32TypeInContext(context
), i
, 0);
226 src
[i
] = LLVMBuildLoad(builder
, LLVMBuildGEP(builder
, src_ptr
, &index
, 1, ""), "");
227 dst
[i
] = LLVMBuildLoad(builder
, LLVMBuildGEP(builder
, dst_ptr
, &index
, 1, ""), "");
228 con
[i
] = LLVMBuildLoad(builder
, LLVMBuildGEP(builder
, const_ptr
, &index
, 1, ""), "");
229 lp_build_name(src
[i
], "src.%c", "rgba"[i
]);
230 lp_build_name(con
[i
], "con.%c", "rgba"[i
]);
231 lp_build_name(dst
[i
], "dst.%c", "rgba"[i
]);
234 lp_build_blend_soa(gallivm
, blend
, type
, rt
, src
, dst
, con
, res
);
236 for(i
= 0; i
< 4; ++i
) {
237 LLVMValueRef index
= LLVMConstInt(LLVMInt32TypeInContext(context
), i
, 0);
238 lp_build_name(res
[i
], "res.%c", "rgba"[i
]);
239 LLVMBuildStore(builder
, res
[i
], LLVMBuildGEP(builder
, res_ptr
, &index
, 1, ""));
243 LLVMBuildRetVoid(builder
);;
250 compute_blend_ref_term(unsigned rgb_factor
,
251 unsigned alpha_factor
,
252 const double *factor
,
260 switch (rgb_factor
) {
261 case PIPE_BLENDFACTOR_ONE
:
262 term
[0] = factor
[0]; /* R */
263 term
[1] = factor
[1]; /* G */
264 term
[2] = factor
[2]; /* B */
266 case PIPE_BLENDFACTOR_SRC_COLOR
:
267 term
[0] = factor
[0] * src
[0]; /* R */
268 term
[1] = factor
[1] * src
[1]; /* G */
269 term
[2] = factor
[2] * src
[2]; /* B */
271 case PIPE_BLENDFACTOR_SRC_ALPHA
:
272 term
[0] = factor
[0] * src
[3]; /* R */
273 term
[1] = factor
[1] * src
[3]; /* G */
274 term
[2] = factor
[2] * src
[3]; /* B */
276 case PIPE_BLENDFACTOR_DST_COLOR
:
277 term
[0] = factor
[0] * dst
[0]; /* R */
278 term
[1] = factor
[1] * dst
[1]; /* G */
279 term
[2] = factor
[2] * dst
[2]; /* B */
281 case PIPE_BLENDFACTOR_DST_ALPHA
:
282 term
[0] = factor
[0] * dst
[3]; /* R */
283 term
[1] = factor
[1] * dst
[3]; /* G */
284 term
[2] = factor
[2] * dst
[3]; /* B */
286 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
287 temp
= MIN2(src
[3], 1.0f
- dst
[3]);
288 term
[0] = factor
[0] * temp
; /* R */
289 term
[1] = factor
[1] * temp
; /* G */
290 term
[2] = factor
[2] * temp
; /* B */
292 case PIPE_BLENDFACTOR_CONST_COLOR
:
293 term
[0] = factor
[0] * con
[0]; /* R */
294 term
[1] = factor
[1] * con
[1]; /* G */
295 term
[2] = factor
[2] * con
[2]; /* B */
297 case PIPE_BLENDFACTOR_CONST_ALPHA
:
298 term
[0] = factor
[0] * con
[3]; /* R */
299 term
[1] = factor
[1] * con
[3]; /* G */
300 term
[2] = factor
[2] * con
[3]; /* B */
302 case PIPE_BLENDFACTOR_SRC1_COLOR
:
303 assert(0); /* to do */
305 case PIPE_BLENDFACTOR_SRC1_ALPHA
:
306 assert(0); /* to do */
308 case PIPE_BLENDFACTOR_ZERO
:
309 term
[0] = 0.0f
; /* R */
310 term
[1] = 0.0f
; /* G */
311 term
[2] = 0.0f
; /* B */
313 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
314 term
[0] = factor
[0] * (1.0f
- src
[0]); /* R */
315 term
[1] = factor
[1] * (1.0f
- src
[1]); /* G */
316 term
[2] = factor
[2] * (1.0f
- src
[2]); /* B */
318 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
319 term
[0] = factor
[0] * (1.0f
- src
[3]); /* R */
320 term
[1] = factor
[1] * (1.0f
- src
[3]); /* G */
321 term
[2] = factor
[2] * (1.0f
- src
[3]); /* B */
323 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
324 term
[0] = factor
[0] * (1.0f
- dst
[3]); /* R */
325 term
[1] = factor
[1] * (1.0f
- dst
[3]); /* G */
326 term
[2] = factor
[2] * (1.0f
- dst
[3]); /* B */
328 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
329 term
[0] = factor
[0] * (1.0f
- dst
[0]); /* R */
330 term
[1] = factor
[1] * (1.0f
- dst
[1]); /* G */
331 term
[2] = factor
[2] * (1.0f
- dst
[2]); /* B */
333 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
334 term
[0] = factor
[0] * (1.0f
- con
[0]); /* R */
335 term
[1] = factor
[1] * (1.0f
- con
[1]); /* G */
336 term
[2] = factor
[2] * (1.0f
- con
[2]); /* B */
338 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
339 term
[0] = factor
[0] * (1.0f
- con
[3]); /* R */
340 term
[1] = factor
[1] * (1.0f
- con
[3]); /* G */
341 term
[2] = factor
[2] * (1.0f
- con
[3]); /* B */
343 case PIPE_BLENDFACTOR_INV_SRC1_COLOR
:
344 assert(0); /* to do */
346 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA
:
347 assert(0); /* to do */
354 * Compute src/first term A
356 switch (alpha_factor
) {
357 case PIPE_BLENDFACTOR_ONE
:
358 term
[3] = factor
[3]; /* A */
360 case PIPE_BLENDFACTOR_SRC_COLOR
:
361 case PIPE_BLENDFACTOR_SRC_ALPHA
:
362 term
[3] = factor
[3] * src
[3]; /* A */
364 case PIPE_BLENDFACTOR_DST_COLOR
:
365 case PIPE_BLENDFACTOR_DST_ALPHA
:
366 term
[3] = factor
[3] * dst
[3]; /* A */
368 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
:
369 term
[3] = src
[3]; /* A */
371 case PIPE_BLENDFACTOR_CONST_COLOR
:
372 case PIPE_BLENDFACTOR_CONST_ALPHA
:
373 term
[3] = factor
[3] * con
[3]; /* A */
375 case PIPE_BLENDFACTOR_ZERO
:
376 term
[3] = 0.0f
; /* A */
378 case PIPE_BLENDFACTOR_INV_SRC_COLOR
:
379 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
:
380 term
[3] = factor
[3] * (1.0f
- src
[3]); /* A */
382 case PIPE_BLENDFACTOR_INV_DST_COLOR
:
383 case PIPE_BLENDFACTOR_INV_DST_ALPHA
:
384 term
[3] = factor
[3] * (1.0f
- dst
[3]); /* A */
386 case PIPE_BLENDFACTOR_INV_CONST_COLOR
:
387 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
:
388 term
[3] = factor
[3] * (1.0f
- con
[3]);
397 compute_blend_ref(const struct pipe_blend_state
*blend
,
406 compute_blend_ref_term(blend
->rt
[0].rgb_src_factor
, blend
->rt
[0].alpha_src_factor
,
407 src
, src
, dst
, con
, src_term
);
408 compute_blend_ref_term(blend
->rt
[0].rgb_dst_factor
, blend
->rt
[0].alpha_dst_factor
,
409 dst
, src
, dst
, con
, dst_term
);
414 switch (blend
->rt
[0].rgb_func
) {
416 res
[0] = src_term
[0] + dst_term
[0]; /* R */
417 res
[1] = src_term
[1] + dst_term
[1]; /* G */
418 res
[2] = src_term
[2] + dst_term
[2]; /* B */
420 case PIPE_BLEND_SUBTRACT
:
421 res
[0] = src_term
[0] - dst_term
[0]; /* R */
422 res
[1] = src_term
[1] - dst_term
[1]; /* G */
423 res
[2] = src_term
[2] - dst_term
[2]; /* B */
425 case PIPE_BLEND_REVERSE_SUBTRACT
:
426 res
[0] = dst_term
[0] - src_term
[0]; /* R */
427 res
[1] = dst_term
[1] - src_term
[1]; /* G */
428 res
[2] = dst_term
[2] - src_term
[2]; /* B */
431 res
[0] = MIN2(src_term
[0], dst_term
[0]); /* R */
432 res
[1] = MIN2(src_term
[1], dst_term
[1]); /* G */
433 res
[2] = MIN2(src_term
[2], dst_term
[2]); /* B */
436 res
[0] = MAX2(src_term
[0], dst_term
[0]); /* R */
437 res
[1] = MAX2(src_term
[1], dst_term
[1]); /* G */
438 res
[2] = MAX2(src_term
[2], dst_term
[2]); /* B */
447 switch (blend
->rt
[0].alpha_func
) {
449 res
[3] = src_term
[3] + dst_term
[3]; /* A */
451 case PIPE_BLEND_SUBTRACT
:
452 res
[3] = src_term
[3] - dst_term
[3]; /* A */
454 case PIPE_BLEND_REVERSE_SUBTRACT
:
455 res
[3] = dst_term
[3] - src_term
[3]; /* A */
458 res
[3] = MIN2(src_term
[3], dst_term
[3]); /* A */
461 res
[3] = MAX2(src_term
[3], dst_term
[3]); /* A */
471 test_one(struct gallivm_state
*gallivm
,
474 const struct pipe_blend_state
*blend
,
475 enum vector_mode mode
,
478 LLVMModuleRef module
= gallivm
->module
;
479 LLVMValueRef func
= NULL
;
480 LLVMExecutionEngineRef engine
= gallivm
->engine
;
482 blend_test_ptr_t blend_test_ptr
;
484 const unsigned n
= LP_TEST_NUM_SAMPLES
;
485 int64_t cycles
[LP_TEST_NUM_SAMPLES
];
486 double cycles_avg
= 0.0;
491 dump_blend_type(stdout
, blend
, mode
, type
);
493 func
= add_blend_test(gallivm
, blend
, mode
, type
);
495 if(LLVMVerifyModule(module
, LLVMPrintMessageAction
, &error
)) {
496 LLVMDumpModule(module
);
499 LLVMDisposeMessage(error
);
501 code
= LLVMGetPointerToGlobal(engine
, func
);
502 blend_test_ptr
= voidptr_to_blend_test_ptr_t(code
);
505 lp_disassemble(code
);
508 for(i
= 0; i
< n
&& success
; ++i
) {
510 PIPE_ALIGN_VAR(16) uint8_t src
[LP_NATIVE_VECTOR_WIDTH
/8];
511 PIPE_ALIGN_VAR(16) uint8_t dst
[LP_NATIVE_VECTOR_WIDTH
/8];
512 PIPE_ALIGN_VAR(16) uint8_t con
[LP_NATIVE_VECTOR_WIDTH
/8];
513 PIPE_ALIGN_VAR(16) uint8_t res
[LP_NATIVE_VECTOR_WIDTH
/8];
514 PIPE_ALIGN_VAR(16) uint8_t ref
[LP_NATIVE_VECTOR_WIDTH
/8];
515 int64_t start_counter
= 0;
516 int64_t end_counter
= 0;
518 random_vec(type
, src
);
519 random_vec(type
, dst
);
520 random_vec(type
, con
);
523 double fsrc
[LP_MAX_VECTOR_LENGTH
];
524 double fdst
[LP_MAX_VECTOR_LENGTH
];
525 double fcon
[LP_MAX_VECTOR_LENGTH
];
526 double fref
[LP_MAX_VECTOR_LENGTH
];
528 read_vec(type
, src
, fsrc
);
529 read_vec(type
, dst
, fdst
);
530 read_vec(type
, con
, fcon
);
532 for(j
= 0; j
< type
.length
; j
+= 4)
533 compute_blend_ref(blend
, fsrc
+ j
, fdst
+ j
, fcon
+ j
, fref
+ j
);
535 write_vec(type
, ref
, fref
);
538 start_counter
= rdtsc();
539 blend_test_ptr(src
, dst
, con
, res
);
540 end_counter
= rdtsc();
542 cycles
[i
] = end_counter
- start_counter
;
544 if(!compare_vec(type
, res
, ref
)) {
548 dump_blend_type(stderr
, blend
, mode
, type
);
549 fprintf(stderr
, "MISMATCH\n");
551 fprintf(stderr
, " Src: ");
552 dump_vec(stderr
, type
, src
);
553 fprintf(stderr
, "\n");
555 fprintf(stderr
, " Dst: ");
556 dump_vec(stderr
, type
, dst
);
557 fprintf(stderr
, "\n");
559 fprintf(stderr
, " Con: ");
560 dump_vec(stderr
, type
, con
);
561 fprintf(stderr
, "\n");
563 fprintf(stderr
, " Res: ");
564 dump_vec(stderr
, type
, res
);
565 fprintf(stderr
, "\n");
567 fprintf(stderr
, " Ref: ");
568 dump_vec(stderr
, type
, ref
);
569 fprintf(stderr
, "\n");
574 const unsigned stride
= type
.length
*type
.width
/8;
575 PIPE_ALIGN_VAR(16) uint8_t src
[4*LP_NATIVE_VECTOR_WIDTH
/8];
576 PIPE_ALIGN_VAR(16) uint8_t dst
[4*LP_NATIVE_VECTOR_WIDTH
/8];
577 PIPE_ALIGN_VAR(16) uint8_t con
[4*LP_NATIVE_VECTOR_WIDTH
/8];
578 PIPE_ALIGN_VAR(16) uint8_t res
[4*LP_NATIVE_VECTOR_WIDTH
/8];
579 PIPE_ALIGN_VAR(16) uint8_t ref
[4*LP_NATIVE_VECTOR_WIDTH
/8];
580 int64_t start_counter
= 0;
581 int64_t end_counter
= 0;
584 for(j
= 0; j
< 4; ++j
) {
585 random_vec(type
, src
+ j
*stride
);
586 random_vec(type
, dst
+ j
*stride
);
587 random_vec(type
, con
+ j
*stride
);
597 for(k
= 0; k
< type
.length
; ++k
) {
598 for(j
= 0; j
< 4; ++j
) {
599 fsrc
[j
] = read_elem(type
, src
+ j
*stride
, k
);
600 fdst
[j
] = read_elem(type
, dst
+ j
*stride
, k
);
601 fcon
[j
] = read_elem(type
, con
+ j
*stride
, k
);
604 compute_blend_ref(blend
, fsrc
, fdst
, fcon
, fref
);
606 for(j
= 0; j
< 4; ++j
)
607 write_elem(type
, ref
+ j
*stride
, k
, fref
[j
]);
611 start_counter
= rdtsc();
612 blend_test_ptr(src
, dst
, con
, res
);
613 end_counter
= rdtsc();
615 cycles
[i
] = end_counter
- start_counter
;
618 for (j
= 0; j
< 4; ++j
)
619 if(!compare_vec(type
, res
+ j
*stride
, ref
+ j
*stride
))
626 dump_blend_type(stderr
, blend
, mode
, type
);
627 fprintf(stderr
, "MISMATCH\n");
628 for(j
= 0; j
< 4; ++j
) {
629 char channel
= "RGBA"[j
];
630 fprintf(stderr
, " Src%c: ", channel
);
631 dump_vec(stderr
, type
, src
+ j
*stride
);
632 fprintf(stderr
, "\n");
634 fprintf(stderr
, " Dst%c: ", channel
);
635 dump_vec(stderr
, type
, dst
+ j
*stride
);
636 fprintf(stderr
, "\n");
638 fprintf(stderr
, " Con%c: ", channel
);
639 dump_vec(stderr
, type
, con
+ j
*stride
);
640 fprintf(stderr
, "\n");
642 fprintf(stderr
, " Res%c: ", channel
);
643 dump_vec(stderr
, type
, res
+ j
*stride
);
644 fprintf(stderr
, "\n");
646 fprintf(stderr
, " Ref%c: ", channel
);
647 dump_vec(stderr
, type
, ref
+ j
*stride
);
648 fprintf(stderr
, "\n");
650 fprintf(stderr
, "\n");
657 * Unfortunately the output of cycle counter is not very reliable as it comes
658 * -- sometimes we get outliers (due IRQs perhaps?) which are
659 * better removed to avoid random or biased data.
662 double sum
= 0.0, sum2
= 0.0;
666 for(i
= 0; i
< n
; ++i
) {
668 sum2
+= cycles
[i
]*cycles
[i
];
672 std
= sqrtf((sum2
- n
*avg
*avg
)/n
);
676 for(i
= 0; i
< n
; ++i
) {
677 if(fabs(cycles
[i
] - avg
) <= 4.0*std
) {
688 write_tsv_row(fp
, blend
, mode
, type
, cycles_avg
, success
);
692 LLVMDumpModule(module
);
693 LLVMWriteBitcodeToFile(module
, "blend.bc");
694 fprintf(stderr
, "blend.bc written\n");
695 fprintf(stderr
, "Invoke as \"llc -o - blend.bc\"\n");
699 LLVMFreeMachineCodeForFunction(engine
, func
);
707 PIPE_BLENDFACTOR_ZERO
,
708 PIPE_BLENDFACTOR_ONE
,
709 PIPE_BLENDFACTOR_SRC_COLOR
,
710 PIPE_BLENDFACTOR_SRC_ALPHA
,
711 PIPE_BLENDFACTOR_DST_COLOR
,
712 PIPE_BLENDFACTOR_DST_ALPHA
,
713 PIPE_BLENDFACTOR_CONST_COLOR
,
714 PIPE_BLENDFACTOR_CONST_ALPHA
,
716 PIPE_BLENDFACTOR_SRC1_COLOR
,
717 PIPE_BLENDFACTOR_SRC1_ALPHA
,
719 PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
,
720 PIPE_BLENDFACTOR_INV_SRC_COLOR
,
721 PIPE_BLENDFACTOR_INV_SRC_ALPHA
,
722 PIPE_BLENDFACTOR_INV_DST_COLOR
,
723 PIPE_BLENDFACTOR_INV_DST_ALPHA
,
724 PIPE_BLENDFACTOR_INV_CONST_COLOR
,
725 PIPE_BLENDFACTOR_INV_CONST_ALPHA
,
727 PIPE_BLENDFACTOR_INV_SRC1_COLOR
,
728 PIPE_BLENDFACTOR_INV_SRC1_ALPHA
,
737 PIPE_BLEND_REVERSE_SUBTRACT
,
743 const struct lp_type blend_types
[] = {
744 /* float, fixed, sign, norm, width, len */
745 { TRUE
, FALSE
, TRUE
, FALSE
, 32, 4 }, /* f32 x 4 */
746 { FALSE
, FALSE
, FALSE
, TRUE
, 8, 16 }, /* u8n x 16 */
750 const unsigned num_funcs
= sizeof(blend_funcs
)/sizeof(blend_funcs
[0]);
751 const unsigned num_factors
= sizeof(blend_factors
)/sizeof(blend_factors
[0]);
752 const unsigned num_types
= sizeof(blend_types
)/sizeof(blend_types
[0]);
756 test_all(struct gallivm_state
*gallivm
, unsigned verbose
, FILE *fp
)
758 const unsigned *rgb_func
;
759 const unsigned *rgb_src_factor
;
760 const unsigned *rgb_dst_factor
;
761 const unsigned *alpha_func
;
762 const unsigned *alpha_src_factor
;
763 const unsigned *alpha_dst_factor
;
764 struct pipe_blend_state blend
;
765 enum vector_mode mode
;
766 const struct lp_type
*type
;
767 boolean success
= TRUE
;
769 for(rgb_func
= blend_funcs
; rgb_func
< &blend_funcs
[num_funcs
]; ++rgb_func
) {
770 for(alpha_func
= blend_funcs
; alpha_func
< &blend_funcs
[num_funcs
]; ++alpha_func
) {
771 for(rgb_src_factor
= blend_factors
; rgb_src_factor
< &blend_factors
[num_factors
]; ++rgb_src_factor
) {
772 for(rgb_dst_factor
= blend_factors
; rgb_dst_factor
<= rgb_src_factor
; ++rgb_dst_factor
) {
773 for(alpha_src_factor
= blend_factors
; alpha_src_factor
< &blend_factors
[num_factors
]; ++alpha_src_factor
) {
774 for(alpha_dst_factor
= blend_factors
; alpha_dst_factor
<= alpha_src_factor
; ++alpha_dst_factor
) {
775 for(mode
= 0; mode
< 2; ++mode
) {
776 for(type
= blend_types
; type
< &blend_types
[num_types
]; ++type
) {
778 if(*rgb_dst_factor
== PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
||
779 *alpha_dst_factor
== PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
)
782 memset(&blend
, 0, sizeof blend
);
783 blend
.rt
[0].blend_enable
= 1;
784 blend
.rt
[0].rgb_func
= *rgb_func
;
785 blend
.rt
[0].rgb_src_factor
= *rgb_src_factor
;
786 blend
.rt
[0].rgb_dst_factor
= *rgb_dst_factor
;
787 blend
.rt
[0].alpha_func
= *alpha_func
;
788 blend
.rt
[0].alpha_src_factor
= *alpha_src_factor
;
789 blend
.rt
[0].alpha_dst_factor
= *alpha_dst_factor
;
790 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
792 if(!test_one(gallivm
, verbose
, fp
, &blend
, mode
, *type
))
809 test_some(struct gallivm_state
*gallivm
, unsigned verbose
, FILE *fp
,
812 const unsigned *rgb_func
;
813 const unsigned *rgb_src_factor
;
814 const unsigned *rgb_dst_factor
;
815 const unsigned *alpha_func
;
816 const unsigned *alpha_src_factor
;
817 const unsigned *alpha_dst_factor
;
818 struct pipe_blend_state blend
;
819 enum vector_mode mode
;
820 const struct lp_type
*type
;
822 boolean success
= TRUE
;
824 for(i
= 0; i
< n
; ++i
) {
825 rgb_func
= &blend_funcs
[rand() % num_funcs
];
826 alpha_func
= &blend_funcs
[rand() % num_funcs
];
827 rgb_src_factor
= &blend_factors
[rand() % num_factors
];
828 alpha_src_factor
= &blend_factors
[rand() % num_factors
];
831 rgb_dst_factor
= &blend_factors
[rand() % num_factors
];
832 } while(*rgb_dst_factor
== PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
);
835 alpha_dst_factor
= &blend_factors
[rand() % num_factors
];
836 } while(*alpha_dst_factor
== PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
);
840 type
= &blend_types
[rand() % num_types
];
842 memset(&blend
, 0, sizeof blend
);
843 blend
.rt
[0].blend_enable
= 1;
844 blend
.rt
[0].rgb_func
= *rgb_func
;
845 blend
.rt
[0].rgb_src_factor
= *rgb_src_factor
;
846 blend
.rt
[0].rgb_dst_factor
= *rgb_dst_factor
;
847 blend
.rt
[0].alpha_func
= *alpha_func
;
848 blend
.rt
[0].alpha_src_factor
= *alpha_src_factor
;
849 blend
.rt
[0].alpha_dst_factor
= *alpha_dst_factor
;
850 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
852 if(!test_one(gallivm
, verbose
, fp
, &blend
, mode
, *type
))
861 test_single(struct gallivm_state
*gallivm
, unsigned verbose
, FILE *fp
)
863 printf("no test_single()");