From a05bfff8cb2f1e55ba7e4e1363e1d2be97c07b91 Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Tue, 26 Apr 2022 13:23:03 -0700 Subject: [PATCH] r600/sfn: Implement 0*x=0 behavior for use_legacy_math_rules. The TGSI backend chooses these opcodes for LEGACY_MATH_RULES, so do the same thing here for ARB programs which want the same behavior. Acked-by: Kenneth Graunke Part-of: --- .../drivers/r600/sfn/sfn_emitaluinstruction.cpp | 15 +++++++++++---- .../drivers/r600/sfn/sfn_emitinstruction.cpp | 5 +++++ .../drivers/r600/sfn/sfn_emitinstruction.h | 1 + src/gallium/drivers/r600/sfn/sfn_shader_base.h | 4 ++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp b/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp index 2d6e9c3c249..306822552ba 100644 --- a/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp @@ -130,7 +130,10 @@ bool EmitAluInstruction::do_emit(nir_instr* ir) case nir_op_feq: return emit_alu_op2(instr, op2_sete_dx10); case nir_op_fexp2: return emit_alu_trans_op1(instr, op1_exp_ieee); case nir_op_ffloor: return emit_alu_op1(instr, op1_floor); - case nir_op_ffma: return emit_alu_op3(instr, op3_muladd_ieee); + case nir_op_ffma: + if (use_legacy_math_rules()) + return emit_alu_op2(instr, op3_muladd); + return emit_alu_op3(instr, op3_muladd_ieee); case nir_op_ffract: return emit_alu_op1(instr, op1_fract); case nir_op_fge32: return emit_alu_op2(instr, op2_setge_dx10); case nir_op_fge: return emit_alu_op2(instr, op2_setge_dx10); @@ -140,7 +143,10 @@ bool EmitAluInstruction::do_emit(nir_instr* ir) case nir_op_flt: return emit_alu_op2(instr, op2_setgt_dx10, op2_opt_reverse); case nir_op_fmax: return emit_alu_op2(instr, op2_max_dx10); case nir_op_fmin: return emit_alu_op2(instr, op2_min_dx10); - case nir_op_fmul: return emit_alu_op2(instr, op2_mul_ieee); + case nir_op_fmul: + if (use_legacy_math_rules()) + return emit_alu_op2(instr, op2_mul); + return emit_alu_op2(instr, op2_mul_ieee); case nir_op_fneg: return emit_alu_op1(instr, op1_mov, {1 << alu_src0_neg}); case nir_op_fneu32: return emit_alu_op2(instr, op2_setne_dx10); case nir_op_fneu: return emit_alu_op2(instr, op2_setne_dx10); @@ -593,10 +599,11 @@ bool EmitAluInstruction::emit_dot(const nir_alu_instr& instr, int n) { const nir_alu_src& src0 = instr.src[0]; const nir_alu_src& src1 = instr.src[1]; + EAluOp dot4_op = use_legacy_math_rules() ? op2_dot4 : op2_dot4_ieee; AluInstruction *ir = nullptr; for (int i = 0; i < n ; ++i) { - ir = new AluInstruction(op2_dot4_ieee, from_nir(instr.dest, i), + ir = new AluInstruction(dot4_op, from_nir(instr.dest, i), m_src[0][i], m_src[1][i], instr.dest.write_mask & (1 << i) ? write : empty); @@ -609,7 +616,7 @@ bool EmitAluInstruction::emit_dot(const nir_alu_instr& instr, int n) emit_instruction(ir); } for (int i = n; i < 4 ; ++i) { - ir = new AluInstruction(op2_dot4_ieee, from_nir(instr.dest, i), + ir = new AluInstruction(dot4_op, from_nir(instr.dest, i), Value::zero, Value::zero, instr.dest.write_mask & (1 << i) ? write : empty); emit_instruction(ir); diff --git a/src/gallium/drivers/r600/sfn/sfn_emitinstruction.cpp b/src/gallium/drivers/r600/sfn/sfn_emitinstruction.cpp index ee603789807..7978ff87da3 100644 --- a/src/gallium/drivers/r600/sfn/sfn_emitinstruction.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_emitinstruction.cpp @@ -45,6 +45,11 @@ bool EmitInstruction::emit(nir_instr* instr) return do_emit(instr); } +bool EmitInstruction::use_legacy_math_rules(void) +{ + return m_proc.use_legacy_math_rules(); +} + PValue EmitInstruction::from_nir(const nir_src& v, unsigned component, unsigned swizzled) { return m_proc.from_nir(v, component, swizzled); diff --git a/src/gallium/drivers/r600/sfn/sfn_emitinstruction.h b/src/gallium/drivers/r600/sfn/sfn_emitinstruction.h index ba3c4982533..79080a5e949 100644 --- a/src/gallium/drivers/r600/sfn/sfn_emitinstruction.h +++ b/src/gallium/drivers/r600/sfn/sfn_emitinstruction.h @@ -70,6 +70,7 @@ protected: bool emit_instruction(EAluOp opcode, PValue dest, std::vector src0, const std::set& m_flags); + bool use_legacy_math_rules(void); PValue from_nir_with_fetch_constant(const nir_src& src, unsigned component, int channel = -1); GPRVector vec_from_nir_with_fetch_constant(const nir_src& src, unsigned mask, diff --git a/src/gallium/drivers/r600/sfn/sfn_shader_base.h b/src/gallium/drivers/r600/sfn/sfn_shader_base.h index 4fbf136a69b..7109a10f104 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader_base.h +++ b/src/gallium/drivers/r600/sfn/sfn_shader_base.h @@ -73,6 +73,10 @@ public: void emit_export_instruction(WriteoutInstruction *ir); void emit_instruction(AluInstruction *ir); + bool use_legacy_math_rules(void) { + return m_sel.nir->info.use_legacy_math_rules; + }; + void split_constants(nir_alu_instr* instr); void remap_registers();