sp_quad_blend.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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    /* loop over colorbuffer outputs */
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       /* get/swizzle dest colors */
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       /* convert to ubyte */
00131       for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
00132          dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */
00133          dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */
00134          dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */
00135          dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */
00136 
00137          src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */
00138          src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */
00139          src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */
00140          src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */
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    /* pass quad to next stage */
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    /* loop over colorbuffer outputs */
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       /* get/swizzle dest colors */
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        * Compute src/first term RGB
00262        */
00263       switch (softpipe->blend->rgb_src_factor) {
00264       case PIPE_BLENDFACTOR_ONE:
00265          VEC4_COPY(source[0], quadColor[0]); /* R */
00266          VEC4_COPY(source[1], quadColor[1]); /* G */
00267          VEC4_COPY(source[2], quadColor[2]); /* B */
00268          break;
00269       case PIPE_BLENDFACTOR_SRC_COLOR:
00270          VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */
00271          VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */
00272          VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */
00273          break;
00274       case PIPE_BLENDFACTOR_SRC_ALPHA:
00275          {
00276             const float *alpha = quadColor[3];
00277             VEC4_MUL(source[0], quadColor[0], alpha); /* R */
00278             VEC4_MUL(source[1], quadColor[1], alpha); /* G */
00279             VEC4_MUL(source[2], quadColor[2], alpha); /* B */
00280          }
00281          break;
00282       case PIPE_BLENDFACTOR_DST_COLOR:
00283          VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */
00284          VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */
00285          VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */
00286          break;
00287       case PIPE_BLENDFACTOR_DST_ALPHA:
00288          {
00289             const float *alpha = dest[3];
00290             VEC4_MUL(source[0], quadColor[0], alpha); /* R */
00291             VEC4_MUL(source[1], quadColor[1], alpha); /* G */
00292             VEC4_MUL(source[2], quadColor[2], alpha); /* B */
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); /* R */
00302             VEC4_MUL(source[1], quadColor[1], temp); /* G */
00303             VEC4_MUL(source[2], quadColor[2], temp); /* B */
00304          }
00305          break;
00306       case PIPE_BLENDFACTOR_CONST_COLOR:
00307          {
00308             float comp[4];
00309             VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
00310             VEC4_MUL(source[0], quadColor[0], comp); /* R */
00311             VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
00312             VEC4_MUL(source[1], quadColor[1], comp); /* G */
00313             VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
00314             VEC4_MUL(source[2], quadColor[2], comp); /* B */
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); /* R */
00322             VEC4_MUL(source[1], quadColor[1], alpha); /* G */
00323             VEC4_MUL(source[2], quadColor[2], alpha); /* B */
00324          }
00325          break;
00326       case PIPE_BLENDFACTOR_SRC1_COLOR:
00327          assert(0); /* to do */
00328          break;
00329       case PIPE_BLENDFACTOR_SRC1_ALPHA:
00330          assert(0); /* to do */
00331          break;
00332       case PIPE_BLENDFACTOR_ZERO:
00333          VEC4_COPY(source[0], zero); /* R */
00334          VEC4_COPY(source[1], zero); /* G */
00335          VEC4_COPY(source[2], zero); /* B */
00336          break;
00337       case PIPE_BLENDFACTOR_INV_SRC_COLOR:
00338          {
00339             float inv_comp[4];
00340             VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
00341             VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
00342             VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
00343             VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
00344             VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
00345             VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
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); /* R */
00353             VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
00354             VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
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); /* R */
00362             VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
00363             VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
00364          }
00365          break;
00366       case PIPE_BLENDFACTOR_INV_DST_COLOR:
00367          {
00368             float inv_comp[4];
00369             VEC4_SUB(inv_comp, one, dest[0]); /* R */
00370             VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
00371             VEC4_SUB(inv_comp, one, dest[1]); /* G */
00372             VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
00373             VEC4_SUB(inv_comp, one, dest[2]); /* B */
00374             VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
00375          }
00376          break;
00377       case PIPE_BLENDFACTOR_INV_CONST_COLOR:
00378          {
00379             float inv_comp[4];
00380             /* R */
00381             VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
00382             VEC4_MUL(source[0], quadColor[0], inv_comp);
00383             /* G */
00384             VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
00385             VEC4_MUL(source[1], quadColor[1], inv_comp);
00386             /* B */
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); /* R */
00396             VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
00397             VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
00398          }
00399          break;
00400       case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
00401          assert(0); /* to do */
00402          break;
00403       case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
00404          assert(0); /* to do */
00405          break;
00406       default:
00407          assert(0);
00408       }
00409 
00410       /*
00411        * Compute src/first term A
00412        */
00413       switch (softpipe->blend->alpha_src_factor) {
00414       case PIPE_BLENDFACTOR_ONE:
00415          VEC4_COPY(source[3], quadColor[3]); /* A */
00416          break;
00417       case PIPE_BLENDFACTOR_SRC_COLOR:
00418          /* fall-through */
00419       case PIPE_BLENDFACTOR_SRC_ALPHA:
00420          {
00421             const float *alpha = quadColor[3];
00422             VEC4_MUL(source[3], quadColor[3], alpha); /* A */
00423          }
00424          break;
00425       case PIPE_BLENDFACTOR_DST_COLOR:
00426          /* fall-through */
00427       case PIPE_BLENDFACTOR_DST_ALPHA:
00428          VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
00429          break;
00430       case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
00431          /* multiply alpha by 1.0 */
00432          VEC4_COPY(source[3], quadColor[3]); /* A */
00433          break;
00434       case PIPE_BLENDFACTOR_CONST_COLOR:
00435          /* fall-through */
00436       case PIPE_BLENDFACTOR_CONST_ALPHA:
00437          {
00438             float comp[4];
00439             VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
00440             VEC4_MUL(source[3], quadColor[3], comp); /* A */
00441          }
00442          break;
00443       case PIPE_BLENDFACTOR_ZERO:
00444          VEC4_COPY(source[3], zero); /* A */
00445          break;
00446       case PIPE_BLENDFACTOR_INV_SRC_COLOR:
00447          /* fall-through */
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); /* A */
00453          }
00454          break;
00455       case PIPE_BLENDFACTOR_INV_DST_COLOR:
00456          /* fall-through */
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); /* A */
00462          }
00463          break;
00464       case PIPE_BLENDFACTOR_INV_CONST_COLOR:
00465          /* fall-through */
00466       case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
00467          {
00468             float inv_comp[4];
00469             /* A */
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        * Compute dest/second term RGB
00481        */
00482       switch (softpipe->blend->rgb_dst_factor) {
00483       case PIPE_BLENDFACTOR_ONE:
00484          /* dest = dest * 1   NO-OP, leave dest as-is */
00485          break;
00486       case PIPE_BLENDFACTOR_SRC_COLOR:
00487          VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */
00488          VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */
00489          VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */
00490          break;
00491       case PIPE_BLENDFACTOR_SRC_ALPHA:
00492          VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */
00493          VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */
00494          VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */
00495          break;
00496       case PIPE_BLENDFACTOR_DST_ALPHA:
00497          VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
00498          VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
00499          VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
00500          break;
00501       case PIPE_BLENDFACTOR_DST_COLOR:
00502          VEC4_MUL(dest[0], dest[0], dest[0]); /* R */
00503          VEC4_MUL(dest[1], dest[1], dest[1]); /* G */
00504          VEC4_MUL(dest[2], dest[2], dest[2]); /* B */
00505          break;
00506       case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
00507          assert(0); /* illegal */
00508          break;
00509       case PIPE_BLENDFACTOR_CONST_COLOR:
00510          {
00511             float comp[4];
00512             VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
00513             VEC4_MUL(dest[0], dest[0], comp); /* R */
00514             VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
00515             VEC4_MUL(dest[1], dest[1], comp); /* G */
00516             VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
00517             VEC4_MUL(dest[2], dest[2], comp); /* B */
00518          }
00519          break;
00520       case PIPE_BLENDFACTOR_CONST_ALPHA:
00521          {
00522             float comp[4];
00523             VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
00524             VEC4_MUL(dest[0], dest[0], comp); /* R */
00525             VEC4_MUL(dest[1], dest[1], comp); /* G */
00526             VEC4_MUL(dest[2], dest[2], comp); /* B */
00527          }
00528          break;
00529       case PIPE_BLENDFACTOR_ZERO:
00530          VEC4_COPY(dest[0], zero); /* R */
00531          VEC4_COPY(dest[1], zero); /* G */
00532          VEC4_COPY(dest[2], zero); /* B */
00533          break;
00534       case PIPE_BLENDFACTOR_SRC1_COLOR:
00535       case PIPE_BLENDFACTOR_SRC1_ALPHA:
00536          /* XXX what are these? */
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]); /* R */
00543             VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
00544             VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
00545             VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
00546             VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
00547             VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
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); /* R */
00555             VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
00556             VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
00557          }
00558          break;
00559       case PIPE_BLENDFACTOR_INV_DST_ALPHA:
00560          {
00561             float inv_comp[4];
00562             VEC4_SUB(inv_comp, one, dest[3]); /* A */
00563             VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
00564             VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
00565             VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
00566          }
00567          break;
00568       case PIPE_BLENDFACTOR_INV_DST_COLOR:
00569          {
00570             float inv_comp[4];
00571             VEC4_SUB(inv_comp, one, dest[0]); /* R */
00572             VEC4_MUL(dest[0], dest[0], inv_comp); /* R */
00573             VEC4_SUB(inv_comp, one, dest[1]); /* G */
00574             VEC4_MUL(dest[1], dest[1], inv_comp); /* G */
00575             VEC4_SUB(inv_comp, one, dest[2]); /* B */
00576             VEC4_MUL(dest[2], dest[2], inv_comp); /* B */
00577          }
00578          break;
00579       case PIPE_BLENDFACTOR_INV_CONST_COLOR:
00580          {
00581             float inv_comp[4];
00582             /* R */
00583             VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
00584             VEC4_MUL(dest[0], dest[0], inv_comp);
00585             /* G */
00586             VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
00587             VEC4_MUL(dest[1], dest[1], inv_comp);
00588             /* B */
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          /* XXX what are these? */
00605          assert(0);
00606          break;
00607       default:
00608          assert(0);
00609       }
00610 
00611       /*
00612        * Compute dest/second term A
00613        */
00614       switch (softpipe->blend->alpha_dst_factor) {
00615       case PIPE_BLENDFACTOR_ONE:
00616          /* dest = dest * 1   NO-OP, leave dest as-is */
00617          break;
00618       case PIPE_BLENDFACTOR_SRC_COLOR:
00619          /* fall-through */
00620       case PIPE_BLENDFACTOR_SRC_ALPHA:
00621          VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */
00622          break;
00623       case PIPE_BLENDFACTOR_DST_COLOR:
00624          /* fall-through */
00625       case PIPE_BLENDFACTOR_DST_ALPHA:
00626          VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
00627          break;
00628       case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
00629          assert(0); /* illegal */
00630          break;
00631       case PIPE_BLENDFACTOR_CONST_COLOR:
00632          /* fall-through */
00633       case PIPE_BLENDFACTOR_CONST_ALPHA:
00634          {
00635             float comp[4];
00636             VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
00637             VEC4_MUL(dest[3], dest[3], comp); /* A */
00638          }
00639          break;
00640       case PIPE_BLENDFACTOR_ZERO:
00641          VEC4_COPY(dest[3], zero); /* A */
00642          break;
00643       case PIPE_BLENDFACTOR_INV_SRC_COLOR:
00644          /* fall-through */
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); /* A */
00650          }
00651          break;
00652       case PIPE_BLENDFACTOR_INV_DST_COLOR:
00653          /* fall-through */
00654       case PIPE_BLENDFACTOR_INV_DST_ALPHA:
00655          {
00656             float inv_comp[4];
00657             VEC4_SUB(inv_comp, one, dest[3]); /* A */
00658             VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
00659          }
00660          break;
00661       case PIPE_BLENDFACTOR_INV_CONST_COLOR:
00662          /* fall-through */
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        * Combine RGB terms
00676        */
00677       switch (softpipe->blend->rgb_func) {
00678       case PIPE_BLEND_ADD:
00679          VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */
00680          VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */
00681          VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */
00682          break;
00683       case PIPE_BLEND_SUBTRACT:
00684          VEC4_SUB(quadColor[0], source[0], dest[0]); /* R */
00685          VEC4_SUB(quadColor[1], source[1], dest[1]); /* G */
00686          VEC4_SUB(quadColor[2], source[2], dest[2]); /* B */
00687          break;
00688       case PIPE_BLEND_REVERSE_SUBTRACT:
00689          VEC4_SUB(quadColor[0], dest[0], source[0]); /* R */
00690          VEC4_SUB(quadColor[1], dest[1], source[1]); /* G */
00691          VEC4_SUB(quadColor[2], dest[2], source[2]); /* B */
00692          break;
00693       case PIPE_BLEND_MIN:
00694          VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */
00695          VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */
00696          VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */
00697          break;
00698       case PIPE_BLEND_MAX:
00699          VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */
00700          VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */
00701          VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */
00702          break;
00703       default:
00704          assert(0);
00705       }
00706 
00707       /*
00708        * Combine A terms
00709        */
00710       switch (softpipe->blend->alpha_func) {
00711       case PIPE_BLEND_ADD:
00712          VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */
00713          break;
00714       case PIPE_BLEND_SUBTRACT:
00715          VEC4_SUB(quadColor[3], source[3], dest[3]); /* A */
00716          break;
00717       case PIPE_BLEND_REVERSE_SUBTRACT:
00718          VEC4_SUB(quadColor[3], dest[3], source[3]); /* A */
00719          break;
00720       case PIPE_BLEND_MIN:
00721          VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */
00722          break;
00723       case PIPE_BLEND_MAX:
00724          VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */
00725          break;
00726       default:
00727          assert(0);
00728       }
00729 
00730    } /* cbuf loop */
00731 
00732    /* pass blended quad to next stage */
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 }

Generated on Tue Sep 29 06:25:17 2009 for Gallium3D by  doxygen 1.5.4