[Mesa-dev] [PATCH 1/2] llvmpipe: first steps of adding dual source blend support

sroland at vmware.com sroland at vmware.com
Thu Feb 7 19:19:08 PST 2013


From: Roland Scheidegger <sroland at vmware.com>

This adds support of the additional blending factors to the blend function
itself, and also enables testing of it in lp_test_blend (which passes).
Still need to add the glue code of linking fs shader outputs to blend inputs
in llvmpipe, and probably need to add special handling if destination doesn't
include alpha (which lp_test_blend doesn't test).
---
 src/gallium/drivers/llvmpipe/lp_bld_blend.h     |    1 +
 src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c |   12 ++--
 src/gallium/drivers/llvmpipe/lp_state_fs.c      |    1 +
 src/gallium/drivers/llvmpipe/lp_test_blend.c    |   70 ++++++++++++++++-------
 4 files changed, 57 insertions(+), 27 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.h b/src/gallium/drivers/llvmpipe/lp_bld_blend.h
index 394935b..4bd2867 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend.h
@@ -61,6 +61,7 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
                    unsigned rt,
                    LLVMValueRef src,
                    LLVMValueRef src_alpha,
+                   LLVMValueRef src1,
                    LLVMValueRef dst,
                    LLVMValueRef mask,
                    LLVMValueRef const_,
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
index ccdf852..8e9e7fe 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
@@ -69,6 +69,7 @@ struct lp_build_blend_aos_context
 
    LLVMValueRef src;
    LLVMValueRef src_alpha;
+   LLVMValueRef src1;
    LLVMValueRef dst;
    LLVMValueRef const_;
    LLVMValueRef const_alpha;
@@ -123,9 +124,7 @@ lp_build_blend_factor_unswizzled(struct lp_build_blend_aos_context *bld,
       return const_alpha;
    case PIPE_BLENDFACTOR_SRC1_COLOR:
    case PIPE_BLENDFACTOR_SRC1_ALPHA:
-      /* TODO */
-      assert(0);
-      return bld->base.zero;
+      return bld->src1;
    case PIPE_BLENDFACTOR_INV_SRC_COLOR:
       if(!bld->inv_src)
          bld->inv_src = lp_build_comp(&bld->base, bld->src);
@@ -149,9 +148,7 @@ lp_build_blend_factor_unswizzled(struct lp_build_blend_aos_context *bld,
       return bld->inv_const_alpha;
    case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
    case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
-      /* TODO */
-      assert(0);
-      return bld->base.zero;
+      return lp_build_comp(&bld->base, bld->src1);
    default:
       assert(0);
       return bld->base.zero;
@@ -268,6 +265,7 @@ lp_build_blend_factor(struct lp_build_blend_aos_context *bld,
  * @param type          data type of the pixel vector
  * @param rt            render target index
  * @param src           blend src
+ * @param src1          second blend src (for dual source blend)
  * @param dst           blend dst
  * @param mask          optional mask to apply to the blending result
  * @param const_        const blend color
@@ -283,6 +281,7 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
                    unsigned rt,
                    LLVMValueRef src,
                    LLVMValueRef src_alpha,
+                   LLVMValueRef src1,
                    LLVMValueRef dst,
                    LLVMValueRef mask,
                    LLVMValueRef const_,
@@ -304,6 +303,7 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
    memset(&bld, 0, sizeof bld);
    lp_build_context_init(&bld.base, gallivm, type);
    bld.src = src;
+   bld.src1 = src1;
    bld.dst = dst;
    bld.const_ = const_;
    bld.src_alpha = src_alpha;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 90a67e6..2b31c14 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -1693,6 +1693,7 @@ generate_unswizzled_blend(struct gallivm_state *gallivm,
                                   rt,
                                   src[i],
                                   has_alpha ? NULL : src_alpha[i],
+                                  NULL,
                                   dst[i],
                                   partial_mask ? src_mask[i] : NULL,
                                   blend_color,
diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c
index 754434d..6faaedf 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c
@@ -45,7 +45,8 @@
 #include "lp_test.h"
 
 
-typedef void (*blend_test_ptr_t)(const void *src, const void *dst, const void *con, void *res);
+typedef void (*blend_test_ptr_t)(const void *src, const void *src1,
+                                 const void *dst, const void *con, void *res);
 
 
 void
@@ -138,9 +139,10 @@ add_blend_test(struct gallivm_state *gallivm,
    LLVMModuleRef module = gallivm->module;
    LLVMContextRef context = gallivm->context;
    LLVMTypeRef vec_type;
-   LLVMTypeRef args[4];
+   LLVMTypeRef args[5];
    LLVMValueRef func;
    LLVMValueRef src_ptr;
+   LLVMValueRef src1_ptr;
    LLVMValueRef dst_ptr;
    LLVMValueRef const_ptr;
    LLVMValueRef res_ptr;
@@ -150,29 +152,32 @@ add_blend_test(struct gallivm_state *gallivm,
    const unsigned rt = 0;
    const unsigned char swizzle[4] = { 0, 1, 2, 3 };
    LLVMValueRef src;
+   LLVMValueRef src1;
    LLVMValueRef dst;
    LLVMValueRef con;
    LLVMValueRef res;
 
    vec_type = lp_build_vec_type(gallivm, type);
 
-   args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0);
-   func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidTypeInContext(context), args, 4, 0));
+   args[4] = args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0);
+   func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidTypeInContext(context), args, 5, 0));
    LLVMSetFunctionCallConv(func, LLVMCCallConv);
    src_ptr = LLVMGetParam(func, 0);
-   dst_ptr = LLVMGetParam(func, 1);
-   const_ptr = LLVMGetParam(func, 2);
-   res_ptr = LLVMGetParam(func, 3);
+   src1_ptr = LLVMGetParam(func, 1);
+   dst_ptr = LLVMGetParam(func, 2);
+   const_ptr = LLVMGetParam(func, 3);
+   res_ptr = LLVMGetParam(func, 4);
 
    block = LLVMAppendBasicBlockInContext(context, func, "entry");
    builder = gallivm->builder;
    LLVMPositionBuilderAtEnd(builder, block);
 
    src = LLVMBuildLoad(builder, src_ptr, "src");
+   src1 = LLVMBuildLoad(builder, src1_ptr, "src1");
    dst = LLVMBuildLoad(builder, dst_ptr, "dst");
    con = LLVMBuildLoad(builder, const_ptr, "const");
 
-   res = lp_build_blend_aos(gallivm, blend, format, type, rt, src, NULL, dst, NULL, con, NULL, swizzle, 4);
+   res = lp_build_blend_aos(gallivm, blend, format, type, rt, src, NULL, src1, dst, NULL, con, NULL, swizzle, 4);
 
    lp_build_name(res, "res");
 
@@ -189,6 +194,7 @@ compute_blend_ref_term(unsigned rgb_factor,
                        unsigned alpha_factor,
                        const double *factor,
                        const double *src,
+                       const double *src1,
                        const double *dst,
                        const double *con,
                        double *term)
@@ -238,10 +244,14 @@ compute_blend_ref_term(unsigned rgb_factor,
       term[2] = factor[2] * con[3]; /* B */
       break;
    case PIPE_BLENDFACTOR_SRC1_COLOR:
-      assert(0); /* to do */
+      term[0] = factor[0] * src1[0]; /* R */
+      term[1] = factor[1] * src1[1]; /* G */
+      term[2] = factor[2] * src1[2]; /* B */
       break;
    case PIPE_BLENDFACTOR_SRC1_ALPHA:
-      assert(0); /* to do */
+      term[0] = factor[0] * src1[3]; /* R */
+      term[1] = factor[1] * src1[3]; /* G */
+      term[2] = factor[2] * src1[3]; /* B */
       break;
    case PIPE_BLENDFACTOR_ZERO:
       term[0] = 0.0f; /* R */
@@ -279,10 +289,14 @@ compute_blend_ref_term(unsigned rgb_factor,
       term[2] = factor[2] * (1.0f - con[3]); /* B */
       break;
    case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
-      assert(0); /* to do */
+      term[0] = factor[0] * (1.0f - src1[0]); /* R */
+      term[1] = factor[1] * (1.0f - src1[1]); /* G */
+      term[2] = factor[2] * (1.0f - src1[2]); /* B */
       break;
    case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
-      assert(0); /* to do */
+      term[0] = factor[0] * (1.0f - src1[3]); /* R */
+      term[1] = factor[1] * (1.0f - src1[3]); /* G */
+      term[2] = factor[2] * (1.0f - src1[3]); /* B */
       break;
    default:
       assert(0);
@@ -310,6 +324,10 @@ compute_blend_ref_term(unsigned rgb_factor,
    case PIPE_BLENDFACTOR_CONST_ALPHA:
       term[3] = factor[3] * con[3]; /* A */
       break;
+   case PIPE_BLENDFACTOR_SRC1_COLOR:
+   case PIPE_BLENDFACTOR_SRC1_ALPHA:
+      term[3] = factor[3] * src1[3]; /* A */
+      break;
    case PIPE_BLENDFACTOR_ZERO:
       term[3] = 0.0f; /* A */
       break;
@@ -325,6 +343,10 @@ compute_blend_ref_term(unsigned rgb_factor,
    case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
       term[3] = factor[3] * (1.0f - con[3]);
       break;
+   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+      term[3] = factor[3] * (1.0f - src1[3]); /* A */
+      break;
    default:
       assert(0);
    }
@@ -334,6 +356,7 @@ compute_blend_ref_term(unsigned rgb_factor,
 static void
 compute_blend_ref(const struct pipe_blend_state *blend,
                   const double *src,
+                  const double *src1,
                   const double *dst,
                   const double *con,
                   double *res)
@@ -342,9 +365,9 @@ compute_blend_ref(const struct pipe_blend_state *blend,
    double dst_term[4];
 
    compute_blend_ref_term(blend->rt[0].rgb_src_factor, blend->rt[0].alpha_src_factor,
-                          src, src, dst, con, src_term);
+                          src, src, src1, dst, con, src_term);
    compute_blend_ref_term(blend->rt[0].rgb_dst_factor, blend->rt[0].alpha_dst_factor,
-                          dst, src, dst, con, dst_term);
+                          dst, src, src1, dst, con, dst_term);
 
    /*
     * Combine RGB terms
@@ -435,8 +458,9 @@ test_one(unsigned verbose,
    success = TRUE;
 
    {
-      uint8_t *src, *dst, *con, *res, *ref;
+      uint8_t *src, *src1, *dst, *con, *res, *ref;
       src = align_malloc(stride, stride);
+      src1 = align_malloc(stride, stride);
       dst = align_malloc(stride, stride);
       con = align_malloc(stride, stride);
       res = align_malloc(stride, stride);
@@ -447,27 +471,30 @@ test_one(unsigned verbose,
          int64_t end_counter = 0;
 
          random_vec(type, src);
+         random_vec(type, src1);
          random_vec(type, dst);
          random_vec(type, con);
 
          {
             double fsrc[LP_MAX_VECTOR_LENGTH];
+            double fsrc1[LP_MAX_VECTOR_LENGTH];
             double fdst[LP_MAX_VECTOR_LENGTH];
             double fcon[LP_MAX_VECTOR_LENGTH];
             double fref[LP_MAX_VECTOR_LENGTH];
 
             read_vec(type, src, fsrc);
+            read_vec(type, src1, fsrc1);
             read_vec(type, dst, fdst);
             read_vec(type, con, fcon);
 
             for(j = 0; j < type.length; j += 4)
-               compute_blend_ref(blend, fsrc + j, fdst + j, fcon + j, fref + j);
+               compute_blend_ref(blend, fsrc + j, fsrc1 + j, fdst + j, fcon + j, fref + j);
 
             write_vec(type, ref, fref);
          }
 
          start_counter = rdtsc();
-         blend_test_ptr(src, dst, con, res);
+         blend_test_ptr(src, src1, dst, con, res);
          end_counter = rdtsc();
 
          cycles[i] = end_counter - start_counter;
@@ -483,6 +510,10 @@ test_one(unsigned verbose,
             dump_vec(stderr, type, src);
             fprintf(stderr, "\n");
 
+            fprintf(stderr, "  Src1: ");
+            dump_vec(stderr, type, src1);
+            fprintf(stderr, "\n");
+
             fprintf(stderr, "  Dst: ");
             dump_vec(stderr, type, dst);
             fprintf(stderr, "\n");
@@ -501,6 +532,7 @@ test_one(unsigned verbose,
          }
       }
       align_free(src);
+      align_free(src1);
       align_free(dst);
       align_free(con);
       align_free(res);
@@ -559,10 +591,8 @@ blend_factors[] = {
    PIPE_BLENDFACTOR_DST_ALPHA,
    PIPE_BLENDFACTOR_CONST_COLOR,
    PIPE_BLENDFACTOR_CONST_ALPHA,
-#if 0
    PIPE_BLENDFACTOR_SRC1_COLOR,
    PIPE_BLENDFACTOR_SRC1_ALPHA,
-#endif
    PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE,
    PIPE_BLENDFACTOR_INV_SRC_COLOR,
    PIPE_BLENDFACTOR_INV_SRC_ALPHA,
@@ -570,10 +600,8 @@ blend_factors[] = {
    PIPE_BLENDFACTOR_INV_DST_ALPHA,
    PIPE_BLENDFACTOR_INV_CONST_COLOR,
    PIPE_BLENDFACTOR_INV_CONST_ALPHA,
-#if 0
    PIPE_BLENDFACTOR_INV_SRC1_COLOR,
    PIPE_BLENDFACTOR_INV_SRC1_ALPHA,
-#endif
 };
 
 
-- 
1.7.9.5



More information about the mesa-dev mailing list