From: Kenneth Graunke Date: Wed, 27 Jan 2016 20:21:04 +0000 (-0800) Subject: i965: Fix SIN/COS precision problems. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4acfc9effbe4513075881a045bdfbec8ad2433a4;p=mesa.git i965: Fix SIN/COS precision problems. Signed-off-by: Kenneth Graunke --- 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: