sp_quad_blend.c revision b642730be93149baa7556e5791393168ab396175
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN GRAPHICS 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 * quad blending 30 * \author Brian Paul 31 */ 32 33#include "pipe/p_defines.h" 34#include "pipe/p_util.h" 35#include "sp_context.h" 36#include "sp_headers.h" 37#include "sp_surface.h" 38#include "sp_tile_cache.h" 39#include "sp_quad.h" 40 41 42#define VEC4_COPY(DST, SRC) \ 43do { \ 44 DST[0] = SRC[0]; \ 45 DST[1] = SRC[1]; \ 46 DST[2] = SRC[2]; \ 47 DST[3] = SRC[3]; \ 48} while(0) 49 50#define VEC4_SCALAR(DST, SRC) \ 51do { \ 52 DST[0] = SRC; \ 53 DST[1] = SRC; \ 54 DST[2] = SRC; \ 55 DST[3] = SRC; \ 56} while(0) 57 58#define VEC4_ADD(R, A, B) \ 59do { \ 60 R[0] = A[0] + B[0]; \ 61 R[1] = A[1] + B[1]; \ 62 R[2] = A[2] + B[2]; \ 63 R[3] = A[3] + B[3]; \ 64} while (0) 65 66#define VEC4_SUB(R, A, B) \ 67do { \ 68 R[0] = A[0] - B[0]; \ 69 R[1] = A[1] - B[1]; \ 70 R[2] = A[2] - B[2]; \ 71 R[3] = A[3] - B[3]; \ 72} while (0) 73 74#define VEC4_MUL(R, A, B) \ 75do { \ 76 R[0] = A[0] * B[0]; \ 77 R[1] = A[1] * B[1]; \ 78 R[2] = A[2] * B[2]; \ 79 R[3] = A[3] * B[3]; \ 80} while (0) 81 82#define VEC4_MIN(R, A, B) \ 83do { \ 84 R[0] = (A[0] < B[0]) ? A[0] : B[0]; \ 85 R[1] = (A[1] < B[1]) ? A[1] : B[1]; \ 86 R[2] = (A[2] < B[2]) ? A[2] : B[2]; \ 87 R[3] = (A[3] < B[3]) ? A[3] : B[3]; \ 88} while (0) 89 90#define VEC4_MAX(R, A, B) \ 91do { \ 92 R[0] = (A[0] > B[0]) ? A[0] : B[0]; \ 93 R[1] = (A[1] > B[1]) ? A[1] : B[1]; \ 94 R[2] = (A[2] > B[2]) ? A[2] : B[2]; \ 95 R[3] = (A[3] > B[3]) ? A[3] : B[3]; \ 96} while (0) 97 98 99 100static void 101logicop_quad(struct quad_stage *qs, struct quad_header *quad) 102{ 103 struct softpipe_context *softpipe = qs->softpipe; 104 float dest[4][QUAD_SIZE]; 105 ubyte src[4][4], dst[4][4], res[4][4]; 106 uint *src4 = (uint *) src; 107 uint *dst4 = (uint *) dst; 108 uint *res4 = (uint *) res; 109 struct softpipe_cached_tile * 110 tile = sp_get_cached_tile(softpipe, 111 softpipe->cbuf_cache[softpipe->current_cbuf], 112 quad->x0, quad->y0); 113 float (*quadColor)[4] = quad->outputs.color; 114 uint i, j; 115 116 /* get/swizzle dest colors */ 117 for (j = 0; j < QUAD_SIZE; j++) { 118 int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); 119 int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); 120 for (i = 0; i < 4; i++) { 121 dest[i][j] = tile->data.color[y][x][i]; 122 } 123 } 124 125 /* convert to ubyte */ 126 for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */ 127 UNCLAMPED_FLOAT_TO_UBYTE(dst[j][0], dest[j][0]); /* P0 */ 128 UNCLAMPED_FLOAT_TO_UBYTE(dst[j][1], dest[j][1]); /* P1 */ 129 UNCLAMPED_FLOAT_TO_UBYTE(dst[j][2], dest[j][2]); /* P2 */ 130 UNCLAMPED_FLOAT_TO_UBYTE(dst[j][3], dest[j][3]); /* P3 */ 131 132 UNCLAMPED_FLOAT_TO_UBYTE(src[j][0], quadColor[j][0]); /* P0 */ 133 UNCLAMPED_FLOAT_TO_UBYTE(src[j][1], quadColor[j][1]); /* P1 */ 134 UNCLAMPED_FLOAT_TO_UBYTE(src[j][2], quadColor[j][2]); /* P2 */ 135 UNCLAMPED_FLOAT_TO_UBYTE(src[j][3], quadColor[j][3]); /* P3 */ 136 } 137 138 switch (softpipe->blend->logicop_func) { 139 case PIPE_LOGICOP_CLEAR: 140 for (j = 0; j < 4; j++) 141 res4[j] = 0; 142 break; 143 case PIPE_LOGICOP_NOR: 144 for (j = 0; j < 4; j++) 145 res4[j] = ~(src4[j] | dst4[j]); 146 break; 147 case PIPE_LOGICOP_AND_INVERTED: 148 for (j = 0; j < 4; j++) 149 res4[j] = ~src4[j] & dst4[j]; 150 break; 151 case PIPE_LOGICOP_COPY_INVERTED: 152 for (j = 0; j < 4; j++) 153 res4[j] = ~src4[j]; 154 break; 155 case PIPE_LOGICOP_AND_REVERSE: 156 for (j = 0; j < 4; j++) 157 res4[j] = src4[j] & ~dst4[j]; 158 break; 159 case PIPE_LOGICOP_INVERT: 160 for (j = 0; j < 4; j++) 161 res4[j] = ~dst4[j]; 162 break; 163 case PIPE_LOGICOP_XOR: 164 for (j = 0; j < 4; j++) 165 res4[j] = dst4[j] ^ src4[j]; 166 break; 167 case PIPE_LOGICOP_NAND: 168 for (j = 0; j < 4; j++) 169 res4[j] = ~(src4[j] & dst4[j]); 170 break; 171 case PIPE_LOGICOP_AND: 172 for (j = 0; j < 4; j++) 173 res4[j] = src4[j] & dst4[j]; 174 break; 175 case PIPE_LOGICOP_EQUIV: 176 for (j = 0; j < 4; j++) 177 res4[j] = ~(src4[j] ^ dst4[j]); 178 break; 179 case PIPE_LOGICOP_NOOP: 180 for (j = 0; j < 4; j++) 181 res4[j] = dst4[j]; 182 break; 183 case PIPE_LOGICOP_OR_INVERTED: 184 for (j = 0; j < 4; j++) 185 res4[j] = ~src4[j] | dst4[j]; 186 break; 187 case PIPE_LOGICOP_COPY: 188 for (j = 0; j < 4; j++) 189 res4[j] = src4[j]; 190 break; 191 case PIPE_LOGICOP_OR_REVERSE: 192 for (j = 0; j < 4; j++) 193 res4[j] = src4[j] | ~dst4[j]; 194 break; 195 case PIPE_LOGICOP_OR: 196 for (j = 0; j < 4; j++) 197 res4[j] = src4[j] | dst4[j]; 198 break; 199 case PIPE_LOGICOP_SET: 200 for (j = 0; j < 4; j++) 201 res4[j] = ~0; 202 break; 203 default: 204 assert(0); 205 } 206 207 for (j = 0; j < 4; j++) { 208 quadColor[j][0] = UBYTE_TO_FLOAT(res[j][0]); 209 quadColor[j][1] = UBYTE_TO_FLOAT(res[j][1]); 210 quadColor[j][2] = UBYTE_TO_FLOAT(res[j][2]); 211 quadColor[j][3] = UBYTE_TO_FLOAT(res[j][3]); 212 } 213 214 /* pass quad to next stage */ 215 qs->next->run(qs->next, quad); 216} 217 218 219 220 221static void 222blend_quad(struct quad_stage *qs, struct quad_header *quad) 223{ 224 struct softpipe_context *softpipe = qs->softpipe; 225 static const float zero[4] = { 0, 0, 0, 0 }; 226 static const float one[4] = { 1, 1, 1, 1 }; 227 float source[4][QUAD_SIZE], dest[4][QUAD_SIZE]; 228 struct softpipe_cached_tile *tile 229 = sp_get_cached_tile(softpipe, 230 softpipe->cbuf_cache[softpipe->current_cbuf], 231 quad->x0, quad->y0); 232 float (*quadColor)[4] = quad->outputs.color; 233 uint i, j; 234 235 if (softpipe->blend->logicop_enable) { 236 logicop_quad(qs, quad); 237 return; 238 } 239 240 /* get/swizzle dest colors */ 241 for (j = 0; j < QUAD_SIZE; j++) { 242 int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); 243 int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); 244 for (i = 0; i < 4; i++) { 245 dest[i][j] = tile->data.color[y][x][i]; 246 } 247 } 248 249 /* 250 * Compute src/first term RGB 251 */ 252 switch (softpipe->blend->rgb_src_factor) { 253 case PIPE_BLENDFACTOR_ONE: 254 VEC4_COPY(source[0], quadColor[0]); /* R */ 255 VEC4_COPY(source[1], quadColor[1]); /* G */ 256 VEC4_COPY(source[2], quadColor[2]); /* B */ 257 break; 258 case PIPE_BLENDFACTOR_SRC_COLOR: 259 VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */ 260 VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */ 261 VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */ 262 break; 263 case PIPE_BLENDFACTOR_SRC_ALPHA: 264 { 265 const float *alpha = quadColor[3]; 266 VEC4_MUL(source[0], quadColor[0], alpha); /* R */ 267 VEC4_MUL(source[1], quadColor[1], alpha); /* G */ 268 VEC4_MUL(source[2], quadColor[2], alpha); /* B */ 269 } 270 break; 271 case PIPE_BLENDFACTOR_DST_COLOR: 272 VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */ 273 VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */ 274 VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ 275 break; 276 case PIPE_BLENDFACTOR_DST_ALPHA: 277 { 278 const float *alpha = dest[3]; 279 VEC4_MUL(source[0], quadColor[0], alpha); /* R */ 280 VEC4_MUL(source[1], quadColor[1], alpha); /* G */ 281 VEC4_MUL(source[2], quadColor[2], alpha); /* B */ 282 } 283 break; 284 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 285 { 286 const float *alpha = quadColor[3]; 287 float diff[4]; 288 VEC4_SUB(diff, one, dest[3]); 289 VEC4_MIN(source[0], alpha, diff); /* R */ 290 VEC4_MIN(source[1], alpha, diff); /* G */ 291 VEC4_MIN(source[2], alpha, diff); /* B */ 292 } 293 break; 294 case PIPE_BLENDFACTOR_CONST_COLOR: 295 { 296 float comp[4]; 297 VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ 298 VEC4_MUL(source[0], quadColor[0], comp); /* R */ 299 VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ 300 VEC4_MUL(source[1], quadColor[1], comp); /* G */ 301 VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ 302 VEC4_MUL(source[2], quadColor[2], comp); /* B */ 303 } 304 break; 305 case PIPE_BLENDFACTOR_CONST_ALPHA: 306 { 307 float alpha[4]; 308 VEC4_SCALAR(alpha, softpipe->blend_color.color[3]); 309 VEC4_MUL(source[0], quadColor[0], alpha); /* R */ 310 VEC4_MUL(source[1], quadColor[1], alpha); /* G */ 311 VEC4_MUL(source[2], quadColor[2], alpha); /* B */ 312 } 313 break; 314 case PIPE_BLENDFACTOR_SRC1_COLOR: 315 assert(0); /* to do */ 316 break; 317 case PIPE_BLENDFACTOR_SRC1_ALPHA: 318 assert(0); /* to do */ 319 break; 320 case PIPE_BLENDFACTOR_ZERO: 321 VEC4_COPY(source[0], zero); /* R */ 322 VEC4_COPY(source[1], zero); /* G */ 323 VEC4_COPY(source[2], zero); /* B */ 324 break; 325 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 326 { 327 float inv_comp[4]; 328 VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ 329 VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ 330 VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ 331 VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ 332 VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ 333 VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ 334 } 335 break; 336 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 337 { 338 float inv_alpha[4]; 339 VEC4_SUB(inv_alpha, one, quadColor[3]); 340 VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ 341 VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ 342 VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ 343 } 344 break; 345 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 346 { 347 float inv_alpha[4]; 348 VEC4_SUB(inv_alpha, one, dest[3]); 349 VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ 350 VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ 351 VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ 352 } 353 break; 354 case PIPE_BLENDFACTOR_INV_DST_COLOR: 355 { 356 float inv_comp[4]; 357 VEC4_SUB(inv_comp, one, dest[0]); /* R */ 358 VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ 359 VEC4_SUB(inv_comp, one, dest[1]); /* G */ 360 VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ 361 VEC4_SUB(inv_comp, one, dest[2]); /* B */ 362 VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ 363 } 364 break; 365 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 366 { 367 float inv_comp[4]; 368 /* R */ 369 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); 370 VEC4_MUL(source[0], quadColor[0], inv_comp); 371 /* G */ 372 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); 373 VEC4_MUL(source[1], quadColor[1], inv_comp); 374 /* B */ 375 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); 376 VEC4_MUL(source[2], quadColor[2], inv_comp); 377 } 378 break; 379 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 380 { 381 float inv_alpha[4]; 382 VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]); 383 VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ 384 VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ 385 VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ 386 } 387 break; 388 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 389 assert(0); /* to do */ 390 break; 391 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: 392 assert(0); /* to do */ 393 break; 394 default: 395 abort(); 396 } 397 398 /* 399 * Compute src/first term A 400 */ 401 switch (softpipe->blend->alpha_src_factor) { 402 case PIPE_BLENDFACTOR_ONE: 403 VEC4_COPY(source[3], quadColor[3]); /* A */ 404 break; 405 case PIPE_BLENDFACTOR_SRC_COLOR: 406 /* fall-through */ 407 case PIPE_BLENDFACTOR_SRC_ALPHA: 408 { 409 const float *alpha = quadColor[3]; 410 VEC4_MUL(source[3], quadColor[3], alpha); /* A */ 411 } 412 break; 413 case PIPE_BLENDFACTOR_DST_COLOR: 414 /* fall-through */ 415 case PIPE_BLENDFACTOR_DST_ALPHA: 416 VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ 417 break; 418 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 419 { 420 const float *alpha = quadColor[3]; 421 float diff[4]; 422 VEC4_SUB(diff, one, dest[3]); 423 VEC4_MIN(source[3], alpha, diff); /* A */ 424 } 425 break; 426 case PIPE_BLENDFACTOR_CONST_COLOR: 427 /* fall-through */ 428 case PIPE_BLENDFACTOR_CONST_ALPHA: 429 { 430 float comp[4]; 431 VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ 432 VEC4_MUL(source[3], quadColor[3], comp); /* A */ 433 } 434 break; 435 case PIPE_BLENDFACTOR_ZERO: 436 VEC4_COPY(source[3], zero); /* A */ 437 break; 438 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 439 /* fall-through */ 440 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 441 { 442 float inv_alpha[4]; 443 VEC4_SUB(inv_alpha, one, quadColor[3]); 444 VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ 445 } 446 break; 447 case PIPE_BLENDFACTOR_INV_DST_COLOR: 448 /* fall-through */ 449 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 450 { 451 float inv_alpha[4]; 452 VEC4_SUB(inv_alpha, one, dest[3]); 453 VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ 454 } 455 break; 456 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 457 /* fall-through */ 458 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 459 { 460 float inv_comp[4]; 461 /* A */ 462 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); 463 VEC4_MUL(source[3], quadColor[3], inv_comp); 464 } 465 break; 466 default: 467 abort(); 468 } 469 470 471 /* 472 * Compute dest/second term RGB 473 */ 474 switch (softpipe->blend->rgb_dst_factor) { 475 case PIPE_BLENDFACTOR_ONE: 476 /* dest = dest * 1 NO-OP, leave dest as-is */ 477 break; 478 case PIPE_BLENDFACTOR_SRC_COLOR: 479 VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */ 480 VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */ 481 VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */ 482 break; 483 case PIPE_BLENDFACTOR_SRC_ALPHA: 484 VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */ 485 VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */ 486 VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ 487 break; 488 case PIPE_BLENDFACTOR_DST_ALPHA: 489 VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ 490 VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ 491 VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ 492 break; 493 case PIPE_BLENDFACTOR_DST_COLOR: 494 VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ 495 VEC4_MUL(dest[1], dest[1], dest[1]); /* G */ 496 VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ 497 break; 498 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 499 assert(0); /* illegal */ 500 break; 501 case PIPE_BLENDFACTOR_CONST_COLOR: 502 { 503 float comp[4]; 504 VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ 505 VEC4_MUL(dest[0], dest[0], comp); /* R */ 506 VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ 507 VEC4_MUL(dest[1], dest[1], comp); /* G */ 508 VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ 509 VEC4_MUL(dest[2], dest[2], comp); /* B */ 510 } 511 break; 512 case PIPE_BLENDFACTOR_CONST_ALPHA: 513 { 514 float comp[4]; 515 VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ 516 VEC4_MUL(dest[0], dest[0], comp); /* R */ 517 VEC4_MUL(dest[1], dest[1], comp); /* G */ 518 VEC4_MUL(dest[2], dest[2], comp); /* B */ 519 } 520 break; 521 case PIPE_BLENDFACTOR_ZERO: 522 VEC4_COPY(dest[0], zero); /* R */ 523 VEC4_COPY(dest[1], zero); /* G */ 524 VEC4_COPY(dest[2], zero); /* B */ 525 break; 526 case PIPE_BLENDFACTOR_SRC1_COLOR: 527 case PIPE_BLENDFACTOR_SRC1_ALPHA: 528 /* XXX what are these? */ 529 assert(0); 530 break; 531 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 532 { 533 float inv_comp[4]; 534 VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ 535 VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ 536 VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ 537 VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ 538 VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ 539 VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ 540 } 541 break; 542 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 543 { 544 float one_minus_alpha[QUAD_SIZE]; 545 VEC4_SUB(one_minus_alpha, one, quadColor[3]); 546 VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ 547 VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ 548 VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ 549 } 550 break; 551 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 552 { 553 float inv_comp[4]; 554 VEC4_SUB(inv_comp, one, quadColor[3]); /* A */ 555 VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ 556 VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ 557 VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ 558 } 559 break; 560 case PIPE_BLENDFACTOR_INV_DST_COLOR: 561 { 562 float inv_comp[4]; 563 VEC4_SUB(inv_comp, one, dest[0]); /* R */ 564 VEC4_MUL(dest[0], dest[0], inv_comp); /* R */ 565 VEC4_SUB(inv_comp, one, dest[1]); /* G */ 566 VEC4_MUL(dest[1], dest[1], inv_comp); /* G */ 567 VEC4_SUB(inv_comp, one, dest[2]); /* B */ 568 VEC4_MUL(dest[2], dest[2], inv_comp); /* B */ 569 } 570 break; 571 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 572 { 573 float inv_comp[4]; 574 /* R */ 575 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); 576 VEC4_MUL(dest[0], dest[0], inv_comp); 577 /* G */ 578 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); 579 VEC4_MUL(dest[1], dest[1], inv_comp); 580 /* B */ 581 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); 582 VEC4_MUL(dest[2], dest[2], inv_comp); 583 } 584 break; 585 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 586 { 587 float inv_comp[4]; 588 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); 589 VEC4_MUL(dest[0], dest[0], inv_comp); 590 VEC4_MUL(dest[1], dest[1], inv_comp); 591 VEC4_MUL(dest[2], dest[2], inv_comp); 592 } 593 break; 594 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 595 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: 596 /* XXX what are these? */ 597 assert(0); 598 break; 599 default: 600 assert(0); 601 } 602 603 /* 604 * Compute dest/second term A 605 */ 606 switch (softpipe->blend->alpha_dst_factor) { 607 case PIPE_BLENDFACTOR_ONE: 608 /* dest = dest * 1 NO-OP, leave dest as-is */ 609 break; 610 case PIPE_BLENDFACTOR_SRC_COLOR: 611 /* fall-through */ 612 case PIPE_BLENDFACTOR_SRC_ALPHA: 613 VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */ 614 break; 615 case PIPE_BLENDFACTOR_DST_COLOR: 616 /* fall-through */ 617 case PIPE_BLENDFACTOR_DST_ALPHA: 618 VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ 619 break; 620 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 621 assert(0); /* illegal */ 622 break; 623 case PIPE_BLENDFACTOR_CONST_COLOR: 624 /* fall-through */ 625 case PIPE_BLENDFACTOR_CONST_ALPHA: 626 { 627 float comp[4]; 628 VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ 629 VEC4_MUL(dest[3], dest[3], comp); /* A */ 630 } 631 break; 632 case PIPE_BLENDFACTOR_ZERO: 633 VEC4_COPY(dest[3], zero); /* A */ 634 break; 635 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 636 /* fall-through */ 637 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 638 { 639 float one_minus_alpha[QUAD_SIZE]; 640 VEC4_SUB(one_minus_alpha, one, quadColor[3]); 641 VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */ 642 } 643 break; 644 case PIPE_BLENDFACTOR_INV_DST_COLOR: 645 /* fall-through */ 646 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 647 { 648 float inv_comp[4]; 649 VEC4_SUB(inv_comp, one, dest[3]); /* A */ 650 VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ 651 } 652 break; 653 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 654 /* fall-through */ 655 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 656 { 657 float inv_comp[4]; 658 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); 659 VEC4_MUL(dest[3], dest[3], inv_comp); 660 } 661 break; 662 default: 663 assert(0); 664 } 665 666 /* 667 * Combine RGB terms 668 */ 669 switch (softpipe->blend->rgb_func) { 670 case PIPE_BLEND_ADD: 671 VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */ 672 VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */ 673 VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */ 674 break; 675 case PIPE_BLEND_SUBTRACT: 676 VEC4_SUB(quadColor[0], source[0], dest[0]); /* R */ 677 VEC4_SUB(quadColor[1], source[1], dest[1]); /* G */ 678 VEC4_SUB(quadColor[2], source[2], dest[2]); /* B */ 679 break; 680 case PIPE_BLEND_REVERSE_SUBTRACT: 681 VEC4_SUB(quadColor[0], dest[0], source[0]); /* R */ 682 VEC4_SUB(quadColor[1], dest[1], source[1]); /* G */ 683 VEC4_SUB(quadColor[2], dest[2], source[2]); /* B */ 684 break; 685 case PIPE_BLEND_MIN: 686 VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */ 687 VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */ 688 VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */ 689 break; 690 case PIPE_BLEND_MAX: 691 VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */ 692 VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */ 693 VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */ 694 break; 695 default: 696 assert(0); 697 } 698 699 /* 700 * Combine A terms 701 */ 702 switch (softpipe->blend->alpha_func) { 703 case PIPE_BLEND_ADD: 704 VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */ 705 break; 706 case PIPE_BLEND_SUBTRACT: 707 VEC4_SUB(quadColor[3], source[3], dest[3]); /* A */ 708 break; 709 case PIPE_BLEND_REVERSE_SUBTRACT: 710 VEC4_SUB(quadColor[3], dest[3], source[3]); /* A */ 711 break; 712 case PIPE_BLEND_MIN: 713 VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */ 714 break; 715 case PIPE_BLEND_MAX: 716 VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */ 717 break; 718 default: 719 abort(); 720 } 721 722 /* pass blended quad to next stage */ 723 qs->next->run(qs->next, quad); 724} 725 726 727static void blend_begin(struct quad_stage *qs) 728{ 729 qs->next->begin(qs->next); 730} 731 732 733static void blend_destroy(struct quad_stage *qs) 734{ 735 FREE( qs ); 736} 737 738 739struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe ) 740{ 741 struct quad_stage *stage = CALLOC_STRUCT(quad_stage); 742 743 stage->softpipe = softpipe; 744 stage->begin = blend_begin; 745 stage->run = blend_quad; 746 stage->destroy = blend_destroy; 747 748 return stage; 749} 750