00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00033 #include "pipe/p_defines.h"
00034 #include "util/u_math.h"
00035 #include "util/u_memory.h"
00036 #include "sp_context.h"
00037 #include "sp_headers.h"
00038 #include "sp_surface.h"
00039 #include "sp_tile_cache.h"
00040 #include "sp_quad.h"
00041
00042
00043 #define VEC4_COPY(DST, SRC) \
00044 do { \
00045 DST[0] = SRC[0]; \
00046 DST[1] = SRC[1]; \
00047 DST[2] = SRC[2]; \
00048 DST[3] = SRC[3]; \
00049 } while(0)
00050
00051 #define VEC4_SCALAR(DST, SRC) \
00052 do { \
00053 DST[0] = SRC; \
00054 DST[1] = SRC; \
00055 DST[2] = SRC; \
00056 DST[3] = SRC; \
00057 } while(0)
00058
00059 #define VEC4_ADD(R, A, B) \
00060 do { \
00061 R[0] = A[0] + B[0]; \
00062 R[1] = A[1] + B[1]; \
00063 R[2] = A[2] + B[2]; \
00064 R[3] = A[3] + B[3]; \
00065 } while (0)
00066
00067 #define VEC4_SUB(R, A, B) \
00068 do { \
00069 R[0] = A[0] - B[0]; \
00070 R[1] = A[1] - B[1]; \
00071 R[2] = A[2] - B[2]; \
00072 R[3] = A[3] - B[3]; \
00073 } while (0)
00074
00075 #define VEC4_MUL(R, A, B) \
00076 do { \
00077 R[0] = A[0] * B[0]; \
00078 R[1] = A[1] * B[1]; \
00079 R[2] = A[2] * B[2]; \
00080 R[3] = A[3] * B[3]; \
00081 } while (0)
00082
00083 #define VEC4_MIN(R, A, B) \
00084 do { \
00085 R[0] = (A[0] < B[0]) ? A[0] : B[0]; \
00086 R[1] = (A[1] < B[1]) ? A[1] : B[1]; \
00087 R[2] = (A[2] < B[2]) ? A[2] : B[2]; \
00088 R[3] = (A[3] < B[3]) ? A[3] : B[3]; \
00089 } while (0)
00090
00091 #define VEC4_MAX(R, A, B) \
00092 do { \
00093 R[0] = (A[0] > B[0]) ? A[0] : B[0]; \
00094 R[1] = (A[1] > B[1]) ? A[1] : B[1]; \
00095 R[2] = (A[2] > B[2]) ? A[2] : B[2]; \
00096 R[3] = (A[3] > B[3]) ? A[3] : B[3]; \
00097 } while (0)
00098
00099
00100
00101 static void
00102 logicop_quad(struct quad_stage *qs, struct quad_header *quad)
00103 {
00104 struct softpipe_context *softpipe = qs->softpipe;
00105 uint cbuf;
00106
00107
00108 for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
00109 float dest[4][QUAD_SIZE];
00110 ubyte src[4][4], dst[4][4], res[4][4];
00111 uint *src4 = (uint *) src;
00112 uint *dst4 = (uint *) dst;
00113 uint *res4 = (uint *) res;
00114 struct softpipe_cached_tile *
00115 tile = sp_get_cached_tile(softpipe,
00116 softpipe->cbuf_cache[cbuf],
00117 quad->input.x0, quad->input.y0);
00118 float (*quadColor)[4] = quad->output.color[cbuf];
00119 uint i, j;
00120
00121
00122 for (j = 0; j < QUAD_SIZE; j++) {
00123 int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
00124 int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
00125 for (i = 0; i < 4; i++) {
00126 dest[i][j] = tile->data.color[y][x][i];
00127 }
00128 }
00129
00130
00131 for (j = 0; j < 4; j++) {
00132 dst[j][0] = float_to_ubyte(dest[j][0]);
00133 dst[j][1] = float_to_ubyte(dest[j][1]);
00134 dst[j][2] = float_to_ubyte(dest[j][2]);
00135 dst[j][3] = float_to_ubyte(dest[j][3]);
00136
00137 src[j][0] = float_to_ubyte(quadColor[j][0]);
00138 src[j][1] = float_to_ubyte(quadColor[j][1]);
00139 src[j][2] = float_to_ubyte(quadColor[j][2]);
00140 src[j][3] = float_to_ubyte(quadColor[j][3]);
00141 }
00142
00143 switch (softpipe->blend->logicop_func) {
00144 case PIPE_LOGICOP_CLEAR:
00145 for (j = 0; j < 4; j++)
00146 res4[j] = 0;
00147 break;
00148 case PIPE_LOGICOP_NOR:
00149 for (j = 0; j < 4; j++)
00150 res4[j] = ~(src4[j] | dst4[j]);
00151 break;
00152 case PIPE_LOGICOP_AND_INVERTED:
00153 for (j = 0; j < 4; j++)
00154 res4[j] = ~src4[j] & dst4[j];
00155 break;
00156 case PIPE_LOGICOP_COPY_INVERTED:
00157 for (j = 0; j < 4; j++)
00158 res4[j] = ~src4[j];
00159 break;
00160 case PIPE_LOGICOP_AND_REVERSE:
00161 for (j = 0; j < 4; j++)
00162 res4[j] = src4[j] & ~dst4[j];
00163 break;
00164 case PIPE_LOGICOP_INVERT:
00165 for (j = 0; j < 4; j++)
00166 res4[j] = ~dst4[j];
00167 break;
00168 case PIPE_LOGICOP_XOR:
00169 for (j = 0; j < 4; j++)
00170 res4[j] = dst4[j] ^ src4[j];
00171 break;
00172 case PIPE_LOGICOP_NAND:
00173 for (j = 0; j < 4; j++)
00174 res4[j] = ~(src4[j] & dst4[j]);
00175 break;
00176 case PIPE_LOGICOP_AND:
00177 for (j = 0; j < 4; j++)
00178 res4[j] = src4[j] & dst4[j];
00179 break;
00180 case PIPE_LOGICOP_EQUIV:
00181 for (j = 0; j < 4; j++)
00182 res4[j] = ~(src4[j] ^ dst4[j]);
00183 break;
00184 case PIPE_LOGICOP_NOOP:
00185 for (j = 0; j < 4; j++)
00186 res4[j] = dst4[j];
00187 break;
00188 case PIPE_LOGICOP_OR_INVERTED:
00189 for (j = 0; j < 4; j++)
00190 res4[j] = ~src4[j] | dst4[j];
00191 break;
00192 case PIPE_LOGICOP_COPY:
00193 for (j = 0; j < 4; j++)
00194 res4[j] = src4[j];
00195 break;
00196 case PIPE_LOGICOP_OR_REVERSE:
00197 for (j = 0; j < 4; j++)
00198 res4[j] = src4[j] | ~dst4[j];
00199 break;
00200 case PIPE_LOGICOP_OR:
00201 for (j = 0; j < 4; j++)
00202 res4[j] = src4[j] | dst4[j];
00203 break;
00204 case PIPE_LOGICOP_SET:
00205 for (j = 0; j < 4; j++)
00206 res4[j] = ~0;
00207 break;
00208 default:
00209 assert(0);
00210 }
00211
00212 for (j = 0; j < 4; j++) {
00213 quadColor[j][0] = ubyte_to_float(res[j][0]);
00214 quadColor[j][1] = ubyte_to_float(res[j][1]);
00215 quadColor[j][2] = ubyte_to_float(res[j][2]);
00216 quadColor[j][3] = ubyte_to_float(res[j][3]);
00217 }
00218 }
00219
00220
00221 qs->next->run(qs->next, quad);
00222 }
00223
00224
00225
00226
00227 static void
00228 blend_quad(struct quad_stage *qs, struct quad_header *quad)
00229 {
00230 static const float zero[4] = { 0, 0, 0, 0 };
00231 static const float one[4] = { 1, 1, 1, 1 };
00232
00233 struct softpipe_context *softpipe = qs->softpipe;
00234 uint cbuf;
00235
00236 if (softpipe->blend->logicop_enable) {
00237 logicop_quad(qs, quad);
00238 return;
00239 }
00240
00241
00242 for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
00243 float source[4][QUAD_SIZE], dest[4][QUAD_SIZE];
00244 struct softpipe_cached_tile *tile
00245 = sp_get_cached_tile(softpipe,
00246 softpipe->cbuf_cache[cbuf],
00247 quad->input.x0, quad->input.y0);
00248 float (*quadColor)[4] = quad->output.color[cbuf];
00249 uint i, j;
00250
00251
00252 for (j = 0; j < QUAD_SIZE; j++) {
00253 int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
00254 int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
00255 for (i = 0; i < 4; i++) {
00256 dest[i][j] = tile->data.color[y][x][i];
00257 }
00258 }
00259
00260
00261
00262
00263 switch (softpipe->blend->rgb_src_factor) {
00264 case PIPE_BLENDFACTOR_ONE:
00265 VEC4_COPY(source[0], quadColor[0]);
00266 VEC4_COPY(source[1], quadColor[1]);
00267 VEC4_COPY(source[2], quadColor[2]);
00268 break;
00269 case PIPE_BLENDFACTOR_SRC_COLOR:
00270 VEC4_MUL(source[0], quadColor[0], quadColor[0]);
00271 VEC4_MUL(source[1], quadColor[1], quadColor[1]);
00272 VEC4_MUL(source[2], quadColor[2], quadColor[2]);
00273 break;
00274 case PIPE_BLENDFACTOR_SRC_ALPHA:
00275 {
00276 const float *alpha = quadColor[3];
00277 VEC4_MUL(source[0], quadColor[0], alpha);
00278 VEC4_MUL(source[1], quadColor[1], alpha);
00279 VEC4_MUL(source[2], quadColor[2], alpha);
00280 }
00281 break;
00282 case PIPE_BLENDFACTOR_DST_COLOR:
00283 VEC4_MUL(source[0], quadColor[0], dest[0]);
00284 VEC4_MUL(source[1], quadColor[1], dest[1]);
00285 VEC4_MUL(source[2], quadColor[2], dest[2]);
00286 break;
00287 case PIPE_BLENDFACTOR_DST_ALPHA:
00288 {
00289 const float *alpha = dest[3];
00290 VEC4_MUL(source[0], quadColor[0], alpha);
00291 VEC4_MUL(source[1], quadColor[1], alpha);
00292 VEC4_MUL(source[2], quadColor[2], alpha);
00293 }
00294 break;
00295 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
00296 {
00297 const float *alpha = quadColor[3];
00298 float diff[4], temp[4];
00299 VEC4_SUB(diff, one, dest[3]);
00300 VEC4_MIN(temp, alpha, diff);
00301 VEC4_MUL(source[0], quadColor[0], temp);
00302 VEC4_MUL(source[1], quadColor[1], temp);
00303 VEC4_MUL(source[2], quadColor[2], temp);
00304 }
00305 break;
00306 case PIPE_BLENDFACTOR_CONST_COLOR:
00307 {
00308 float comp[4];
00309 VEC4_SCALAR(comp, softpipe->blend_color.color[0]);
00310 VEC4_MUL(source[0], quadColor[0], comp);
00311 VEC4_SCALAR(comp, softpipe->blend_color.color[1]);
00312 VEC4_MUL(source[1], quadColor[1], comp);
00313 VEC4_SCALAR(comp, softpipe->blend_color.color[2]);
00314 VEC4_MUL(source[2], quadColor[2], comp);
00315 }
00316 break;
00317 case PIPE_BLENDFACTOR_CONST_ALPHA:
00318 {
00319 float alpha[4];
00320 VEC4_SCALAR(alpha, softpipe->blend_color.color[3]);
00321 VEC4_MUL(source[0], quadColor[0], alpha);
00322 VEC4_MUL(source[1], quadColor[1], alpha);
00323 VEC4_MUL(source[2], quadColor[2], alpha);
00324 }
00325 break;
00326 case PIPE_BLENDFACTOR_SRC1_COLOR:
00327 assert(0);
00328 break;
00329 case PIPE_BLENDFACTOR_SRC1_ALPHA:
00330 assert(0);
00331 break;
00332 case PIPE_BLENDFACTOR_ZERO:
00333 VEC4_COPY(source[0], zero);
00334 VEC4_COPY(source[1], zero);
00335 VEC4_COPY(source[2], zero);
00336 break;
00337 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
00338 {
00339 float inv_comp[4];
00340 VEC4_SUB(inv_comp, one, quadColor[0]);
00341 VEC4_MUL(source[0], quadColor[0], inv_comp);
00342 VEC4_SUB(inv_comp, one, quadColor[1]);
00343 VEC4_MUL(source[1], quadColor[1], inv_comp);
00344 VEC4_SUB(inv_comp, one, quadColor[2]);
00345 VEC4_MUL(source[2], quadColor[2], inv_comp);
00346 }
00347 break;
00348 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
00349 {
00350 float inv_alpha[4];
00351 VEC4_SUB(inv_alpha, one, quadColor[3]);
00352 VEC4_MUL(source[0], quadColor[0], inv_alpha);
00353 VEC4_MUL(source[1], quadColor[1], inv_alpha);
00354 VEC4_MUL(source[2], quadColor[2], inv_alpha);
00355 }
00356 break;
00357 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
00358 {
00359 float inv_alpha[4];
00360 VEC4_SUB(inv_alpha, one, dest[3]);
00361 VEC4_MUL(source[0], quadColor[0], inv_alpha);
00362 VEC4_MUL(source[1], quadColor[1], inv_alpha);
00363 VEC4_MUL(source[2], quadColor[2], inv_alpha);
00364 }
00365 break;
00366 case PIPE_BLENDFACTOR_INV_DST_COLOR:
00367 {
00368 float inv_comp[4];
00369 VEC4_SUB(inv_comp, one, dest[0]);
00370 VEC4_MUL(source[0], quadColor[0], inv_comp);
00371 VEC4_SUB(inv_comp, one, dest[1]);
00372 VEC4_MUL(source[1], quadColor[1], inv_comp);
00373 VEC4_SUB(inv_comp, one, dest[2]);
00374 VEC4_MUL(source[2], quadColor[2], inv_comp);
00375 }
00376 break;
00377 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
00378 {
00379 float inv_comp[4];
00380
00381 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
00382 VEC4_MUL(source[0], quadColor[0], inv_comp);
00383
00384 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
00385 VEC4_MUL(source[1], quadColor[1], inv_comp);
00386
00387 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
00388 VEC4_MUL(source[2], quadColor[2], inv_comp);
00389 }
00390 break;
00391 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
00392 {
00393 float inv_alpha[4];
00394 VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]);
00395 VEC4_MUL(source[0], quadColor[0], inv_alpha);
00396 VEC4_MUL(source[1], quadColor[1], inv_alpha);
00397 VEC4_MUL(source[2], quadColor[2], inv_alpha);
00398 }
00399 break;
00400 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
00401 assert(0);
00402 break;
00403 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
00404 assert(0);
00405 break;
00406 default:
00407 assert(0);
00408 }
00409
00410
00411
00412
00413 switch (softpipe->blend->alpha_src_factor) {
00414 case PIPE_BLENDFACTOR_ONE:
00415 VEC4_COPY(source[3], quadColor[3]);
00416 break;
00417 case PIPE_BLENDFACTOR_SRC_COLOR:
00418
00419 case PIPE_BLENDFACTOR_SRC_ALPHA:
00420 {
00421 const float *alpha = quadColor[3];
00422 VEC4_MUL(source[3], quadColor[3], alpha);
00423 }
00424 break;
00425 case PIPE_BLENDFACTOR_DST_COLOR:
00426
00427 case PIPE_BLENDFACTOR_DST_ALPHA:
00428 VEC4_MUL(source[3], quadColor[3], dest[3]);
00429 break;
00430 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
00431
00432 VEC4_COPY(source[3], quadColor[3]);
00433 break;
00434 case PIPE_BLENDFACTOR_CONST_COLOR:
00435
00436 case PIPE_BLENDFACTOR_CONST_ALPHA:
00437 {
00438 float comp[4];
00439 VEC4_SCALAR(comp, softpipe->blend_color.color[3]);
00440 VEC4_MUL(source[3], quadColor[3], comp);
00441 }
00442 break;
00443 case PIPE_BLENDFACTOR_ZERO:
00444 VEC4_COPY(source[3], zero);
00445 break;
00446 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
00447
00448 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
00449 {
00450 float inv_alpha[4];
00451 VEC4_SUB(inv_alpha, one, quadColor[3]);
00452 VEC4_MUL(source[3], quadColor[3], inv_alpha);
00453 }
00454 break;
00455 case PIPE_BLENDFACTOR_INV_DST_COLOR:
00456
00457 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
00458 {
00459 float inv_alpha[4];
00460 VEC4_SUB(inv_alpha, one, dest[3]);
00461 VEC4_MUL(source[3], quadColor[3], inv_alpha);
00462 }
00463 break;
00464 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
00465
00466 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
00467 {
00468 float inv_comp[4];
00469
00470 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
00471 VEC4_MUL(source[3], quadColor[3], inv_comp);
00472 }
00473 break;
00474 default:
00475 assert(0);
00476 }
00477
00478
00479
00480
00481
00482 switch (softpipe->blend->rgb_dst_factor) {
00483 case PIPE_BLENDFACTOR_ONE:
00484
00485 break;
00486 case PIPE_BLENDFACTOR_SRC_COLOR:
00487 VEC4_MUL(dest[0], dest[0], quadColor[0]);
00488 VEC4_MUL(dest[1], dest[1], quadColor[1]);
00489 VEC4_MUL(dest[2], dest[2], quadColor[2]);
00490 break;
00491 case PIPE_BLENDFACTOR_SRC_ALPHA:
00492 VEC4_MUL(dest[0], dest[0], quadColor[3]);
00493 VEC4_MUL(dest[1], dest[1], quadColor[3]);
00494 VEC4_MUL(dest[2], dest[2], quadColor[3]);
00495 break;
00496 case PIPE_BLENDFACTOR_DST_ALPHA:
00497 VEC4_MUL(dest[0], dest[0], dest[3]);
00498 VEC4_MUL(dest[1], dest[1], dest[3]);
00499 VEC4_MUL(dest[2], dest[2], dest[3]);
00500 break;
00501 case PIPE_BLENDFACTOR_DST_COLOR:
00502 VEC4_MUL(dest[0], dest[0], dest[0]);
00503 VEC4_MUL(dest[1], dest[1], dest[1]);
00504 VEC4_MUL(dest[2], dest[2], dest[2]);
00505 break;
00506 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
00507 assert(0);
00508 break;
00509 case PIPE_BLENDFACTOR_CONST_COLOR:
00510 {
00511 float comp[4];
00512 VEC4_SCALAR(comp, softpipe->blend_color.color[0]);
00513 VEC4_MUL(dest[0], dest[0], comp);
00514 VEC4_SCALAR(comp, softpipe->blend_color.color[1]);
00515 VEC4_MUL(dest[1], dest[1], comp);
00516 VEC4_SCALAR(comp, softpipe->blend_color.color[2]);
00517 VEC4_MUL(dest[2], dest[2], comp);
00518 }
00519 break;
00520 case PIPE_BLENDFACTOR_CONST_ALPHA:
00521 {
00522 float comp[4];
00523 VEC4_SCALAR(comp, softpipe->blend_color.color[3]);
00524 VEC4_MUL(dest[0], dest[0], comp);
00525 VEC4_MUL(dest[1], dest[1], comp);
00526 VEC4_MUL(dest[2], dest[2], comp);
00527 }
00528 break;
00529 case PIPE_BLENDFACTOR_ZERO:
00530 VEC4_COPY(dest[0], zero);
00531 VEC4_COPY(dest[1], zero);
00532 VEC4_COPY(dest[2], zero);
00533 break;
00534 case PIPE_BLENDFACTOR_SRC1_COLOR:
00535 case PIPE_BLENDFACTOR_SRC1_ALPHA:
00536
00537 assert(0);
00538 break;
00539 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
00540 {
00541 float inv_comp[4];
00542 VEC4_SUB(inv_comp, one, quadColor[0]);
00543 VEC4_MUL(dest[0], inv_comp, dest[0]);
00544 VEC4_SUB(inv_comp, one, quadColor[1]);
00545 VEC4_MUL(dest[1], inv_comp, dest[1]);
00546 VEC4_SUB(inv_comp, one, quadColor[2]);
00547 VEC4_MUL(dest[2], inv_comp, dest[2]);
00548 }
00549 break;
00550 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
00551 {
00552 float one_minus_alpha[QUAD_SIZE];
00553 VEC4_SUB(one_minus_alpha, one, quadColor[3]);
00554 VEC4_MUL(dest[0], dest[0], one_minus_alpha);
00555 VEC4_MUL(dest[1], dest[1], one_minus_alpha);
00556 VEC4_MUL(dest[2], dest[2], one_minus_alpha);
00557 }
00558 break;
00559 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
00560 {
00561 float inv_comp[4];
00562 VEC4_SUB(inv_comp, one, dest[3]);
00563 VEC4_MUL(dest[0], inv_comp, dest[0]);
00564 VEC4_MUL(dest[1], inv_comp, dest[1]);
00565 VEC4_MUL(dest[2], inv_comp, dest[2]);
00566 }
00567 break;
00568 case PIPE_BLENDFACTOR_INV_DST_COLOR:
00569 {
00570 float inv_comp[4];
00571 VEC4_SUB(inv_comp, one, dest[0]);
00572 VEC4_MUL(dest[0], dest[0], inv_comp);
00573 VEC4_SUB(inv_comp, one, dest[1]);
00574 VEC4_MUL(dest[1], dest[1], inv_comp);
00575 VEC4_SUB(inv_comp, one, dest[2]);
00576 VEC4_MUL(dest[2], dest[2], inv_comp);
00577 }
00578 break;
00579 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
00580 {
00581 float inv_comp[4];
00582
00583 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
00584 VEC4_MUL(dest[0], dest[0], inv_comp);
00585
00586 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
00587 VEC4_MUL(dest[1], dest[1], inv_comp);
00588
00589 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
00590 VEC4_MUL(dest[2], dest[2], inv_comp);
00591 }
00592 break;
00593 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
00594 {
00595 float inv_comp[4];
00596 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
00597 VEC4_MUL(dest[0], dest[0], inv_comp);
00598 VEC4_MUL(dest[1], dest[1], inv_comp);
00599 VEC4_MUL(dest[2], dest[2], inv_comp);
00600 }
00601 break;
00602 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
00603 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
00604
00605 assert(0);
00606 break;
00607 default:
00608 assert(0);
00609 }
00610
00611
00612
00613
00614 switch (softpipe->blend->alpha_dst_factor) {
00615 case PIPE_BLENDFACTOR_ONE:
00616
00617 break;
00618 case PIPE_BLENDFACTOR_SRC_COLOR:
00619
00620 case PIPE_BLENDFACTOR_SRC_ALPHA:
00621 VEC4_MUL(dest[3], dest[3], quadColor[3]);
00622 break;
00623 case PIPE_BLENDFACTOR_DST_COLOR:
00624
00625 case PIPE_BLENDFACTOR_DST_ALPHA:
00626 VEC4_MUL(dest[3], dest[3], dest[3]);
00627 break;
00628 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
00629 assert(0);
00630 break;
00631 case PIPE_BLENDFACTOR_CONST_COLOR:
00632
00633 case PIPE_BLENDFACTOR_CONST_ALPHA:
00634 {
00635 float comp[4];
00636 VEC4_SCALAR(comp, softpipe->blend_color.color[3]);
00637 VEC4_MUL(dest[3], dest[3], comp);
00638 }
00639 break;
00640 case PIPE_BLENDFACTOR_ZERO:
00641 VEC4_COPY(dest[3], zero);
00642 break;
00643 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
00644
00645 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
00646 {
00647 float one_minus_alpha[QUAD_SIZE];
00648 VEC4_SUB(one_minus_alpha, one, quadColor[3]);
00649 VEC4_MUL(dest[3], dest[3], one_minus_alpha);
00650 }
00651 break;
00652 case PIPE_BLENDFACTOR_INV_DST_COLOR:
00653
00654 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
00655 {
00656 float inv_comp[4];
00657 VEC4_SUB(inv_comp, one, dest[3]);
00658 VEC4_MUL(dest[3], inv_comp, dest[3]);
00659 }
00660 break;
00661 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
00662
00663 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
00664 {
00665 float inv_comp[4];
00666 VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
00667 VEC4_MUL(dest[3], dest[3], inv_comp);
00668 }
00669 break;
00670 default:
00671 assert(0);
00672 }
00673
00674
00675
00676
00677 switch (softpipe->blend->rgb_func) {
00678 case PIPE_BLEND_ADD:
00679 VEC4_ADD(quadColor[0], source[0], dest[0]);
00680 VEC4_ADD(quadColor[1], source[1], dest[1]);
00681 VEC4_ADD(quadColor[2], source[2], dest[2]);
00682 break;
00683 case PIPE_BLEND_SUBTRACT:
00684 VEC4_SUB(quadColor[0], source[0], dest[0]);
00685 VEC4_SUB(quadColor[1], source[1], dest[1]);
00686 VEC4_SUB(quadColor[2], source[2], dest[2]);
00687 break;
00688 case PIPE_BLEND_REVERSE_SUBTRACT:
00689 VEC4_SUB(quadColor[0], dest[0], source[0]);
00690 VEC4_SUB(quadColor[1], dest[1], source[1]);
00691 VEC4_SUB(quadColor[2], dest[2], source[2]);
00692 break;
00693 case PIPE_BLEND_MIN:
00694 VEC4_MIN(quadColor[0], source[0], dest[0]);
00695 VEC4_MIN(quadColor[1], source[1], dest[1]);
00696 VEC4_MIN(quadColor[2], source[2], dest[2]);
00697 break;
00698 case PIPE_BLEND_MAX:
00699 VEC4_MAX(quadColor[0], source[0], dest[0]);
00700 VEC4_MAX(quadColor[1], source[1], dest[1]);
00701 VEC4_MAX(quadColor[2], source[2], dest[2]);
00702 break;
00703 default:
00704 assert(0);
00705 }
00706
00707
00708
00709
00710 switch (softpipe->blend->alpha_func) {
00711 case PIPE_BLEND_ADD:
00712 VEC4_ADD(quadColor[3], source[3], dest[3]);
00713 break;
00714 case PIPE_BLEND_SUBTRACT:
00715 VEC4_SUB(quadColor[3], source[3], dest[3]);
00716 break;
00717 case PIPE_BLEND_REVERSE_SUBTRACT:
00718 VEC4_SUB(quadColor[3], dest[3], source[3]);
00719 break;
00720 case PIPE_BLEND_MIN:
00721 VEC4_MIN(quadColor[3], source[3], dest[3]);
00722 break;
00723 case PIPE_BLEND_MAX:
00724 VEC4_MAX(quadColor[3], source[3], dest[3]);
00725 break;
00726 default:
00727 assert(0);
00728 }
00729
00730 }
00731
00732
00733 qs->next->run(qs->next, quad);
00734 }
00735
00736
00737 static void blend_begin(struct quad_stage *qs)
00738 {
00739 qs->next->begin(qs->next);
00740 }
00741
00742
00743 static void blend_destroy(struct quad_stage *qs)
00744 {
00745 FREE( qs );
00746 }
00747
00748
00749 struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe )
00750 {
00751 struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
00752
00753 stage->softpipe = softpipe;
00754 stage->begin = blend_begin;
00755 stage->run = blend_quad;
00756 stage->destroy = blend_destroy;
00757
00758 return stage;
00759 }