softpipe: move all color-combine code into sp_quad_blend.c
authorKeith Whitwell <keithw@vmware.com>
Fri, 24 Jul 2009 19:19:18 +0000 (20:19 +0100)
committerKeith Whitwell <keithw@vmware.com>
Fri, 24 Jul 2009 19:19:18 +0000 (20:19 +0100)
Consolidate the read-modify-write color combining code from
the blend, colormask and output stages.

src/gallium/drivers/softpipe/Makefile
src/gallium/drivers/softpipe/SConscript
src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/softpipe/sp_quad_blend.c
src/gallium/drivers/softpipe/sp_quad_bufloop.c [deleted file]
src/gallium/drivers/softpipe/sp_quad_colormask.c [deleted file]
src/gallium/drivers/softpipe/sp_quad_coverage.c
src/gallium/drivers/softpipe/sp_quad_output.c [deleted file]
src/gallium/drivers/softpipe/sp_quad_pipe.c

index 516e3992fdddf53963f6ebb523cde34a3ba4e0ed..bdc1a5819fc6b06a0d7f776986b03c3c98ed6638 100644 (file)
@@ -15,17 +15,15 @@ C_SOURCES = \
        sp_prim_setup.c \
        sp_prim_vbuf.c \
        sp_quad_pipe.c \
-       sp_quad_alpha_test.c \
-       sp_quad_blend.c \
-       sp_quad_colormask.c \
-       sp_quad_coverage.c \
-       sp_quad_depth_test.c \
+       sp_quad_stipple.c \
        sp_quad_earlyz.c \
+       sp_quad_depth_test.c \
+       sp_quad_stencil.c \
        sp_quad_fs.c \
+       sp_quad_alpha_test.c \
        sp_quad_occlusion.c \
-       sp_quad_output.c \
-       sp_quad_stencil.c \
-       sp_quad_stipple.c \
+       sp_quad_coverage.c \
+       sp_quad_blend.c \
        sp_screen.c \
         sp_setup.c \
        sp_state_blend.c \
index f8720638a76b093efb082d8e4dbec742b065ee10..dcc25732baf250790b22bc0fd01068e5a1622339 100644 (file)
@@ -18,13 +18,11 @@ softpipe = env.ConvenienceLibrary(
                'sp_quad_alpha_test.c',
                'sp_quad_blend.c',
                'sp_quad_pipe.c',
-               'sp_quad_colormask.c',
                'sp_quad_coverage.c',
                'sp_quad_depth_test.c',
                'sp_quad_earlyz.c',
                'sp_quad_fs.c',
                'sp_quad_occlusion.c',
-               'sp_quad_output.c',
                'sp_quad_stencil.c',
                'sp_quad_stipple.c',
                'sp_query.c',
index 4418ef0ff4cd9b6c9e782b05cd888a31626bd48d..28a0dd62ac20d8c19537054f52d84484986e138a 100644 (file)
@@ -97,8 +97,6 @@ static void softpipe_destroy( struct pipe_context *pipe )
       softpipe->quad.occlusion->destroy( softpipe->quad.occlusion );
       softpipe->quad.coverage->destroy( softpipe->quad.coverage );
       softpipe->quad.blend->destroy( softpipe->quad.blend );
-      softpipe->quad.colormask->destroy( softpipe->quad.colormask );
-      softpipe->quad.output->destroy( softpipe->quad.output );
 
    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
       sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
@@ -241,8 +239,6 @@ softpipe_create( struct pipe_screen *screen )
       softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);
       softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);
       softpipe->quad.blend = sp_quad_blend_stage(softpipe);
-      softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
-      softpipe->quad.output = sp_quad_output_stage(softpipe);
 
    /* vertex shader samplers */
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
index 153a648b0eff003059f5eac4c458b1861ada472d..b76ff610a3f0a455822271a85a1b40f8ae2bb3a7 100644 (file)
@@ -123,8 +123,6 @@ struct softpipe_context {
       struct quad_stage *occlusion;
       struct quad_stage *coverage;
       struct quad_stage *blend;
-      struct quad_stage *colormask;
-      struct quad_stage *output;
 
       struct quad_stage *first; /**< points to one of the above stages */
    } quad;
