Mesa (master): llvmpipe: Implement alpha_to_coverage for non-MSAA framebuffers.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Tue Jan 7 16:04:51 UTC 2014


Module: Mesa
Branch: master
Commit: 72c6d0e506ad0e8262dddbc7a7cf2d6813761753
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=72c6d0e506ad0e8262dddbc7a7cf2d6813761753

Author: Si Chen <sichen at vmware.com>
Date:   Wed Dec 18 02:17:55 2013 -0800

llvmpipe: Implement alpha_to_coverage for non-MSAA framebuffers.

Implement Alpha to Coverage by discarding a fragment alpha component is
less than 0.5.  This is a joint work of Jose and Si.

Reviewed-by: José Fonseca <jfonseca at vmware.com>
Reviewed-by: Roland Scheidegger <sroland at vmware.com>

---

 src/gallium/drivers/llvmpipe/lp_bld_blend.c |   30 +++++++++++++++++++++++++++
 src/gallium/drivers/llvmpipe/lp_bld_blend.h |    7 +++++++
 src/gallium/drivers/llvmpipe/lp_state_fs.c  |   23 +++++++++++++++++++-
 3 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.c b/src/gallium/drivers/llvmpipe/lp_bld_blend.c
index 1dab28c..1de43f7 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend.c
@@ -30,6 +30,11 @@
 
 #include "gallivm/lp_bld_type.h"
 #include "gallivm/lp_bld_arit.h"
+#include "gallivm/lp_bld_const.h"
+#include "gallivm/lp_bld_logic.h"
+#include "gallivm/lp_bld_swizzle.h"
+#include "gallivm/lp_bld_flow.h"
+#include "gallivm/lp_bld_debug.h"
 
 #include "lp_bld_blend.h"
 
@@ -191,3 +196,28 @@ lp_build_blend(struct lp_build_context *bld,
    dst_term = lp_build_mul(bld, dst, dst_factor);
    return lp_build_blend_func(bld, func, src_term, dst_term);
 }
+
+void
+lp_build_alpha_to_coverage(struct gallivm_state *gallivm,
+                           struct lp_type type,
+                           struct lp_build_mask_context *mask,
+                           LLVMValueRef alpha,
+                           boolean do_branch)
+{
+   struct lp_build_context bld;
+   LLVMValueRef test;
+   LLVMValueRef alpha_ref_value;
+
+   lp_build_context_init(&bld, gallivm, type);
+
+   alpha_ref_value = lp_build_const_vec(gallivm, type, 0.5);
+
+   test = lp_build_cmp(&bld, PIPE_FUNC_GREATER, alpha, alpha_ref_value);
+
+   lp_build_name(test, "alpha_to_coverage");
+
+   lp_build_mask_update(mask, test);
+
+   if (do_branch)
+      lp_build_mask_check(mask);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.h b/src/gallium/drivers/llvmpipe/lp_bld_blend.h
index 249a345..adfab85 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend.h
@@ -38,6 +38,7 @@
 struct pipe_blend_state;
 struct lp_type;
 struct lp_build_context;
+struct lp_build_mask_context;
 
 
 LLVMValueRef
@@ -99,5 +100,11 @@ lp_build_blend_func_reverse(unsigned rgb_func,
 boolean
 lp_build_blend_func_commutative(unsigned func);
 
+void
+lp_build_alpha_to_coverage(struct gallivm_state *gallivm,
+                           struct lp_type type,
+                           struct lp_build_mask_context *mask,
+                           LLVMValueRef alpha,
+                           boolean do_branch);
 
 #endif /* !LP_BLD_BLEND_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 2118c1a..eedafa3 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -296,7 +296,9 @@ generate_fs_loop(struct gallivm_state *gallivm,
       assert(zs_format_desc);
 
       if (!shader->info.base.writes_z) {
-         if (key->alpha.enabled || shader->info.base.uses_kill) {
+         if (key->alpha.enabled ||
+             key->blend.alpha_to_coverage ||
+             shader->info.base.uses_kill) {
             /* With alpha test and kill, can do the depth test early
              * and hopefully eliminate some quads.  But need to do a
              * special deferred depth write once the final mask value
@@ -438,6 +440,21 @@ generate_fs_loop(struct gallivm_state *gallivm,
       }
    }
 
+   /* Emulate Alpha to Coverage with Alpha test */
+   if (key->blend.alpha_to_coverage) {
+      int color0 = find_output_by_semantic(&shader->info.base,
+                                           TGSI_SEMANTIC_COLOR,
+                                           0);
+
+      if (color0 != -1 && outputs[color0][3]) {
+         LLVMValueRef alpha = LLVMBuildLoad(builder, outputs[color0][3], "alpha");
+
+         lp_build_alpha_to_coverage(gallivm, type,
+                                    &mask, alpha,
+                                    (depth_mode & LATE_DEPTH_TEST) != 0);
+      }
+   }
+
    /* Late Z test */
    if (depth_mode & LATE_DEPTH_TEST) {
       int pos0 = find_output_by_semantic(&shader->info.base,
@@ -2426,6 +2443,9 @@ dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key)
       debug_printf("blend.alpha_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE));
    }
    debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask);
+   if (key->blend.alpha_to_coverage) {
+      debug_printf("blend.alpha_to_coverage is enabled\n");
+   }
    for (i = 0; i < key->nr_samplers; ++i) {
       const struct lp_static_sampler_state *sampler = &key->state[i].sampler_state;
       debug_printf("sampler[%u] = \n", i);
@@ -2521,6 +2541,7 @@ generate_variant(struct llvmpipe_context *lp,
          fullcolormask &&
          !key->stencil[0].enabled &&
          !key->alpha.enabled &&
+         !key->blend.alpha_to_coverage &&
          !key->depth.enabled &&
          !shader->info.base.uses_kill
       ? TRUE : FALSE;




More information about the mesa-commit mailing list