lp_test_blend.c revision 272dadbe4ebeaeb4f942c0f3c2fd140285b0457c
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 58unsigned verbose = 0; 59 60 61typedef void (*blend_test_ptr_t)(const float *src, const float *dst, const float *const_, float *res); 62 63 64static LLVMValueRef 65add_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 122static void 123random_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) \ 134do { \ 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) \ 140do { \ 141 R = (A) - (B); if (R < 0.0f) R = 0.0f; \ 142} while (0) 143 144 145static void 146compute_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 292static void 293compute_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 363static boolean 364test_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 455struct value_name_pair 456{ 457 unsigned value; 458 const char *name; 459}; 460 461 462const struct value_name_pair 463blend_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 490const struct value_name_pair 491blend_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 500const unsigned num_funcs = sizeof(blend_funcs)/sizeof(blend_funcs[0]); 501const unsigned num_factors = sizeof(blend_factors)/sizeof(blend_factors[0]); 502 503 504static boolean 505test_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 560static boolean 561test_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 615int 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} 635