From be93398a5b1a0323cbbd8dc826920ea11b1de0ab Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 15 Jan 2015 13:38:17 +0100 Subject: [PATCH] glsl: Fix modf() with infinity At least on Intel GPUs modf() with infinity returns NaN for the remainder. It does not seem like there is an easy way out of this, since ir_unop_fract also returns NaN for infinity arguments, so the only way to fix this seems to be adding a conditional that checks specifically for this case. Fixes the following 6 dEQP tests: dEQP-GLES3.functional.shaders.builtin_functions.precision.modf.lowp_vertex dEQP-GLES3.functional.shaders.builtin_functions.precision.modf.lowp_fragment dEQP-GLES3.functional.shaders.builtin_functions.precision.modf.mediump_vertex dEQP-GLES3.functional.shaders.builtin_functions.precision.modf.mediump_fragment dEQP-GLES3.functional.shaders.builtin_functions.precision.modf.highp_vertex dEQP-GLES3.functional.shaders.builtin_functions.precision.modf.highp_fragment --- src/glsl/builtin_functions.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp index bb7fbcd..510f3a0 100644 --- a/src/glsl/builtin_functions.cpp +++ b/src/glsl/builtin_functions.cpp @@ -2885,7 +2885,10 @@ builtin_builder::_modf(const glsl_type *type) ir_variable *t = body.make_temp(type, "t"); body.emit(assign(t, expr(ir_unop_trunc, x))); body.emit(assign(i, t)); - body.emit(ret(sub(x, t))); + body.emit(if_tree(equal(abs(x), + imm(std::numeric_limits::infinity())), + ret(imm(0.0f)), + ret(sub(x, t)))); return sig; } -- 1.9.1