llvmpipe: fix up indexing of blend/colormask state for render targets
authorBrian Paul <brianp@vmware.com>
Mon, 10 May 2010 23:02:06 +0000 (17:02 -0600)
committerBrian Paul <brianp@vmware.com>
Mon, 10 May 2010 23:04:19 +0000 (17:04 -0600)
src/gallium/drivers/llvmpipe/lp_bld_blend.h
src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/llvmpipe/lp_test_blend.c

index b2ada10a3d68ca0dfebf2a1ba0feb1540597ab15..5cecec3d7f9f5a7b3757c3c168ec70ea9962b3f7 100644 (file)
@@ -64,6 +64,7 @@ LLVMValueRef
 lp_build_blend_aos(LLVMBuilderRef builder,
                    const struct pipe_blend_state *blend,
                    struct lp_type type,
+                   unsigned rt,
                    LLVMValueRef src,
                    LLVMValueRef dst,
                    LLVMValueRef const_,
@@ -74,6 +75,7 @@ void
 lp_build_blend_soa(LLVMBuilderRef builder,
                    const struct pipe_blend_state *blend,
                    struct lp_type type,
+                   unsigned rt,
                    LLVMValueRef src[4],
                    LLVMValueRef dst[4],
                    LLVMValueRef const_[4],
index 44c28c1739a10fe0bef07b4f1fedd84b8d7cc4d4..70d08e71f6ecf660351cef812335eafc30acdb5c 100644 (file)
@@ -308,6 +308,7 @@ LLVMValueRef
 lp_build_blend_aos(LLVMBuilderRef builder,
                    const struct pipe_blend_state *blend,
                    struct lp_type type,
+                   unsigned rt,
                    LLVMValueRef src,
                    LLVMValueRef dst,
                    LLVMValueRef const_,
@@ -317,11 +318,10 @@ lp_build_blend_aos(LLVMBuilderRef builder,
    LLVMValueRef src_term;
    LLVMValueRef dst_term;
 
-   /* FIXME */
-   assert(blend->independent_blend_enable == 0);
-   assert(blend->rt[0].colormask == 0xf);
+   /* FIXME: color masking not implemented yet */
+   assert(blend->rt[rt].colormask == 0xf);
 
-   if(!blend->rt[0].blend_enable)
+   if(!blend->rt[rt].blend_enable)
       return src;
 
    /* It makes no sense to blend unless values are normalized */
@@ -338,16 +338,16 @@ lp_build_blend_aos(LLVMBuilderRef builder,
     * combinations it is possible to reorder the operations and therefore saving
     * some instructions. */
 
-   src_term = lp_build_blend_factor(&bld, src, blend->rt[0].rgb_src_factor,
-                                    blend->rt[0].alpha_src_factor, alpha_swizzle);
-   dst_term = lp_build_blend_factor(&bld, dst, blend->rt[0].rgb_dst_factor,
-                                    blend->rt[0].alpha_dst_factor, alpha_swizzle);
+   src_term = lp_build_blend_factor(&bld, src, blend->rt[rt].rgb_src_factor,
+                                    blend->rt[rt].alpha_src_factor, alpha_swizzle);
+   dst_term = lp_build_blend_factor(&bld, dst, blend->rt[rt].rgb_dst_factor,
+                                    blend->rt[rt].alpha_dst_factor, alpha_swizzle);
 
    lp_build_name(src_term, "src_term");
    lp_build_name(dst_term, "dst_term");
 
-   if(blend->rt[0].rgb_func == blend->rt[0].alpha_func) {
-      return lp_build_blend_func(&bld.base, blend->rt[0].rgb_func, src_term, dst_term);
+   if(blend->rt[rt].rgb_func == blend->rt[rt].alpha_func) {
+      return lp_build_blend_func(&bld.base, blend->rt[rt].rgb_func, src_term, dst_term);
    }
    else {
       /* Seperate RGB / A functions */
@@ -355,8 +355,8 @@ lp_build_blend_aos(LLVMBuilderRef builder,
       LLVMValueRef rgb;
       LLVMValueRef alpha;
 
-      rgb   = lp_build_blend_func(&bld.base, blend->rt[0].rgb_func,   src_term, dst_term);
-      alpha = lp_build_blend_func(&bld.base, blend->rt[0].alpha_func, src_term, dst_term);
+      rgb   = lp_build_blend_func(&bld.base, blend->rt[rt].rgb_func,   src_term, dst_term);
+      alpha = lp_build_blend_func(&bld.base, blend->rt[rt].alpha_func, src_term, dst_term);
 
       return lp_build_blend_swizzle(&bld, rgb, alpha, LP_BUILD_BLEND_SWIZZLE_RGBA, alpha_swizzle);
    }
index d95e6a6b68e32ade4f890e6d758ad3492c8b3f50..b9c7a6ceed63c8bf5708a16a8291ef9b46352618 100644 (file)
@@ -197,6 +197,7 @@ lp_build_blend_soa_factor(struct lp_build_blend_soa_context *bld,
 
 /**
  * Generate blend code in SOA mode.
+ * \param rt  render target index (to index the blend / colormask state)
  * \param src  src/fragment color
  * \param dst  dst/framebuffer color
  * \param con  constant blend color
@@ -206,6 +207,7 @@ void
 lp_build_blend_soa(LLVMBuilderRef builder,
                    const struct pipe_blend_state *blend,
                    struct lp_type type,
+                   unsigned rt,
                    LLVMValueRef src[4],
                    LLVMValueRef dst[4],
                    LLVMValueRef con[4],
@@ -214,6 +216,8 @@ lp_build_blend_soa(LLVMBuilderRef builder,
    struct lp_build_blend_soa_context bld;
    unsigned i, j, k;
 
+   assert(rt < PIPE_MAX_COLOR_BUFS);
+
    /* Setup build context */
    memset(&bld, 0, sizeof bld);
    lp_build_context_init(&bld.base, builder, type);
@@ -225,7 +229,7 @@ lp_build_blend_soa(LLVMBuilderRef builder,
 
    for (i = 0; i < 4; ++i) {
       /* only compute blending for the color channels enabled for writing */
-      if (blend->rt[0].colormask & (1 << i)) {
+      if (blend->rt[rt].colormask & (1 << i)) {
          if (blend->logicop_enable) {
             if(!type.floating) {
                res[i] = lp_build_logicop(builder, blend->logicop_func, src[i], dst[i]);
@@ -233,10 +237,10 @@ lp_build_blend_soa(LLVMBuilderRef builder,
             else
                res[i] = dst[i];
          }
-         else if (blend->rt[0].blend_enable) {
-            unsigned src_factor = i < 3 ? blend->rt[0].rgb_src_factor : blend->rt[0].alpha_src_factor;
-            unsigned dst_factor = i < 3 ? blend->rt[0].rgb_dst_factor : blend->rt[0].alpha_dst_factor;
-            unsigned func = i < 3 ? blend->rt[0].rgb_func : blend->rt[0].alpha_func;
+         else if (blend->rt[rt].blend_enable) {
+            unsigned src_factor = i < 3 ? blend->rt[rt].rgb_src_factor : blend->rt[rt].alpha_src_factor;
+            unsigned dst_factor = i < 3 ? blend->rt[rt].rgb_dst_factor : blend->rt[rt].alpha_dst_factor;
+            unsigned func = i < 3 ? blend->rt[rt].rgb_func : blend->rt[rt].alpha_func;
             boolean func_commutative = lp_build_blend_func_commutative(func);
 
             /* It makes no sense to blend unless values are normalized */
@@ -294,7 +298,7 @@ lp_build_blend_soa(LLVMBuilderRef builder,
 
             /* See if this function has been previously applied */
             for(j = 0; j < i; ++j) {
-               unsigned prev_func = j < 3 ? blend->rt[0].rgb_func : blend->rt[0].alpha_func;
+               unsigned prev_func = j < 3 ? blend->rt[rt].rgb_func : blend->rt[rt].alpha_func;
                unsigned func_reverse = lp_build_blend_func_reverse(func, prev_func);
 
                if((!func_reverse &&
index 43016ce4c4ceffcab0fc5261e252f7c46b1e2965..09a680bf9881baefcd02aff888e380e6f8663ec9 100644 (file)
@@ -475,6 +475,7 @@ generate_fs(struct llvmpipe_context *lp,
                      consts_ptr, interp->pos, interp->inputs,
                      outputs, sampler, &shader->info);
 
+   /* loop over fragment shader outputs/results */
    for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
       for(chan = 0; chan < NUM_CHANNELS; ++chan) {
          if(outputs[attrib][chan]) {
@@ -531,9 +532,16 @@ generate_fs(struct llvmpipe_context *lp,
 
 /**
  * Generate color blending and color output.
+ * \param rt  the render target index (to index blend, colormask state)
+ * \param type  the pixel color type
+ * \param context_ptr  pointer to the runtime JIT context
+ * \param mask  execution mask (active fragment/pixel mask)
+ * \param src  colors from the fragment shader
+ * \param dst_ptr  the destination color buffer pointer
  */
 static void
 generate_blend(const struct pipe_blend_state *blend,
+               unsigned rt,
                LLVMBuilderRef builder,
                struct lp_type type,
                LLVMValueRef context_ptr,
@@ -564,6 +572,7 @@ generate_blend(const struct pipe_blend_state *blend,
    const_ptr = LLVMBuildBitCast(builder, const_ptr,
                                 LLVMPointerType(vec_type, 0), "");
 
+   /* load constant blend color and colors from the dest color buffer */
    for(chan = 0; chan < 4; ++chan) {
       LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
       con[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
@@ -574,10 +583,12 @@ generate_blend(const struct pipe_blend_state *blend,
       lp_build_name(dst[chan], "dst.%c", "rgba"[chan]);
    }
 
-   lp_build_blend_soa(builder, blend, type, src, dst, con, res);
+   /* do blend */
+   lp_build_blend_soa(builder, blend, type, rt, src, dst, con, res);
 
+   /* store results to color buffer */
    for(chan = 0; chan < 4; ++chan) {
-      if(blend->rt[0].colormask & (1 << chan)) {
+      if(blend->rt[rt].colormask & (1 << chan)) {
          LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
          lp_build_name(res[chan], "res.%c", "rgba"[chan]);
          res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]);
@@ -644,7 +655,6 @@ generate_fragment(struct llvmpipe_context *lp,
    LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH];
    LLVMValueRef fs_out_color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][LP_MAX_VECTOR_LENGTH];
    LLVMValueRef blend_mask;
-   LLVMValueRef blend_in_color[NUM_CHANNELS];
    LLVMValueRef function;
    LLVMValueRef facing;
    unsigned num_fs;
@@ -738,7 +748,7 @@ generate_fragment(struct llvmpipe_context *lp,
    lp_build_name(a0_ptr, "a0");
    lp_build_name(dadx_ptr, "dadx");
    lp_build_name(dady_ptr, "dady");
-   lp_build_name(color_ptr_ptr, "color_ptr");
+   lp_build_name(color_ptr_ptr, "color_ptr_ptr");
    lp_build_name(depth_ptr, "depth");
    lp_build_name(c0, "c0");
    lp_build_name(c1, "c1");
@@ -810,6 +820,8 @@ generate_fragment(struct llvmpipe_context *lp,
    for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
       LLVMValueRef color_ptr;
       LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), cbuf, 0);
+      LLVMValueRef blend_in_color[NUM_CHANNELS];
+      unsigned rt;
 
       /* 
        * Convert the fs's output color and mask to fit to the blending type. 
@@ -830,10 +842,14 @@ generate_fragment(struct llvmpipe_context *lp,
                                "");
       lp_build_name(color_ptr, "color_ptr%d", cbuf);
 
+      /* which blend/colormask state to use */
+      rt = key->blend.independent_blend_enable ? cbuf : 0;
+
       /*
        * Blending.
        */
       generate_blend(&key->blend,
+                     rt,
                     builder,
                     blend_type,
                     context_ptr,
index fae7bf3fcf2ef6a5f1cc35dc7255c0ba818b96a5..d32a9223cdaf9d2c9a050ffd4c5a18d73c9bf5b6 100644 (file)
@@ -163,6 +163,7 @@ add_blend_test(LLVMModuleRef module,
    LLVMValueRef res_ptr;
    LLVMBasicBlockRef block;
    LLVMBuilderRef builder;
+   const unsigned rt = 0;
 
    vec_type = lp_build_vec_type(type);
 
@@ -188,7 +189,7 @@ add_blend_test(LLVMModuleRef module,
       dst = LLVMBuildLoad(builder, dst_ptr, "dst");
       con = LLVMBuildLoad(builder, const_ptr, "const");
 
-      res = lp_build_blend_aos(builder, blend, type, src, dst, con, 3);
+      res = lp_build_blend_aos(builder, blend, type, rt, src, dst, con, 3);
 
       lp_build_name(res, "res");
 
@@ -212,7 +213,7 @@ add_blend_test(LLVMModuleRef module,
          lp_build_name(dst[i], "dst.%c", "rgba"[i]);
       }
 
-      lp_build_blend_soa(builder, blend, type, src, dst, con, res);
+      lp_build_blend_soa(builder, blend, type, rt, src, dst, con, res);
 
       for(i = 0; i < 4; ++i) {
          LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);