summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@vmware.com>2017-11-18 06:23:35 +0100
committerRoland Scheidegger <sroland@vmware.com>2017-11-21 04:06:29 +0100
commitb5957cee920cd7a62e4e726538dbbe44c12e33ab (patch)
tree18f8df358fe595c18b033f83d0e896aebeaa651e /src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
parent464c2d80834e4ccf7f28fb62b82a2fa13e6445fb (diff)
llvmpipe: fix snorm blending
The blend math gets a bit funky due to inverse blend factors being in range [0,2] rather than [-1,1], our normalized math can't really cover this. src_alpha_saturate blend factor has a similar problem too. (Note that piglit fbo-blending-formats test is mostly useless for anything but unorm formats, since not just all src/dst values are between [0,1], but the tests are crafted in a way that the results are between [0,1] too.) v2: some formatting fixes, and fix a fairly obscure (to debug) issue with alpha-only formats (not related to snorm at all), where blend optimization would think it could simplify the blend equation if the blend factors were complementary, however was using the completely unrelated rgb blend factors instead of the alpha ones... Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c53
1 files changed, 33 insertions, 20 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
index 45c5c2bb65e..c16ef1a2e91 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
@@ -112,22 +112,34 @@ lp_build_blend_factor_unswizzled(struct lp_build_blend_aos_context *bld,
case PIPE_BLENDFACTOR_DST_ALPHA:
return bld->dst;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- if(alpha)
+ if (alpha)
return bld->base.one;
else {
/*
* If there's no dst alpha the complement is zero but for unclamped
- * float inputs min can be non-zero (negative).
+ * float inputs (or snorm inputs) min can be non-zero (negative).
*/
- if (!bld->has_dst_alpha) {
- if (!bld->saturate)
+ if (!bld->saturate) {
+ if (!bld->has_dst_alpha) {
bld->saturate = lp_build_min(&bld->base, src_alpha, bld->base.zero);
- }
- else {
- if(!bld->inv_dst)
- bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
- if(!bld->saturate)
+ }
+ else if (bld->base.type.norm && bld->base.type.sign) {
+ /*
+ * The complement/min totally doesn't work, since
+ * the complement is in range [0,2] but the other
+ * min input is [-1,1]. However, we can just clamp to 0
+ * before doing the complement...
+ */
+ LLVMValueRef inv_dst;
+ inv_dst = lp_build_max(&bld->base, bld->base.zero, bld->dst);
+ inv_dst = lp_build_comp(&bld->base, inv_dst);
+ bld->saturate = lp_build_min(&bld->base, src_alpha, inv_dst);
+ } else {
+ if (!bld->inv_dst) {
+ bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
+ }
bld->saturate = lp_build_min(&bld->base, src_alpha, bld->inv_dst);
+ }
}
return bld->saturate;
}
@@ -140,24 +152,24 @@ lp_build_blend_factor_unswizzled(struct lp_build_blend_aos_context *bld,
case PIPE_BLENDFACTOR_SRC1_ALPHA:
return src1_alpha;
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- if(!bld->inv_src)
+ if (!bld->inv_src)
bld->inv_src = lp_build_comp(&bld->base, bld->src);
return bld->inv_src;
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- if(!bld->inv_src_alpha)
+ if (!bld->inv_src_alpha)
bld->inv_src_alpha = lp_build_comp(&bld->base, src_alpha);
return bld->inv_src_alpha;
case PIPE_BLENDFACTOR_INV_DST_COLOR:
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- if(!bld->inv_dst)
+ if (!bld->inv_dst)
bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
return bld->inv_dst;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- if(!bld->inv_const)
+ if (!bld->inv_const)
bld->inv_const = lp_build_comp(&bld->base, bld->const_);
return bld->inv_const;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- if(!bld->inv_const_alpha)
+ if (!bld->inv_const_alpha)
bld->inv_const_alpha = lp_build_comp(&bld->base, const_alpha);
return bld->inv_const_alpha;
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
@@ -331,7 +343,7 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
bld.const_alpha = const_alpha;
bld.has_dst_alpha = FALSE;
- /* Find the alpha channel if not provided seperately */
+ /* Find the alpha channel if not provided separately */
if (!src_alpha) {
for (i = 0; i < 4; ++i) {
if (swizzle[i] == 3) {
@@ -349,7 +361,7 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
}
if (blend->logicop_enable) {
- if(!type.floating) {
+ if (!type.floating) {
result = lp_build_logicop(gallivm->builder, blend->logicop_func, src, dst);
}
else {
@@ -361,6 +373,7 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
boolean rgb_alpha_same = (state->rgb_src_factor == state->rgb_dst_factor &&
state->alpha_src_factor == state->alpha_dst_factor) ||
nr_channels == 1;
+ boolean alpha_only = nr_channels == 1 && alpha_swizzle == PIPE_SWIZZLE_X;
src_factor = lp_build_blend_factor(&bld, state->rgb_src_factor,
state->alpha_src_factor,
@@ -374,8 +387,8 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
result = lp_build_blend(&bld.base,
state->rgb_func,
- state->rgb_src_factor,
- state->rgb_dst_factor,
+ alpha_only ? state->alpha_src_factor : state->rgb_src_factor,
+ alpha_only ? state->alpha_dst_factor : state->rgb_dst_factor,
src,
dst,
src_factor,
@@ -383,8 +396,8 @@ lp_build_blend_aos(struct gallivm_state *gallivm,
rgb_alpha_same,
false);
- if(state->rgb_func != state->alpha_func && nr_channels > 1 &&
- alpha_swizzle != PIPE_SWIZZLE_NONE) {
+ if (state->rgb_func != state->alpha_func && nr_channels > 1 &&
+ alpha_swizzle != PIPE_SWIZZLE_NONE) {
LLVMValueRef alpha;
alpha = lp_build_blend(&bld.base,