summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2016-01-27 12:21:04 -0800
committerKenneth Graunke <[email protected]>2016-01-27 13:56:54 -0800
commit4acfc9effbe4513075881a045bdfbec8ad2433a4 (patch)
tree152b2014bdae16a33405fe8f8bd964d3be228873
parentb833e7a63c0df2c6d4c24e11d8196c90bfd0906e (diff)
i965: Fix SIN/COS precision problems.
Signed-off-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_nir.cpp26
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_nir.cpp26
2 files changed, 40 insertions, 12 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index f41854c2c09..11e7c7dc102 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -715,15 +715,29 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
inst->saturate = instr->dest.saturate;
break;
- case nir_op_fsin:
- inst = bld.emit(SHADER_OPCODE_SIN, result, op[0]);
- inst->saturate = instr->dest.saturate;
+ case nir_op_fsin: {
+ fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_F);
+ inst = bld.emit(SHADER_OPCODE_SIN, tmp, op[0]);
+ if (instr->dest.saturate) {
+ inst->dst = result;
+ inst->saturate = true;
+ } else {
+ bld.MUL(result, tmp, brw_imm_f(0.99997));
+ }
break;
+ }
- case nir_op_fcos:
- inst = bld.emit(SHADER_OPCODE_COS, result, op[0]);
- inst->saturate = instr->dest.saturate;
+ case nir_op_fcos: {
+ fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_F);
+ inst = bld.emit(SHADER_OPCODE_COS, tmp, op[0]);
+ if (instr->dest.saturate) {
+ inst->dst = result;
+ inst->saturate = true;
+ } else {
+ bld.MUL(result, tmp, brw_imm_f(0.99997));
+ }
break;
+ }
case nir_op_fddx:
if (fs_key->high_quality_derivatives) {
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
index a608dca03ff..2b261fcc952 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
@@ -1086,15 +1086,29 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)
inst->saturate = instr->dest.saturate;
break;
- case nir_op_fsin:
- inst = emit_math(SHADER_OPCODE_SIN, dst, op[0]);
- inst->saturate = instr->dest.saturate;
+ case nir_op_fsin: {
+ src_reg tmp = src_reg(this, glsl_type::vec4_type);
+ inst = emit_math(SHADER_OPCODE_SIN, dst_reg(tmp), op[0]);
+ if (instr->dest.saturate) {
+ inst->dst = dst;
+ inst->saturate = true;
+ } else {
+ emit(MUL(dst, tmp, brw_imm_f(0.99997)));
+ }
break;
+ }
- case nir_op_fcos:
- inst = emit_math(SHADER_OPCODE_COS, dst, op[0]);
- inst->saturate = instr->dest.saturate;
+ case nir_op_fcos: {
+ src_reg tmp = src_reg(this, glsl_type::vec4_type);
+ inst = emit_math(SHADER_OPCODE_COS, dst_reg(tmp), op[0]);
+ if (instr->dest.saturate) {
+ inst->dst = dst;
+ inst->saturate = true;
+ } else {
+ emit(MUL(dst, tmp, brw_imm_f(0.99997)));
+ }
break;
+ }
case nir_op_idiv:
case nir_op_udiv: