i965: Fix SIN/COS precision problems.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 27 Jan 2016 20:21:04 +0000 (12:21 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 27 Jan 2016 21:56:54 +0000 (13:56 -0800)
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_fs_nir.cpp
src/mesa/drivers/dri/i965/brw_vec4_nir.cpp

index f41854c2c09664cd359c33f44099b38e1634c3e9..11e7c7dc10219ce8b1d5f66c38f3ef1cba2c4a5e 100644 (file)
@@ -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) {
index a608dca03ffd71fe4eb25df477903766f334abf4..2b261fcc9520e9cc88d0cf1048cec102ed856174 100644 (file)
@@ -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: