llvmpipe: Code generate color masking.
authorJosé Fonseca <jfonseca@vmware.com>
Sun, 9 Aug 2009 22:34:01 +0000 (23:34 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 29 Aug 2009 08:21:27 +0000 (09:21 +0100)
src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
src/gallium/drivers/llvmpipe/lp_quad_blend.c
src/gallium/drivers/llvmpipe/lp_test_blend.c

index a9ea2f4..abdad3e 100644 (file)
@@ -302,6 +302,9 @@ lp_build_blend_aos(LLVMBuilderRef builder,
    LLVMValueRef src_term;
    LLVMValueRef dst_term;
 
+   /* FIXME */
+   assert(blend->colormask == 0xf);
+
    if(!blend->blend_enable)
       return src;
 
index 44c5a51..37253a6 100644 (file)
@@ -65,12 +65,12 @@ struct lp_build_blend_soa_context
     * We store all factors in a table in order to eliminate redundant
     * multiplications later.
     */
-   LLVMValueRef factor[2][8];
+   LLVMValueRef factor[2][2][4];
 
    /**
     * Table with all terms.
     */
-   LLVMValueRef term[8];
+   LLVMValueRef term[2][4];
 };
 
 
@@ -165,16 +165,7 @@ lp_build_blend_soa(LLVMBuilderRef builder,
                    LLVMValueRef res[4])
 {
    struct lp_build_blend_soa_context bld;
-   unsigned i, j;
-
-   if(!blend->blend_enable) {
-      for (i = 0; i < 4; ++i)
-         res[i] = src[i];
-      return;
-   }
-
-   /* It makes no sense to blend unless values are normalized */
-   assert(type.norm);
+   unsigned i, j, k;
 
    /* Setup build context */
    memset(&bld, 0, sizeof bld);
@@ -185,62 +176,75 @@ lp_build_blend_soa(LLVMBuilderRef builder,
       bld.con[i] = con[i];
    }
 
-   /*
-    * Compute src/dst factors.
-    */
    for (i = 0; i < 4; ++i) {
-      unsigned src_factor = i < 3 ? blend->rgb_src_factor : blend->alpha_src_factor;
-      unsigned dst_factor = i < 3 ? blend->rgb_dst_factor : blend->alpha_dst_factor;
-      bld.factor[0][0 + i] = src[i];
-      bld.factor[1][0 + i] = lp_build_blend_soa_factor(&bld, src_factor, i);
-      bld.factor[0][4 + i] = dst[i];
-      bld.factor[1][4 + i] = lp_build_blend_soa_factor(&bld, dst_factor, i);
-   }
-
-   /*
-    * Compute src/dst terms
-    */
-   for (i = 0; i < 8; ++i) {
-
-      /* See if this multiplication has been previously computed */
-      for(j = 0; j < i; ++j) {
-         if((bld.factor[0][j] == bld.factor[0][i] &&
-             bld.factor[1][j] == bld.factor[1][i]) ||
-            (bld.factor[0][j] == bld.factor[1][i] &&
-             bld.factor[1][j] == bld.factor[0][i]))
-            break;
+      if (blend->colormask & (1 << i)) {
+         if (blend->blend_enable) {
+            unsigned src_factor = i < 3 ? blend->rgb_src_factor : blend->alpha_src_factor;
+            unsigned dst_factor = i < 3 ? blend->rgb_dst_factor : blend->alpha_dst_factor;
+            unsigned func = i < 3 ? blend->rgb_func : blend->alpha_func;
+            boolean func_commutative = lp_build_blend_func_commutative(func);
+
+            /* It makes no sense to blend unless values are normalized */
+            assert(type.norm);
+
+            /*
+             * Compute src/dst factors.
+             */
+
+            bld.factor[0][0][i] = src[i];
+            bld.factor[0][1][i] = lp_build_blend_soa_factor(&bld, src_factor, i);
+            bld.factor[1][0][i] = dst[i];
+            bld.factor[1][1][i] = lp_build_blend_soa_factor(&bld, dst_factor, i);
+
+            /*
+             * Compute src/dst terms
+             */
+
+            for(k = 0; k < 2; ++k) {
+               /* See if this multiplication has been previously computed */
+               for(j = 0; j < i; ++j) {
+                  if((bld.factor[k][0][j] == bld.factor[k][0][i] &&
+                      bld.factor[k][1][j] == bld.factor[k][1][i]) ||
+                     (bld.factor[k][0][j] == bld.factor[k][1][i] &&
+                      bld.factor[k][1][j] == bld.factor[k][0][i]))
+                     break;
+               }
+
+               if(j < i)
+                  bld.term[k][i] = bld.term[k][j];
+               else
+                  bld.term[k][i] = lp_build_mul(&bld.base, bld.factor[k][0][i], bld.factor[k][1][i]);
+            }
+
+            /*
+             * Combine terms
+             */
+
+            /* See if this function has been previously applied */
+            for(j = 0; j < i; ++j) {
+               unsigned prev_func = j < 3 ? blend->rgb_func : blend->alpha_func;
+               unsigned func_reverse = lp_build_blend_func_reverse(func, prev_func);
+
+               if((!func_reverse &&
+                   bld.term[0][j] == bld.term[0][i] &&
+                   bld.term[1][j] == bld.term[1][i]) ||
+                  ((func_commutative || func_reverse) &&
+                   bld.term[0][j] == bld.term[1][i] &&
+                   bld.term[1][j] == bld.term[0][i]))
+                  break;
+            }
+
+            if(j < i)
+               res[i] = res[j];
+            else
+               res[i] = lp_build_blend_func(&bld.base, func, bld.term[0][i], bld.term[1][i]);
+         }
+         else {
+            res[i] = src[i];
+         }
       }
-
-      if(j < i)
-         bld.term[i] = bld.term[j];
-      else
-         bld.term[i] = lp_build_mul(&bld.base, bld.factor[0][i], bld.factor[1][i]);
-   }
-
-   /*
-    * Combine terms
-    */
-   for (i = 0; i < 4; ++i) {
-      unsigned func = i < 3 ? blend->rgb_func : blend->alpha_func;
-      boolean func_commutative = lp_build_blend_func_commutative(func);
-
-      /* See if this function has been previously applied */
-      for(j = 0; j < i; ++j) {
-         unsigned prev_func = j < 3 ? blend->rgb_func : blend->alpha_func;
-         unsigned func_reverse = lp_build_blend_func_reverse(func, prev_func);
-
-         if((!func_reverse &&
-             bld.factor[0 + j] == bld.factor[0 + i] &&
-             bld.factor[4 + j] == bld.factor[4 + i]) ||
-            ((func_commutative || func_reverse) &&
-             bld.factor[0 + j] == bld.factor[4 + i] &&
-             bld.factor[4 + j] == bld.factor[0 + i]))
-            break;
+      else {
+         res[i] = dst[i];
       }
-
-      if(j < i)
-         res[i] = res[j];
-      else
-         res[i] = lp_build_blend_func(&bld.base, func, bld.term[i + 0], bld.term[i + 4]);
    }
 }
index fa2e902..2f4c46d 100644 (file)
@@ -148,31 +148,6 @@ logicop_quad(struct quad_stage *qs,
 }
 
 
-static void
-colormask_quad(struct quad_stage *qs,
-               float (*quadColor)[4],
-               float (*dest)[4])
-{
-   struct llvmpipe_context *llvmpipe = qs->llvmpipe;
-
-   /* R */
-   if (!(llvmpipe->blend->base.colormask & PIPE_MASK_R))
-      COPY_4V(quadColor[0], dest[0]);
-
-   /* G */
-   if (!(llvmpipe->blend->base.colormask & PIPE_MASK_G))
-      COPY_4V(quadColor[1], dest[1]);
-
-   /* B */
-   if (!(llvmpipe->blend->base.colormask & PIPE_MASK_B))
-      COPY_4V(quadColor[2], dest[2]);
-
-   /* A */
-   if (!(llvmpipe->blend->base.colormask & PIPE_MASK_A))
-      COPY_4V(quadColor[3], dest[3]);
-}
-
-
 static void blend_begin(struct quad_stage *qs)
 {
 }
@@ -225,9 +200,6 @@ blend_run(struct quad_stage *qs,
                blend->jit_function( quadColor, dest, llvmpipe->blend_color, quadColor );
          }
 
-         if (blend->base.colormask != 0xf)
-            colormask_quad( qs, quadColor, dest );
-   
          /* Output color values
           */
          for (j = 0; j < QUAD_SIZE; j++) {
index 5a09df5..645d388 100644 (file)
@@ -811,6 +811,7 @@ test_all(unsigned verbose, FILE *fp)
                            blend.alpha_func        = *alpha_func;
                            blend.alpha_src_factor  = *alpha_src_factor;
                            blend.alpha_dst_factor  = *alpha_dst_factor;
+                           blend.colormask         = PIPE_MASK_RGBA;
 
                            if(!test_one(verbose, fp, &blend, mode, *type))
                              success = FALSE;
@@ -869,6 +870,7 @@ test_some(unsigned verbose, FILE *fp, unsigned long n)
       blend.alpha_func        = *alpha_func;
       blend.alpha_src_factor  = *alpha_src_factor;
       blend.alpha_dst_factor  = *alpha_dst_factor;
+      blend.colormask         = PIPE_MASK_RGBA;
 
       if(!test_one(verbose, fp, &blend, mode, *type))
         success = FALSE;