index 1ef7529cff7f7fa023c9f748c54a1c644495e197..e1f0e772554cc70ed6df57864951924e1f08df80 100644 (file)
@@ -117,135 +117,677 @@ do { \
 
 
 static void
-logicop_quads(struct quad_stage *qs, 
-              struct quad_header *quads[],
-              unsigned nr)
+logicop_quad(struct quad_stage *qs, 
+             float (*quadColor)[4],
+             float (*dest)[4])
 {
    struct softpipe_context *softpipe = qs->softpipe;
-   uint cbuf;
+   ubyte src[4][4], dst[4][4], res[4][4];
+   uint *src4 = (uint *) src;
+   uint *dst4 = (uint *) dst;
+   uint *res4 = (uint *) res;
+   uint j;
+
+
+   /* convert to ubyte */
+   for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
+      dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */
+      dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */
+      dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */
+      dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */
+
+      src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */
+      src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */
+      src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */
+      src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */
+   }
+
+   switch (softpipe->blend->logicop_func) {
+   case PIPE_LOGICOP_CLEAR:
+      for (j = 0; j < 4; j++)
+         res4[j] = 0;
+      break;
+   case PIPE_LOGICOP_NOR:
+      for (j = 0; j < 4; j++)
+         res4[j] = ~(src4[j] | dst4[j]);
+      break;
+   case PIPE_LOGICOP_AND_INVERTED:
+      for (j = 0; j < 4; j++)
+         res4[j] = ~src4[j] & dst4[j];
+      break;
+   case PIPE_LOGICOP_COPY_INVERTED:
+      for (j = 0; j < 4; j++)
+         res4[j] = ~src4[j];
+      break;
+   case PIPE_LOGICOP_AND_REVERSE:
+      for (j = 0; j < 4; j++)
+         res4[j] = src4[j] & ~dst4[j];
+      break;
+   case PIPE_LOGICOP_INVERT:
+      for (j = 0; j < 4; j++)
+         res4[j] = ~dst4[j];
+      break;
+   case PIPE_LOGICOP_XOR:
+      for (j = 0; j < 4; j++)
+         res4[j] = dst4[j] ^ src4[j];
+      break;
+   case PIPE_LOGICOP_NAND:
+      for (j = 0; j < 4; j++)
+         res4[j] = ~(src4[j] & dst4[j]);
+      break;
+   case PIPE_LOGICOP_AND:
+      for (j = 0; j < 4; j++)
+         res4[j] = src4[j] & dst4[j];
+      break;
+   case PIPE_LOGICOP_EQUIV:
+      for (j = 0; j < 4; j++)
+         res4[j] = ~(src4[j] ^ dst4[j]);
+      break;
+   case PIPE_LOGICOP_NOOP:
+      for (j = 0; j < 4; j++)
+         res4[j] = dst4[j];
+      break;
+   case PIPE_LOGICOP_OR_INVERTED:
+      for (j = 0; j < 4; j++)
+         res4[j] = ~src4[j] | dst4[j];
+      break;
+   case PIPE_LOGICOP_COPY:
+      for (j = 0; j < 4; j++)
+         res4[j] = src4[j];
+      break;
+   case PIPE_LOGICOP_OR_REVERSE:
+      for (j = 0; j < 4; j++)
+         res4[j] = src4[j] | ~dst4[j];
+      break;
+   case PIPE_LOGICOP_OR:
+      for (j = 0; j < 4; j++)
+         res4[j] = src4[j] | dst4[j];
+      break;
+   case PIPE_LOGICOP_SET:
+      for (j = 0; j < 4; j++)
+         res4[j] = ~0;
+      break;
+   default:
+      assert(0);
+   }
+
+   for (j = 0; j < 4; j++) {
+      quadColor[j][0] = ubyte_to_float(res[j][0]);
+      quadColor[j][1] = ubyte_to_float(res[j][1]);
+      quadColor[j][2] = ubyte_to_float(res[j][2]);
+      quadColor[j][3] = ubyte_to_float(res[j][3]);
+   }
+}
+
+
+
+static void
+blend_quad(struct quad_stage *qs, 
+           float (*quadColor)[4],
+           float (*dest)[4])
+{
+   static const float zero[4] = { 0, 0, 0, 0 };
+   static const float one[4] = { 1, 1, 1, 1 };
+   struct softpipe_context *softpipe = qs->softpipe;
+   float source[4][QUAD_SIZE];
+
+   /*
+    * Compute src/first term RGB
+    */
+   switch (softpipe->blend->rgb_src_factor) {
+   case PIPE_BLENDFACTOR_ONE:
+      VEC4_COPY(source[0], quadColor[0]); /* R */
+      VEC4_COPY(source[1], quadColor[1]); /* G */
+      VEC4_COPY(source[2], quadColor[2]); /* B */
+      break;
+   case PIPE_BLENDFACTOR_SRC_COLOR:
+      VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */
+      VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */
+      VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */
+      break;
+   case PIPE_BLENDFACTOR_SRC_ALPHA:
+   {
+      const float *alpha = quadColor[3];
+      VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+      VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+      VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_DST_COLOR:
+      VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */
+      VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */
+      VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */
+      break;
+   case PIPE_BLENDFACTOR_DST_ALPHA:
+   {
+      const float *alpha = dest[3];
+      VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+      VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+      VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+   {
+      const float *alpha = quadColor[3];
+      float diff[4], temp[4];
+      VEC4_SUB(diff, one, dest[3]);
+      VEC4_MIN(temp, alpha, diff);
+      VEC4_MUL(source[0], quadColor[0], temp); /* R */
+      VEC4_MUL(source[1], quadColor[1], temp); /* G */
+      VEC4_MUL(source[2], quadColor[2], temp); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_CONST_COLOR:
+   {
+      float comp[4];
+      VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
+      VEC4_MUL(source[0], quadColor[0], comp); /* R */
+      VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
+      VEC4_MUL(source[1], quadColor[1], comp); /* G */
+      VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
+      VEC4_MUL(source[2], quadColor[2], comp); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_CONST_ALPHA:
+   {
+      float alpha[4];
+      VEC4_SCALAR(alpha, softpipe->blend_color.color[3]);
+      VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+      VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+      VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_SRC1_COLOR:
+      assert(0); /* to do */
+      break;
+   case PIPE_BLENDFACTOR_SRC1_ALPHA:
+      assert(0); /* to do */
+      break;
+   case PIPE_BLENDFACTOR_ZERO:
+      VEC4_COPY(source[0], zero); /* R */
+      VEC4_COPY(source[1], zero); /* G */
+      VEC4_COPY(source[2], zero); /* B */
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+   {
+      float inv_comp[4];
+      VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
+      VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
+      VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
+      VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
+      VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
+      VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+   {
+      float inv_alpha[4];
+      VEC4_SUB(inv_alpha, one, quadColor[3]);
+      VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
+      VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
+      VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+   {
+      float inv_alpha[4];
+      VEC4_SUB(inv_alpha, one, dest[3]);
+      VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
+      VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
+      VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_DST_COLOR:
+   {
+      float inv_comp[4];
+      VEC4_SUB(inv_comp, one, dest[0]); /* R */
+      VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
+      VEC4_SUB(inv_comp, one, dest[1]); /* G */
+      VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
+      VEC4_SUB(inv_comp, one, dest[2]); /* B */
+      VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+   {
+      float inv_comp[4];
+      /* R */
+      VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
+      VEC4_MUL(source[0], quadColor[0], inv_comp);
+      /* G */
+      VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
+      VEC4_MUL(source[1], quadColor[1], inv_comp);
+      /* B */
+      VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
+      VEC4_MUL(source[2], quadColor[2], inv_comp);
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+   {
+      float inv_alpha[4];
+      VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]);
+      VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
+      VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
+      VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+      assert(0); /* to do */
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+      assert(0); /* to do */
+      break;
+   default:
+      assert(0);
+   }
+
+   /*
+    * Compute src/first term A
+    */
+   switch (softpipe->blend->alpha_src_factor) {
+   case PIPE_BLENDFACTOR_ONE:
+      VEC4_COPY(source[3], quadColor[3]); /* A */
+      break;
+   case PIPE_BLENDFACTOR_SRC_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_SRC_ALPHA:
+   {
+      const float *alpha = quadColor[3];
+      VEC4_MUL(source[3], quadColor[3], alpha); /* A */
+   }
+   break;
+   case PIPE_BLENDFACTOR_DST_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_DST_ALPHA:
+      VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
+      break;
+   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+      /* multiply alpha by 1.0 */
+      VEC4_COPY(source[3], quadColor[3]); /* A */
+      break;
+   case PIPE_BLENDFACTOR_CONST_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_CONST_ALPHA:
+   {
+      float comp[4];
+      VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+      VEC4_MUL(source[3], quadColor[3], comp); /* A */
+   }
+   break;
+   case PIPE_BLENDFACTOR_ZERO:
+      VEC4_COPY(source[3], zero); /* A */
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+   {
+      float inv_alpha[4];
+      VEC4_SUB(inv_alpha, one, quadColor[3]);
+      VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_DST_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+   {
+      float inv_alpha[4];
+      VEC4_SUB(inv_alpha, one, dest[3]);
+      VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+   {
+      float inv_comp[4];
+      /* A */
+      VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+      VEC4_MUL(source[3], quadColor[3], inv_comp);
+   }
+   break;
+   default:
+      assert(0);
+   }
+
 
-   /* loop over colorbuffer outputs */
-   for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
+   /*
+    * Compute dest/second term RGB
+    */
+   switch (softpipe->blend->rgb_dst_factor) {
+   case PIPE_BLENDFACTOR_ONE:
+      /* dest = dest * 1   NO-OP, leave dest as-is */
+      break;
+   case PIPE_BLENDFACTOR_SRC_COLOR:
+      VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */
+      VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */
+      VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */
+      break;
+   case PIPE_BLENDFACTOR_SRC_ALPHA:
+      VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */
+      VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */
+      VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */
+      break;
+   case PIPE_BLENDFACTOR_DST_ALPHA:
+      VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
+      VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
+      VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
+      break;
+   case PIPE_BLENDFACTOR_DST_COLOR:
+      VEC4_MUL(dest[0], dest[0], dest[0]); /* R */
+      VEC4_MUL(dest[1], dest[1], dest[1]); /* G */
+      VEC4_MUL(dest[2], dest[2], dest[2]); /* B */
+      break;
+   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+      assert(0); /* illegal */
+      break;
+   case PIPE_BLENDFACTOR_CONST_COLOR:
+   {
+      float comp[4];
+      VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
+      VEC4_MUL(dest[0], dest[0], comp); /* R */
+      VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
+      VEC4_MUL(dest[1], dest[1], comp); /* G */
+      VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
+      VEC4_MUL(dest[2], dest[2], comp); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_CONST_ALPHA:
+   {
+      float comp[4];
+      VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+      VEC4_MUL(dest[0], dest[0], comp); /* R */
+      VEC4_MUL(dest[1], dest[1], comp); /* G */
+      VEC4_MUL(dest[2], dest[2], comp); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_ZERO:
+      VEC4_COPY(dest[0], zero); /* R */
+      VEC4_COPY(dest[1], zero); /* G */
+      VEC4_COPY(dest[2], zero); /* B */
+      break;
+   case PIPE_BLENDFACTOR_SRC1_COLOR:
+   case PIPE_BLENDFACTOR_SRC1_ALPHA:
+      /* XXX what are these? */
+      assert(0);
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+   {
+      float inv_comp[4];
+      VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
+      VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
+      VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
+      VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
+      VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
+      VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+   {
+      float one_minus_alpha[QUAD_SIZE];
+      VEC4_SUB(one_minus_alpha, one, quadColor[3]);
+      VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
+      VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
+      VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+   {
+      float inv_comp[4];
+      VEC4_SUB(inv_comp, one, dest[3]); /* A */
+      VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
+      VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
+      VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_DST_COLOR:
+   {
+      float inv_comp[4];
+      VEC4_SUB(inv_comp, one, dest[0]); /* R */
+      VEC4_MUL(dest[0], dest[0], inv_comp); /* R */
+      VEC4_SUB(inv_comp, one, dest[1]); /* G */
+      VEC4_MUL(dest[1], dest[1], inv_comp); /* G */
+      VEC4_SUB(inv_comp, one, dest[2]); /* B */
+      VEC4_MUL(dest[2], dest[2], inv_comp); /* B */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+   {
+      float inv_comp[4];
+      /* R */
+      VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
+      VEC4_MUL(dest[0], dest[0], inv_comp);
+      /* G */
+      VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
+      VEC4_MUL(dest[1], dest[1], inv_comp);
+      /* B */
+      VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
+      VEC4_MUL(dest[2], dest[2], inv_comp);
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+   {
+      float inv_comp[4];
+      VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+      VEC4_MUL(dest[0], dest[0], inv_comp);
+      VEC4_MUL(dest[1], dest[1], inv_comp);
+      VEC4_MUL(dest[2], dest[2], inv_comp);
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+      /* XXX what are these? */
+      assert(0);
+      break;
+   default:
+      assert(0);
+   }
+
+   /*
+    * Compute dest/second term A
+    */
+   switch (softpipe->blend->alpha_dst_factor) {
+   case PIPE_BLENDFACTOR_ONE:
+      /* dest = dest * 1   NO-OP, leave dest as-is */
+      break;
+   case PIPE_BLENDFACTOR_SRC_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_SRC_ALPHA:
+      VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */
+      break;
+   case PIPE_BLENDFACTOR_DST_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_DST_ALPHA:
+      VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
+      break;
+   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+      assert(0); /* illegal */
+      break;
+   case PIPE_BLENDFACTOR_CONST_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_CONST_ALPHA:
+   {
+      float comp[4];
+      VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+      VEC4_MUL(dest[3], dest[3], comp); /* A */
+   }
+   break;
+   case PIPE_BLENDFACTOR_ZERO:
+      VEC4_COPY(dest[3], zero); /* A */
+      break;
+   case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+   {
+      float one_minus_alpha[QUAD_SIZE];
+      VEC4_SUB(one_minus_alpha, one, quadColor[3]);
+      VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_DST_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+   {
+      float inv_comp[4];
+      VEC4_SUB(inv_comp, one, dest[3]); /* A */
+      VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
+   }
+   break;
+   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+      /* fall-through */
+   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+   {
+      float inv_comp[4];
+      VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+      VEC4_MUL(dest[3], dest[3], inv_comp);
+   }
+   break;
+   default:
+      assert(0);
+   }
+
+   /*
+    * Combine RGB terms
+    */
+   switch (softpipe->blend->rgb_func) {
+   case PIPE_BLEND_ADD:
+      VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
+      VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
+      VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
+      break;
+   case PIPE_BLEND_SUBTRACT:
+      VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */
+      VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */
+      VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */
+      break;
+   case PIPE_BLEND_REVERSE_SUBTRACT:
+      VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */
+      VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */
+      VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */
+      break;
+   case PIPE_BLEND_MIN:
+      VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */
+      VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */
+      VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */
+      break;
+   case PIPE_BLEND_MAX:
+      VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */
+      VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */
+      VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */
+      break;
+   default:
+      assert(0);
+   }
+
+   /*
+    * Combine A terms
+    */
+   switch (softpipe->blend->alpha_func) {
+   case PIPE_BLEND_ADD:
+      VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
+      break;
+   case PIPE_BLEND_SUBTRACT:
+      VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */
+      break;
+   case PIPE_BLEND_REVERSE_SUBTRACT:
+      VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */
+      break;
+   case PIPE_BLEND_MIN:
+      VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */
+      break;
+   case PIPE_BLEND_MAX:
+      VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */
+      break;
+   default:
+      assert(0);
+   }
+}
+
+static void
+colormask_quad(struct quad_stage *qs,
+               float (*quadColor)[4],
+               float (*dest)[4])
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+
+   /* R */
+   if (!(softpipe->blend->colormask & PIPE_MASK_R))
+      COPY_4V(quadColor[0], dest[0]);
+
+   /* G */
+   if (!(softpipe->blend->colormask & PIPE_MASK_G))
+      COPY_4V(quadColor[1], dest[1]);
+
+   /* B */
+   if (!(softpipe->blend->colormask & PIPE_MASK_B))
+      COPY_4V(quadColor[2], dest[2]);
+
+   /* A */
+   if (!(softpipe->blend->colormask & PIPE_MASK_A))
+      COPY_4V(quadColor[3], dest[3]);
+}
+
+
+static void
+blend_fallback(struct quad_stage *qs, 
+               struct quad_header *quads[],
+               unsigned nr)
+{
+   struct softpipe_context *softpipe = qs->softpipe;
+   const struct pipe_blend_state *blend = softpipe->blend;
+   unsigned cbuf;
+
+   for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) 
+   {
       float dest[4][QUAD_SIZE];
-      ubyte src[4][4], dst[4][4], res[4][4];
-      uint *src4 = (uint *) src;
-      uint *dst4 = (uint *) dst;
-      uint *res4 = (uint *) res;
-      uint i, j;
-
-      struct softpipe_cached_tile *
-         tile = sp_get_cached_tile(softpipe->cbuf_cache[cbuf],
-                                   quads[0]->input.x0, 
-                                   quads[0]->input.y0);
-
-      for (i = 0; i < nr; i++) {
-         struct quad_header *quad = quads[i];
+      struct softpipe_cached_tile *tile
+         = sp_get_cached_tile(softpipe->cbuf_cache[cbuf],
+                              quads[0]->input.x0, 
+                              quads[0]->input.y0);
+      uint q, i, j;
+
+      for (q = 0; q < nr; q++) {
+         struct quad_header *quad = quads[q];
          float (*quadColor)[4] = quad->output.color[cbuf];
+         const int itx = (quad->input.x0 & (TILE_SIZE-1));
+         const int ity = (quad->input.y0 & (TILE_SIZE-1));
 
-         /* get/swizzle dest colors */
+         /* get/swizzle dest colors 
+          */
          for (j = 0; j < QUAD_SIZE; j++) {
-            int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
-            int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
+            int x = itx + (j & 1);
+            int y = ity + (j >> 1);
             for (i = 0; i < 4; i++) {
                dest[i][j] = tile->data.color[y][x][i];
             }
          }
 
-         /* convert to ubyte */
-         for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
-            dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */
-            dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */
-            dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */
-            dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */
-
-            src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */
-            src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */
-            src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */
-            src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */
-         }
 
-         switch (softpipe->blend->logicop_func) {
-         case PIPE_LOGICOP_CLEAR:
-            for (j = 0; j < 4; j++)
-               res4[j] = 0;
-            break;
-         case PIPE_LOGICOP_NOR:
-            for (j = 0; j < 4; j++)
-               res4[j] = ~(src4[j] | dst4[j]);
-            break;
-         case PIPE_LOGICOP_AND_INVERTED:
-            for (j = 0; j < 4; j++)
-               res4[j] = ~src4[j] & dst4[j];
-            break;
-         case PIPE_LOGICOP_COPY_INVERTED:
-            for (j = 0; j < 4; j++)
-               res4[j] = ~src4[j];
-            break;
-         case PIPE_LOGICOP_AND_REVERSE:
-            for (j = 0; j < 4; j++)
-               res4[j] = src4[j] & ~dst4[j];
-            break;
-         case PIPE_LOGICOP_INVERT:
-            for (j = 0; j < 4; j++)
-               res4[j] = ~dst4[j];
-            break;
-         case PIPE_LOGICOP_XOR:
-            for (j = 0; j < 4; j++)
-               res4[j] = dst4[j] ^ src4[j];
-            break;
-         case PIPE_LOGICOP_NAND:
-            for (j = 0; j < 4; j++)
-               res4[j] = ~(src4[j] & dst4[j]);
-            break;
-         case PIPE_LOGICOP_AND:
-            for (j = 0; j < 4; j++)
-               res4[j] = src4[j] & dst4[j];
-            break;
-         case PIPE_LOGICOP_EQUIV:
-            for (j = 0; j < 4; j++)
-               res4[j] = ~(src4[j] ^ dst4[j]);
-            break;
-         case PIPE_LOGICOP_NOOP:
-            for (j = 0; j < 4; j++)
-               res4[j] = dst4[j];
-            break;
-         case PIPE_LOGICOP_OR_INVERTED:
-            for (j = 0; j < 4; j++)
-               res4[j] = ~src4[j] | dst4[j];
-            break;
-         case PIPE_LOGICOP_COPY:
-            for (j = 0; j < 4; j++)
-               res4[j] = src4[j];
-            break;
-         case PIPE_LOGICOP_OR_REVERSE:
-            for (j = 0; j < 4; j++)
-               res4[j] = src4[j] | ~dst4[j];
-            break;
-         case PIPE_LOGICOP_OR:
-            for (j = 0; j < 4; j++)
-               res4[j] = src4[j] | dst4[j];
-            break;
-         case PIPE_LOGICOP_SET:
-            for (j = 0; j < 4; j++)
-               res4[j] = ~0;
-            break;
-         default:
-            assert(0);
+         if (blend->logicop_enable) {
+            logicop_quad( qs, quadColor, dest );
+         }
+         else if (blend->blend_enable) {
+            blend_quad( qs, quadColor, dest );
          }
 
-         for (j = 0; j < 4; j++) {
-            quadColor[j][0] = ubyte_to_float(res[j][0]);
-            quadColor[j][1] = ubyte_to_float(res[j][1]);
-            quadColor[j][2] = ubyte_to_float(res[j][2]);
-            quadColor[j][3] = ubyte_to_float(res[j][3]);
+         if (blend->colormask != 0xf)
+            colormask_quad( qs, quadColor, dest );
+   
+         /* Output color values
+          */
+         for (j = 0; j < QUAD_SIZE; j++) {
+            if (quad->inout.mask & (1 << j)) {
+               int x = itx + (j & 1);
+               int y = ity + (j >> 1);
+               for (i = 0; i < 4; i++) { /* loop over color chans */
+                  tile->data.color[y][x][i] = quadColor[i][j];
+               }
+            }
          }
       }
    }
-
-   /* pass blended quad to next stage */
-   qs->next->run(qs->next, quads, nr);
 }
 
+
 static void
 blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs, 
                                          struct quad_header *quads[],
@@ -266,11 +808,13 @@ blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs,
       struct quad_header *quad = quads[q];
       float (*quadColor)[4] = quad->output.color[0];
       const float *alpha = quadColor[3];
+      const int itx = (quad->input.x0 & (TILE_SIZE-1));
+      const int ity = (quad->input.y0 & (TILE_SIZE-1));
       
       /* get/swizzle dest colors */
       for (j = 0; j < QUAD_SIZE; j++) {
-         int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
-         int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
+         int x = itx + (j & 1);
+         int y = ity + (j >> 1);
          for (i = 0; i < 4; i++) {
             dest[i][j] = tile->data.color[y][x][i];
          }
@@ -291,10 +835,17 @@ blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs,
       VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
       VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
       VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
-   }
 
-   /* pass blended quad to next stage */
-   qs->next->run(qs->next, quads, nr);
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (quad->inout.mask & (1 << j)) {
+            int x = itx + (j & 1);
+            int y = ity + (j >> 1);
+            for (i = 0; i < 4; i++) { /* loop over color chans */
+               tile->data.color[y][x][i] = quadColor[i][j];
+            }
+         }
+      }
+   }
 }
 
 static void
@@ -313,11 +864,13 @@ blend_single_add_one_one(struct quad_stage *qs,
    for (q = 0; q < nr; q++) {
       struct quad_header *quad = quads[q];
       float (*quadColor)[4] = quad->output.color[0];
+      const int itx = (quad->input.x0 & (TILE_SIZE-1));
+      const int ity = (quad->input.y0 & (TILE_SIZE-1));
       
       /* get/swizzle dest colors */
       for (j = 0; j < QUAD_SIZE; j++) {
-         int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
-         int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
+         int x = itx + (j & 1);
+         int y = ity + (j >> 1);
          for (i = 0; i < 4; i++) {
             dest[i][j] = tile->data.color[y][x][i];
          }
@@ -327,539 +880,71 @@ blend_single_add_one_one(struct quad_stage *qs,
       VEC4_ADD_SAT(quadColor[1], quadColor[1], dest[1]); /* G */
       VEC4_ADD_SAT(quadColor[2], quadColor[2], dest[2]); /* B */
       VEC4_ADD_SAT(quadColor[3], quadColor[3], dest[3]); /* A */
-   }
 
-   /* pass blended quad to next stage */
-   qs->next->run(qs->next, quads, nr);
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (quad->inout.mask & (1 << j)) {
+            int x = itx + (j & 1);
+            int y = ity + (j >> 1);
+            for (i = 0; i < 4; i++) { /* loop over color chans */
+               tile->data.color[y][x][i] = quadColor[i][j];
+            }
+         }
+      }
+   }
 }
 
+
 static void
-blend_quads_fallback(struct quad_stage *qs, 
-                     struct quad_header *quads[],
-                     unsigned nr)
+single_output_color(struct quad_stage *qs, 
+                    struct quad_header *quads[],
+                    unsigned nr)
 {
-   static const float zero[4] = { 0, 0, 0, 0 };
-   static const float one[4] = { 1, 1, 1, 1 };
-   struct softpipe_context *softpipe = qs->softpipe;
-   uint cbuf;
-
-   /* loop over colorbuffer outputs */
-   for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
-      float source[4][QUAD_SIZE], dest[4][QUAD_SIZE];
-      struct softpipe_cached_tile *tile
-         = sp_get_cached_tile(softpipe->cbuf_cache[cbuf],
-                              quads[0]->input.x0, 
-                              quads[0]->input.y0);
-      uint q, i, j;
+   uint i, j, q;
 
-      for (q = 0; q < nr; q++) {
-         struct quad_header *quad = quads[q];
-         float (*quadColor)[4] = quad->output.color[cbuf];
+   struct softpipe_cached_tile *tile
+      = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
+                           quads[0]->input.x0, 
+                           quads[0]->input.y0);
 
-         /* get/swizzle dest colors */
-         for (j = 0; j < QUAD_SIZE; j++) {
-            int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
-            int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
-            for (i = 0; i < 4; i++) {
-               dest[i][j] = tile->data.color[y][x][i];
+   for (q = 0; q < nr; q++) {
+      struct quad_header *quad = quads[q];
+      float (*quadColor)[4] = quad->output.color[0];
+      const int itx = (quad->input.x0 & (TILE_SIZE-1));
+      const int ity = (quad->input.y0 & (TILE_SIZE-1));
+      
+      for (j = 0; j < QUAD_SIZE; j++) {
+         if (quad->inout.mask & (1 << j)) {
+            int x = itx + (j & 1);
+            int y = ity + (j >> 1);
+            for (i = 0; i < 4; i++) { /* loop over color chans */
+               tile->data.color[y][x][i] = quadColor[i][j];
             }
          }
-
-         /*
-          * Compute src/first term RGB
-          */
-         switch (softpipe->blend->rgb_src_factor) {
-         case PIPE_BLENDFACTOR_ONE:
-            VEC4_COPY(source[0], quadColor[0]); /* R */
-            VEC4_COPY(source[1], quadColor[1]); /* G */
-            VEC4_COPY(source[2], quadColor[2]); /* B */
-            break;
-         case PIPE_BLENDFACTOR_SRC_COLOR:
-            VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */
-            VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */
-            VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */
-            break;
-         case PIPE_BLENDFACTOR_SRC_ALPHA:
-         {
-            const float *alpha = quadColor[3];
-            VEC4_MUL(source[0], quadColor[0], alpha); /* R */
-            VEC4_MUL(source[1], quadColor[1], alpha); /* G */
-            VEC4_MUL(source[2], quadColor[2], alpha); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_DST_COLOR:
-            VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */
-            VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */
-            VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */
-            break;
-         case PIPE_BLENDFACTOR_DST_ALPHA:
-         {
-            const float *alpha = dest[3];
-            VEC4_MUL(source[0], quadColor[0], alpha); /* R */
-            VEC4_MUL(source[1], quadColor[1], alpha); /* G */
-            VEC4_MUL(source[2], quadColor[2], alpha); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
-         {
-            const float *alpha = quadColor[3];
-            float diff[4], temp[4];
-            VEC4_SUB(diff, one, dest[3]);
-            VEC4_MIN(temp, alpha, diff);
-            VEC4_MUL(source[0], quadColor[0], temp); /* R */
-            VEC4_MUL(source[1], quadColor[1], temp); /* G */
-            VEC4_MUL(source[2], quadColor[2], temp); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_CONST_COLOR:
-         {
-            float comp[4];
-            VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
-            VEC4_MUL(source[0], quadColor[0], comp); /* R */
-            VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
-            VEC4_MUL(source[1], quadColor[1], comp); /* G */
-            VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
-            VEC4_MUL(source[2], quadColor[2], comp); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_CONST_ALPHA:
-         {
-            float alpha[4];
-            VEC4_SCALAR(alpha, softpipe->blend_color.color[3]);
-            VEC4_MUL(source[0], quadColor[0], alpha); /* R */
-            VEC4_MUL(source[1], quadColor[1], alpha); /* G */
-            VEC4_MUL(source[2], quadColor[2], alpha); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_SRC1_COLOR:
-            assert(0); /* to do */
-            break;
-         case PIPE_BLENDFACTOR_SRC1_ALPHA:
-            assert(0); /* to do */
-            break;
-         case PIPE_BLENDFACTOR_ZERO:
-            VEC4_COPY(source[0], zero); /* R */
-            VEC4_COPY(source[1], zero); /* G */
-            VEC4_COPY(source[2], zero); /* B */
-            break;
-         case PIPE_BLENDFACTOR_INV_SRC_COLOR:
-         {
-            float inv_comp[4];
-            VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
-            VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
-            VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
-            VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
-            VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
-            VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
-         {
-            float inv_alpha[4];
-            VEC4_SUB(inv_alpha, one, quadColor[3]);
-            VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
-            VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
-            VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_DST_ALPHA:
-         {
-            float inv_alpha[4];
-            VEC4_SUB(inv_alpha, one, dest[3]);
-            VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
-            VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
-            VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_DST_COLOR:
-         {
-            float inv_comp[4];
-            VEC4_SUB(inv_comp, one, dest[0]); /* R */
-            VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
-            VEC4_SUB(inv_comp, one, dest[1]); /* G */
-            VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
-            VEC4_SUB(inv_comp, one, dest[2]); /* B */
-            VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_CONST_COLOR:
-         {
-            float inv_comp[4];
-            /* R */
-            VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
-            VEC4_MUL(source[0], quadColor[0], inv_comp);
-            /* G */
-            VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
-            VEC4_MUL(source[1], quadColor[1], inv_comp);
-            /* B */
-            VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
-            VEC4_MUL(source[2], quadColor[2], inv_comp);
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
-         {
-            float inv_alpha[4];
-            VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]);
-            VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
-            VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
-            VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
-            assert(0); /* to do */
-            break;
-         case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
-            assert(0); /* to do */
-            break;
-         default:
-            assert(0);
-         }
-
-         /*
-          * Compute src/first term A
-          */
-         switch (softpipe->blend->alpha_src_factor) {
-         case PIPE_BLENDFACTOR_ONE:
-            VEC4_COPY(source[3], quadColor[3]); /* A */
-            break;
-         case PIPE_BLENDFACTOR_SRC_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_SRC_ALPHA:
-         {
-            const float *alpha = quadColor[3];
-            VEC4_MUL(source[3], quadColor[3], alpha); /* A */
-         }
-         break;
-         case PIPE_BLENDFACTOR_DST_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_DST_ALPHA:
-            VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
-            break;
-         case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
-            /* multiply alpha by 1.0 */
-            VEC4_COPY(source[3], quadColor[3]); /* A */
-            break;
-         case PIPE_BLENDFACTOR_CONST_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_CONST_ALPHA:
-         {
-            float comp[4];
-            VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
-            VEC4_MUL(source[3], quadColor[3], comp); /* A */
-         }
-         break;
-         case PIPE_BLENDFACTOR_ZERO:
-            VEC4_COPY(source[3], zero); /* A */
-            break;
-         case PIPE_BLENDFACTOR_INV_SRC_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
-         {
-            float inv_alpha[4];
-            VEC4_SUB(inv_alpha, one, quadColor[3]);
-            VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_DST_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_INV_DST_ALPHA:
-         {
-            float inv_alpha[4];
-            VEC4_SUB(inv_alpha, one, dest[3]);
-            VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_CONST_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
-         {
-            float inv_comp[4];
-            /* A */
-            VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
-            VEC4_MUL(source[3], quadColor[3], inv_comp);
-         }
-         break;
-         default:
-            assert(0);
-         }
-
-
-         /*
-          * Compute dest/second term RGB
-          */
-         switch (softpipe->blend->rgb_dst_factor) {
-         case PIPE_BLENDFACTOR_ONE:
-            /* dest = dest * 1   NO-OP, leave dest as-is */
-            break;
-         case PIPE_BLENDFACTOR_SRC_COLOR:
-            VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */
-            VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */
-            VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */
-            break;
-         case PIPE_BLENDFACTOR_SRC_ALPHA:
-            VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */
-            VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */
-            VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */
-            break;
-         case PIPE_BLENDFACTOR_DST_ALPHA:
-            VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
-            VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
-            VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
-            break;
-         case PIPE_BLENDFACTOR_DST_COLOR:
-            VEC4_MUL(dest[0], dest[0], dest[0]); /* R */
-            VEC4_MUL(dest[1], dest[1], dest[1]); /* G */
-            VEC4_MUL(dest[2], dest[2], dest[2]); /* B */
-            break;
-         case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
-            assert(0); /* illegal */
-            break;
-         case PIPE_BLENDFACTOR_CONST_COLOR:
-         {
-            float comp[4];
-            VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
-            VEC4_MUL(dest[0], dest[0], comp); /* R */
-            VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
-            VEC4_MUL(dest[1], dest[1], comp); /* G */
-            VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
-            VEC4_MUL(dest[2], dest[2], comp); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_CONST_ALPHA:
-         {
-            float comp[4];
-            VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
-            VEC4_MUL(dest[0], dest[0], comp); /* R */
-            VEC4_MUL(dest[1], dest[1], comp); /* G */
-            VEC4_MUL(dest[2], dest[2], comp); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_ZERO:
-            VEC4_COPY(dest[0], zero); /* R */
-            VEC4_COPY(dest[1], zero); /* G */
-            VEC4_COPY(dest[2], zero); /* B */
-            break;
-         case PIPE_BLENDFACTOR_SRC1_COLOR:
-         case PIPE_BLENDFACTOR_SRC1_ALPHA:
-            /* XXX what are these? */
-            assert(0);
-            break;
-         case PIPE_BLENDFACTOR_INV_SRC_COLOR:
-         {
-            float inv_comp[4];
-            VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
-            VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
-            VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
-            VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
-            VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
-            VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
-         {
-            float one_minus_alpha[QUAD_SIZE];
-            VEC4_SUB(one_minus_alpha, one, quadColor[3]);
-            VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
-            VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
-            VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_DST_ALPHA:
-         {
-            float inv_comp[4];
-            VEC4_SUB(inv_comp, one, dest[3]); /* A */
-            VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
-            VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
-            VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_DST_COLOR:
-         {
-            float inv_comp[4];
-            VEC4_SUB(inv_comp, one, dest[0]); /* R */
-            VEC4_MUL(dest[0], dest[0], inv_comp); /* R */
-            VEC4_SUB(inv_comp, one, dest[1]); /* G */
-            VEC4_MUL(dest[1], dest[1], inv_comp); /* G */
-            VEC4_SUB(inv_comp, one, dest[2]); /* B */
-            VEC4_MUL(dest[2], dest[2], inv_comp); /* B */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_CONST_COLOR:
-         {
-            float inv_comp[4];
-            /* R */
-            VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
-            VEC4_MUL(dest[0], dest[0], inv_comp);
-            /* G */
-            VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
-            VEC4_MUL(dest[1], dest[1], inv_comp);
-            /* B */
-            VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
-            VEC4_MUL(dest[2], dest[2], inv_comp);
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
-         {
-            float inv_comp[4];
-            VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
-            VEC4_MUL(dest[0], dest[0], inv_comp);
-            VEC4_MUL(dest[1], dest[1], inv_comp);
-            VEC4_MUL(dest[2], dest[2], inv_comp);
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
-         case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
-            /* XXX what are these? */
-            assert(0);
-            break;
-         default:
-            assert(0);
-         }
-
-         /*
-          * Compute dest/second term A
-          */
-         switch (softpipe->blend->alpha_dst_factor) {
-         case PIPE_BLENDFACTOR_ONE:
-            /* dest = dest * 1   NO-OP, leave dest as-is */
-            break;
-         case PIPE_BLENDFACTOR_SRC_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_SRC_ALPHA:
-            VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */
-            break;
-         case PIPE_BLENDFACTOR_DST_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_DST_ALPHA:
-            VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
-            break;
-         case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
-            assert(0); /* illegal */
-            break;
-         case PIPE_BLENDFACTOR_CONST_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_CONST_ALPHA:
-         {
-            float comp[4];
-            VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
-            VEC4_MUL(dest[3], dest[3], comp); /* A */
-         }
-         break;
-         case PIPE_BLENDFACTOR_ZERO:
-            VEC4_COPY(dest[3], zero); /* A */
-            break;
-         case PIPE_BLENDFACTOR_INV_SRC_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
-         {
-            float one_minus_alpha[QUAD_SIZE];
-            VEC4_SUB(one_minus_alpha, one, quadColor[3]);
-            VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_DST_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_INV_DST_ALPHA:
-         {
-            float inv_comp[4];
-            VEC4_SUB(inv_comp, one, dest[3]); /* A */
-            VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
-         }
-         break;
-         case PIPE_BLENDFACTOR_INV_CONST_COLOR:
-            /* fall-through */
-         case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
-         {
-            float inv_comp[4];
-            VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
-            VEC4_MUL(dest[3], dest[3], inv_comp);
-         }
-         break;
-         default:
-            assert(0);
-         }
-
-         /*
-          * Combine RGB terms
-          */
-         switch (softpipe->blend->rgb_func) {
-         case PIPE_BLEND_ADD:
-            VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
-            VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
-            VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
-            break;
-         case PIPE_BLEND_SUBTRACT:
-            VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */
-            VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */
-            VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */
-            break;
-         case PIPE_BLEND_REVERSE_SUBTRACT:
-            VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */
-            VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */
-            VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */
-            break;
-         case PIPE_BLEND_MIN:
-            VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */
-            VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */
-            VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */
-            break;
-         case PIPE_BLEND_MAX:
-            VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */
-            VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */
-            VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */
-            break;
-         default:
-            assert(0);
-         }
-
-         /*
-          * Combine A terms
-          */
-         switch (softpipe->blend->alpha_func) {
-         case PIPE_BLEND_ADD:
-            VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
-            break;
-         case PIPE_BLEND_SUBTRACT:
-            VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */
-            break;
-         case PIPE_BLEND_REVERSE_SUBTRACT:
-            VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */
-            break;
-         case PIPE_BLEND_MIN:
-            VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */
-            break;
-         case PIPE_BLEND_MAX:
-            VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */
-            break;
-         default:
-            assert(0);
-         }
       }
-   } /* cbuf loop */
-
-   /* pass blended quad to next stage */
-   qs->next->run(qs->next, quads, nr);
+   }
 }
 
 
 static void
-blend_quad(struct quad_stage *qs, 
-           struct quad_header *quads[],
-           unsigned nr)
+choose_blend_quad(struct quad_stage *qs, 
+                  struct quad_header *quads[],
+                  unsigned nr)
 {
    struct softpipe_context *softpipe = qs->softpipe;
    const struct pipe_blend_state *blend = softpipe->blend;
 
-   if (softpipe->blend->logicop_enable) {
-      qs->run = logicop_quads;
-   }
-   else {
-      qs->run = blend_quads_fallback;
+   qs->run = blend_fallback;
 
-      if (blend->rgb_src_factor == blend->alpha_src_factor &&
-          blend->rgb_dst_factor == blend->alpha_dst_factor &&
-          blend->rgb_func == blend->alpha_func &&
-          softpipe->framebuffer.nr_cbufs == 1)
+   if (!softpipe->blend->logicop_enable &&
+       softpipe->blend->colormask == 0xf) 
+   {
+      if (!blend->blend_enable) {
+         qs->run = single_output_color;
+      }
+      else if (blend->rgb_src_factor == blend->alpha_src_factor &&
+               blend->rgb_dst_factor == blend->alpha_dst_factor &&
+               blend->rgb_func == blend->alpha_func &&
+               softpipe->framebuffer.nr_cbufs == 1)
       {
          if (blend->alpha_func == PIPE_BLEND_ADD) {
             if (blend->rgb_src_factor == PIPE_BLENDFACTOR_ONE &&
@@ -871,7 +956,7 @@ blend_quad(struct quad_stage *qs,
                qs->run = blend_single_add_src_alpha_inv_src_alpha;
 
          }
-      } 
+      }
    }
 
    qs->run(qs, quads, nr);
@@ -880,8 +965,7 @@ blend_quad(struct quad_stage *qs,
 
 static void blend_begin(struct quad_stage *qs)
 {
-   qs->run = blend_quad;
-   qs->next->begin(qs->next);
+   qs->run = choose_blend_quad;
 }
 
 
@@ -897,7 +981,7 @@ struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe )
 
    stage->softpipe = softpipe;
    stage->begin = blend_begin;
-   stage->run = blend_quad;
+   stage->run = choose_blend_quad;
    stage->destroy = blend_destroy;
 
    return stage;
diff --git a/src/gallium/drivers/softpipe/sp_quad_bufloop.c b/src/gallium/drivers/softpipe/sp_quad_bufloop.c
deleted file mode 100644 (file)
index 953d851..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-
-#include "util/u_memory.h"
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_surface.h"
-#include "sp_quad_pipe.h"
-
-
-/**
- * Loop over colorbuffers, passing quad to next stage each time.
- */
-static void
-cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad)
-{
-   struct softpipe_context *softpipe = qs->softpipe;
-   float tmp[PIPE_MAX_COLOR_BUFS][4][QUAD_SIZE];
-   unsigned i;
-
-   assert(sizeof(quad->outputs.color) == sizeof(tmp));
-   assert(softpipe->framebuffer.nr_cbufs <= PIPE_MAX_COLOR_BUFS);
-
-   /* make copy of original colors since they can get modified
-    * by blending and masking.
-    * XXX we won't have to do this if the fragment program actually emits
-    * N separate colors and we're drawing to N color buffers (MRT).
-    * But if we emitted one color and glDrawBuffer(GL_FRONT_AND_BACK) is
-    * in effect, we need to save/restore colors like this.
-    */
-   memcpy(tmp, quad->outputs.color, sizeof(tmp));
-
-   for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
-      /* set current cbuffer */
-#if 0 /* obsolete & going away */
-      softpipe->current_cbuf = i;
-#endif
-
-      /* pass blended quad to next stage */
-      qs->next->run(qs->next, quad);
-
-      /* restore quad's colors for next buffer */
-      memcpy(quad->outputs.color, tmp, sizeof(tmp));
-   }
-}
-
-
-static void cbuf_loop_begin(struct quad_stage *qs)
-{
-   qs->next->begin(qs->next);
-}
-
-
-static void cbuf_loop_destroy(struct quad_stage *qs)
-{
-   FREE( qs );
-}
-
-
-/**
- * Create the colorbuffer loop stage.
- * This is used to implement multiple render targets and GL_FRONT_AND_BACK
- * rendering.
- */
-struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe )
-{
-   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
-
-   stage->softpipe = softpipe;
-   stage->begin = cbuf_loop_begin;
-   stage->run = cbuf_loop_quad;
-   stage->destroy = cbuf_loop_destroy;
-
-   return stage;
-}
-
diff --git a/src/gallium/drivers/softpipe/sp_quad_colormask.c b/src/gallium/drivers/softpipe/sp_quad_colormask.c
deleted file mode 100644 (file)
index ac74287..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * \brief  quad colormask stage
- * \author Brian Paul
- */
-
-#include "pipe/p_defines.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_surface.h"
-#include "sp_quad_pipe.h"
-#include "sp_tile_cache.h"
-
-
-
-/**
- * XXX colormask could be rolled into blending...
- */
-static void
-colormask_quad(struct quad_stage *qs, struct quad_header *quad)
-{
-   struct softpipe_context *softpipe = qs->softpipe;
-   uint cbuf;
-
-   /* loop over colorbuffer outputs */
-   for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
-      float dest[4][QUAD_SIZE];
-      struct softpipe_cached_tile *tile
-         = sp_get_cached_tile(softpipe->cbuf_cache[cbuf],
-                              quad->input.x0, quad->input.y0);
-      float (*quadColor)[4] = quad->output.color[cbuf];
-      uint i, j;
-
-      /* get/swizzle dest colors */
-      for (j = 0; j < QUAD_SIZE; j++) {
-         int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
-         int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
-         for (i = 0; i < 4; i++) {
-            dest[i][j] = tile->data.color[y][x][i];
-         }
-      }
-
-      /* R */
-      if (!(softpipe->blend->colormask & PIPE_MASK_R))
-          COPY_4V(quadColor[0], dest[0]);
-
-      /* G */
-      if (!(softpipe->blend->colormask & PIPE_MASK_G))
-          COPY_4V(quadColor[1], dest[1]);
-
-      /* B */
-      if (!(softpipe->blend->colormask & PIPE_MASK_B))
-          COPY_4V(quadColor[2], dest[2]);
-
-      /* A */
-      if (!(softpipe->blend->colormask & PIPE_MASK_A))
-          COPY_4V(quadColor[3], dest[3]);
-   }
-}
-
-static void
-colormask_quads(struct quad_stage *qs, struct quad_header *quads[],
-                unsigned nr)
-{
-   unsigned i;
-
-   for (i = 0; i < nr; i++)
-      colormask_quad(qs, quads[i]);
-
-   /* pass quad to next stage */
-   qs->next->run(qs->next, quads, nr);
-}
-
-
-
-static void colormask_begin(struct quad_stage *qs)
-{
-   qs->next->begin(qs->next);
-}
-
-
-static void colormask_destroy(struct quad_stage *qs)
-{
-   FREE( qs );
-}
-
-
-struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe )
-{
-   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
-
-   stage->softpipe = softpipe;
-   stage->begin = colormask_begin;
-   stage->run = colormask_quads;
-   stage->destroy = colormask_destroy;
-
-   return stage;
-}
index f06a385b3c24cee2eb892ea9bc8e62f172df03a1..989e997f81b440cd4577965de38e751ce3068a5a 100644 (file)
@@ -68,7 +68,6 @@ coverage_run(struct quad_stage *qs,
                struct quad_header *quads[],
                unsigned nr)
 {
-   struct softpipe_context *softpipe = qs->softpipe;
    unsigned i;
 
    for (i = 0; i < nr; i++)
diff --git a/src/gallium/drivers/softpipe/sp_quad_output.c b/src/gallium/drivers/softpipe/sp_quad_output.c
deleted file mode 100644 (file)
index 79a222f..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "util/u_memory.h"
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_surface.h"
-#include "sp_quad_pipe.h"
-#include "sp_tile_cache.h"
-
-
-/**
- * Last step of quad processing: write quad colors to the framebuffer,
- * taking mask into account.
- */
-static void
-output_quad(struct quad_stage *qs, struct quad_header *quads[], unsigned nr)
-{
-
-   struct softpipe_context *softpipe = qs->softpipe;
-   uint cbuf;
-
-   /* loop over colorbuffer outputs */
-   for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
-      struct softpipe_cached_tile *tile
-         = sp_get_cached_tile(softpipe->cbuf_cache[cbuf],
-                              quads[0]->input.x0, 
-                              quads[0]->input.y0);
-      int i, j, q;
-
-      /* get/swizzle dest colors */
-      for (q = 0; q < nr; q++) {
-         struct quad_header *quad = quads[q];
-         float (*quadColor)[4] = quad->output.color[cbuf];
-
-         /* in-tile pos: */
-         const int itx = quad->input.x0 % TILE_SIZE;
-         const int ity = quad->input.y0 % TILE_SIZE;
-
-         
-         for (j = 0; j < QUAD_SIZE; j++) {
-            if (quad->inout.mask & (1 << j)) {
-               int x = itx + (j & 1);
-               int y = ity + (j >> 1);
-               for (i = 0; i < 4; i++) { /* loop over color chans */
-                  tile->data.color[y][x][i] = quadColor[i][j];
-               }
-               if (0) {
-                  debug_printf("sp write pixel %d,%d: %g, %g, %g\n",
-                               quad->input.x0 + x,
-                               quad->input.y0 + y,
-                               quadColor[0][j],
-                               quadColor[1][j],
-                               quadColor[2][j]);
-               }
-            }
-         }
-      }
-   }
-}
-
-
-static void output_begin(struct quad_stage *qs)
-{
-   assert(qs->next == NULL);
-}
-
-
-static void output_destroy(struct quad_stage *qs)
-{
-   FREE( qs );
-}
-
-
-struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe )
-{
-   struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
-
-   stage->softpipe = softpipe;
-   stage->begin = output_begin;
-   stage->run = output_quad;
-   stage->destroy = output_destroy;
-
-   return stage;
-}
index 6fae7d552f80a4bdd57c30a1fff12b71d7470d60..d138d417acb639165c1b8453718b8ff8b396e280 100644 (file)
@@ -65,25 +65,16 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
 
    /* Color combine
     */
-   sp->quad.first = sp->quad.output;
-
-   if (sp->blend->colormask != 0xf) {
-      sp_push_quad_first( sp, sp->quad.colormask );
-   }
-
-   if (sp->blend->blend_enable ||
-       sp->blend->logicop_enable) {
-      sp_push_quad_first( sp, sp->quad.blend );
-   }
+   sp->quad.first = sp->quad.blend;
 
+   /* Shade/Depth/Stencil/Alpha
+    */
    if ((sp->rasterizer->poly_smooth && sp->reduced_prim == PIPE_PRIM_TRIANGLES) ||
        (sp->rasterizer->line_smooth && sp->reduced_prim == PIPE_PRIM_LINES) ||
        (sp->rasterizer->point_smooth && sp->reduced_prim == PIPE_PRIM_POINTS)) {
       sp_push_quad_first( sp, sp->quad.coverage );
    }
 
-   /* Shade/Depth/Stencil/Alpha
-    */
    if (sp->active_query_count) {
       sp_push_quad_first( sp, sp->quad.occlusion );
    }