[Mesa-dev] [PATCH 1/2] i965/fs: fix precision of f2b
Iago Toral Quiroga
itoral at igalia.com
Thu Feb 25 10:15:48 UTC 2016
>From the OpenGL 4.2 spec:
"When a constructor is used to convert any integer or floating-point type to a
bool, 0 and 0.0 are converted to false, and non-zero values are converted to
true."
Thus, even the smallest non-zero floating value should be translated to true.
This behavior has been verified also with proprietary NVIDIA drivers.
Currently, we implement this conversion as a cmp.nz operation with floats,
subject to floating-point precision limitations, and as a result, relatively
small non-zero floating point numbers return false instead of true.
This patch fixes the problem by getting rid of the sign bit (to cover the case
of -0.0) and testing the result against 0u using an integer comparison instead.
---
src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index db20c71..7d62d7e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -913,9 +913,18 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
bld.MOV(result, negate(op[0]));
break;
- case nir_op_f2b:
- bld.CMP(result, op[0], brw_imm_f(0.0f), BRW_CONDITIONAL_NZ);
- break;
+ case nir_op_f2b: {
+ /* Because comparing to 0.0f is subject to precision limitations, do the
+ * comparison using integers (we need to get rid of the sign bit for that)
+ */
+ if (devinfo->gen >= 8)
+ op[0] = resolve_source_modifiers(op[0]);
+ op[0] = retype(op[0], BRW_REGISTER_TYPE_UD);
+ bld.AND(op[0], op[0], brw_imm_ud(0x7FFFFFFFu));
+ bld.CMP(result, op[0], brw_imm_ud(0u), BRW_CONDITIONAL_NZ);
+ break;
+ }
+
case nir_op_i2b:
bld.CMP(result, op[0], brw_imm_d(0), BRW_CONDITIONAL_NZ);
break;
--
1.9.1
More information about the mesa-dev
mailing list