summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorSi Chen <[email protected]>2013-12-18 02:17:55 -0800
committerJosé Fonseca <[email protected]>2014-01-07 16:04:42 +0000
commit72c6d0e506ad0e8262dddbc7a7cf2d6813761753 (patch)
treee05ac43e669da8a3cf09a7631e9fbb0d171623e4 /src/gallium/drivers
parent2a0fb946e147f5482c93702fbf46ffdf5208f57c (diff)
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 <[email protected]> Reviewed-by: Roland Scheidegger <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend.c30
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend.h7
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c23
3 files changed, 59 insertions, 1 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.c b/src/gallium/drivers/llvmpipe/lp_bld_blend.c
index 1dab28cedfb..1de43f77ee0 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 249a3454159..adfab85dc09 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 2118c1ab489..eedafa36838 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;