Mesa (main): r600/sfn: Implement 0*x=0 behavior for use_legacy_math_rules.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jun 10 03:54:57 UTC 2022


Module: Mesa
Branch: main
Commit: a05bfff8cb2f1e55ba7e4e1363e1d2be97c07b91
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a05bfff8cb2f1e55ba7e4e1363e1d2be97c07b91

Author: Emma Anholt <emma at anholt.net>
Date:   Tue Apr 26 13:23:03 2022 -0700

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 <kenneth at whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16176>

---

 src/gallium/drivers/r600/sfn/sfn_emitaluinstruction.cpp | 15 +++++++++++----
 src/gallium/drivers/r600/sfn/sfn_emitinstruction.cpp    |  5 +++++
 src/gallium/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<PValue> src0,
                          const std::set<AluModifiers>& 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();
 



More information about the mesa-commit mailing list