summaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2016-10-27 20:12:56 -0700
committerEmil Velikov <emil.l.velikov@gmail.com>2016-11-01 12:47:32 +0000
commit0ff597c39b7330bef99fd76d0a2db5c1d8e7fb85 (patch)
tree357ca32c1d2d38c890ed1f895a7f5eaf8d60800f /src/compiler
parent89cefe6325b2534c4e35ac0a4b85155a3be57936 (diff)
downloadexternal_mesa3d-0ff597c39b7330bef99fd76d0a2db5c1d8e7fb85.zip
external_mesa3d-0ff597c39b7330bef99fd76d0a2db5c1d8e7fb85.tar.gz
external_mesa3d-0ff597c39b7330bef99fd76d0a2db5c1d8e7fb85.tar.bz2
glsl: Improve accuracy of alpha scaling in advanced blend lowering.
When blending with GL_COLORBURN_KHR and these colors: dst = <0.372549027, 0.372549027, 0.372549027, 0.372549027> src = <0.09375, 0.046875, 0.0, 0.375> the normalized dst value became 0.99999994 (due to precision problems in the floating point divide of rgb by alpha). This caused the color burn equation to fail the dst >= 1.0 comparison. The blue channel would then fall through to the dst < 1.0 && src >= 0 comparison, which was true, since src.b == 0. This produced a factor of 0.0 instead of 1.0. This is an inherent numerical instability in the color burn and dodge equations - depending on the precision of alpha scaling, the value can be either 0.0 or 1.0. Technically, GLSL floating point division doesn't even guarantee that 0.372549027 / 0.372549027 = 1.0. So arguably, the CTS should allow either value. I've filed a bug at Khronos for further discussion (linked below). In the meantime, this patch improves the precision of alpha scaling by replacing the division with (rgb == alpha ? 1.0 : rgb / alpha). We may not need this long term, but for now, it fixes the following CTS tests: ES31-CTS.blend_equation_advanced.blend_specific.GL_COLORBURN_KHR ES31-CTS.blend_equation_advanced.blend_all.GL_COLORBURN_KHR_all_qualifier Cc: currojerez@riseup.net Cc: mesa-stable@lists.freedesktop.org Bugzilla: https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16042 Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Eduardo Lima Mitev <elima@igalia.com> Reviewed-by: Francisco Jerez <currojerez@riseup.net> (cherry picked from commit e6aeeace6953a7007d98082e3f44bff40a44106d)
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/glsl/lower_blend_equation_advanced.cpp10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/compiler/glsl/lower_blend_equation_advanced.cpp b/src/compiler/glsl/lower_blend_equation_advanced.cpp
index 1d03392..f8210e3 100644
--- a/src/compiler/glsl/lower_blend_equation_advanced.cpp
+++ b/src/compiler/glsl/lower_blend_equation_advanced.cpp
@@ -308,12 +308,18 @@ calc_blend_result(ir_factory f,
f.emit(assign(dst_alpha, swizzle_w(fb)));
f.emit(if_tree(equal(dst_alpha, imm1(0)),
assign(dst_rgb, imm3(0)),
- assign(dst_rgb, div(swizzle_xyz(fb), dst_alpha))));
+ assign(dst_rgb, csel(equal(swizzle_xyz(fb),
+ swizzle(fb, SWIZZLE_WWWW, 3)),
+ imm3(1),
+ div(swizzle_xyz(fb), dst_alpha)))));
f.emit(assign(src_alpha, swizzle_w(src)));
f.emit(if_tree(equal(src_alpha, imm1(0)),
assign(src_rgb, imm3(0)),
- assign(src_rgb, div(swizzle_xyz(src), src_alpha))));
+ assign(src_rgb, csel(equal(swizzle_xyz(src),
+ swizzle(src, SWIZZLE_WWWW, 3)),
+ imm3(1),
+ div(swizzle_xyz(src), src_alpha)))));
ir_variable *factor = f.make_temp(glsl_type::vec3_type, "__blend_factor");