From: Si Chen Date: Wed, 18 Dec 2013 10:17:55 +0000 (-0800) Subject: llvmpipe: Implement alpha_to_coverage for non-MSAA framebuffers. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=72c6d0e506ad0e8262dddbc7a7cf2d6813761753;p=mesa.git 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 Reviewed-by: Roland Scheidegger --- 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;