summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2016-01-27 14:20:47 -0800
committerKenneth Graunke <[email protected]>2016-01-27 14:21:08 -0800
commitf92a35d831cf54f2244d5510932fd17c97b02ce4 (patch)
treef87e0fd756b00cd9a202756c933bb5c5c309518b /src/glsl
parent4acfc9effbe4513075881a045bdfbec8ad2433a4 (diff)
vtn: Fix Modf.
We were botching this for negative numbers - floor of a negative rounds the wrong way. Additionally, both results are supposed to retain the sign of the original. To fix this, just take the abs of both values, then put the sign back. There's probably a better way to do this, but this works for now.
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/nir/spirv/vtn_glsl450.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/glsl/nir/spirv/vtn_glsl450.c b/src/glsl/nir/spirv/vtn_glsl450.c
index 515a743fe48..b98ef052cbf 100644
--- a/src/glsl/nir/spirv/vtn_glsl450.c
+++ b/src/glsl/nir/spirv/vtn_glsl450.c
@@ -418,16 +418,20 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
case GLSLstd450InverseSqrt: op = nir_op_frsq; break;
case GLSLstd450Modf: {
- val->ssa->def = nir_ffract(nb, src[0]);
+ nir_ssa_def *sign = nir_fsign(nb, src[0]);
+ nir_ssa_def *abs = nir_fabs(nb, src[0]);
+ val->ssa->def = nir_fmul(nb, sign, nir_ffract(nb, abs));
nir_store_deref_var(nb, vtn_nir_deref(b, w[6]),
- nir_ffloor(nb, src[0]), 0xf);
+ nir_fmul(nb, sign, nir_ffloor(nb, abs)), 0xf);
return;
}
case GLSLstd450ModfStruct: {
+ nir_ssa_def *sign = nir_fsign(nb, src[0]);
+ nir_ssa_def *abs = nir_fabs(nb, src[0]);
assert(glsl_type_is_struct(val->ssa->type));
- val->ssa->elems[0]->def = nir_ffract(nb, src[0]);
- val->ssa->elems[1]->def = nir_ffloor(nb, src[0]);
+ val->ssa->elems[0]->def = nir_fmul(nb, sign, nir_ffract(nb, abs));
+ val->ssa->elems[1]->def = nir_fmul(nb, sign, nir_ffloor(nb, abs));
return;
}