<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Apr 3, 2016 at 5:34 PM, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The SIN and COS instructions on Intel hardware can produce values<br>
slightly outside of the [-1.0, 1.0] range for a small set of values.<br>
Obviously, this can break everyone's expectations about trig functions.<br>
<br>
According to an internal presentation, the COS instruction can produce<br>
a value up to 1.000027 for inputs in the range (0.08296, 0.09888).  One<br>
suggested workaround is to multiply by 0.99997, scaling down the<br>
amplitude slightly.  Apparently this also minimizes the error function,<br>
reducing the maximum error from 0.00006 to about 0.00003.<br>
<br>
When enabled, fixes 16 dEQP precision tests<br>
<br>
   dEQP-GLES31.functional.shaders.builtin_functions.precision.<br>
   {cos,sin}.{highp,mediump}_compute.{scalar,vec2,vec4,vec4}.<br>
<br>
at the cost of making every sin and cos call more expensive (about<br>
twice the number of cycles on recent hardware).  Enabling this<br>
option has been shown to reduce GPUTest Volplosion performance by<br>
about 10%.<br>
<br>
Signed-off-by: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>><br>
---<br>
 src/mesa/drivers/dri/i965/brw_compiler.c   |  2 ++<br>
 src/mesa/drivers/dri/i965/brw_compiler.h   |  6 ++++++<br>
 src/mesa/drivers/dri/i965/brw_fs_nir.cpp   | 16 ++++++++++++++--<br>
 src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 16 ++++++++++++++--<br>
 4 files changed, 36 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_compiler.c b/src/mesa/drivers/dri/i965/brw_compiler.c<br>
index 3da6aac..6509267 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_compiler.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_compiler.c<br>
@@ -147,6 +147,8 @@ brw_compiler_create(void *mem_ctx, const struct brw_device_info *devinfo)<br>
    brw_fs_alloc_reg_sets(compiler);<br>
    brw_vec4_alloc_reg_set(compiler);<br>
<br>
+   compiler->precise_trig = env_var_as_boolean("INTEL_PRECISE_TRIG", false);<br>
+<br>
    compiler->scalar_stage[MESA_SHADER_VERTEX] =<br>
       devinfo->gen >= 8 && !(INTEL_DEBUG & DEBUG_VEC4VS);<br>
    compiler->scalar_stage[MESA_SHADER_TESS_CTRL] = false;<br>
diff --git a/src/mesa/drivers/dri/i965/brw_compiler.h b/src/mesa/drivers/dri/i965/brw_compiler.h<br>
index 27a95a3..231e000 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_compiler.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_compiler.h<br>
@@ -92,6 +92,12 @@ struct brw_compiler {<br>
<br>
    bool scalar_stage[MESA_SHADER_STAGES];<br>
    struct gl_shader_compiler_options glsl_compiler_options[MESA_SHADER_STAGES];<br>
+<br>
+   /**<br>
+    * Apply workarounds for SIN and COS output range problems.<br>
+    * This can negatively impact performance.<br>
+    */<br>
+   bool precise_trig;<br></blockquote><div><br>This seems like the most reasonable thing to do<br><br></div><div>Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
 };<br>
<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
index 7839428..5cca91e 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
@@ -775,12 +775,24 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)<br>
       break;<br>
<br>
    case nir_op_fsin:<br>
-      inst = bld.emit(SHADER_OPCODE_SIN, result, op[0]);<br>
+      if (!compiler->precise_trig) {<br>
+         inst = bld.emit(SHADER_OPCODE_SIN, result, op[0]);<br>
+      } else {<br>
+         fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_F);<br>
+         inst = bld.emit(SHADER_OPCODE_SIN, tmp, op[0]);<br>
+         inst = bld.MUL(result, tmp, brw_imm_f(0.99997));<br>
+      }<br>
       inst->saturate = instr->dest.saturate;<br>
       break;<br>
<br>
    case nir_op_fcos:<br>
-      inst = bld.emit(SHADER_OPCODE_COS, result, op[0]);<br>
+      if (!compiler->precise_trig) {<br>
+         inst = bld.emit(SHADER_OPCODE_COS, result, op[0]);<br>
+      } else {<br>
+         fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_F);<br>
+         inst = bld.emit(SHADER_OPCODE_COS, tmp, op[0]);<br>
+         inst = bld.MUL(result, tmp, brw_imm_f(0.99997));<br>
+      }<br>
       inst->saturate = instr->dest.saturate;<br>
       break;<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp<br>
index ee6929b..6c8fd06 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp<br>
@@ -1101,12 +1101,24 @@ vec4_visitor::nir_emit_alu(nir_alu_instr *instr)<br>
       break;<br>
<br>
    case nir_op_fsin:<br>
-      inst = emit_math(SHADER_OPCODE_SIN, dst, op[0]);<br>
+      if (!compiler->precise_trig) {<br>
+         inst = emit_math(SHADER_OPCODE_SIN, dst, op[0]);<br>
+      } else {<br>
+         src_reg tmp = src_reg(this, glsl_type::vec4_type);<br>
+         inst = emit_math(SHADER_OPCODE_SIN, dst_reg(tmp), op[0]);<br>
+         inst = emit(MUL(dst, tmp, brw_imm_f(0.99997)));<br>
+      }<br>
       inst->saturate = instr->dest.saturate;<br>
       break;<br>
<br>
    case nir_op_fcos:<br>
-      inst = emit_math(SHADER_OPCODE_COS, dst, op[0]);<br>
+      if (!compiler->precise_trig) {<br>
+         inst = emit_math(SHADER_OPCODE_COS, dst, op[0]);<br>
+      } else {<br>
+         src_reg tmp = src_reg(this, glsl_type::vec4_type);<br>
+         inst = emit_math(SHADER_OPCODE_COS, dst_reg(tmp), op[0]);<br>
+         inst = emit(MUL(dst, tmp, brw_imm_f(0.99997)));<br>
+      }<br>
       inst->saturate = instr->dest.saturate;<br>
       break;<br>
<span class=""><font color="#888888"><br>
--<br>
2.7.4<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>