r600/sfn: Add TF write instruction
authorGert Wollny <gert.wollny@collabora.com>
Sun, 12 Apr 2020 14:59:05 +0000 (16:59 +0200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 28 Apr 2020 08:06:33 +0000 (08:06 +0000)
Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4714>

src/gallium/drivers/r600/sfn/sfn_instruction_base.h
src/gallium/drivers/r600/sfn/sfn_instruction_gds.cpp
src/gallium/drivers/r600/sfn/sfn_instruction_gds.h
src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp

index f7042b378e2f86f0173937466c723db055fb2b67..4986fa9728c2e20cfda373a9b03ded72de00c9fa 100644 (file)
@@ -90,6 +90,7 @@ public:
       mem_wr_scratch,
       gds,
       rat,
+      tf_write,
       block,
       unknown
    };
index 2fd8c7292a32b7c618dcad2a5005213c97f922fd..9c1207b7eb7d61c2595bc2d87880f600c5804d8b 100644 (file)
@@ -142,4 +142,33 @@ RatInstruction::ERatOp RatInstruction::opcode(nir_intrinsic_op opcode)
    }
 }
 
+GDSStoreTessFactor::GDSStoreTessFactor(GPRVector& value):
+   Instruction(tf_write),
+   m_value(value)
+{
+   add_remappable_src_value(&m_value);
+}
+
+void GDSStoreTessFactor::replace_values(const ValueSet& candiates, PValue new_value)
+{
+   for (auto& c: candiates) {
+      for (int i = 0; i < 4; ++i) {
+         if (*c == *m_value[i])
+            m_value[i] = new_value;
+      }
+   }
+}
+
+
+bool GDSStoreTessFactor::is_equal_to(const Instruction& lhs) const
+{
+   auto& other = static_cast<const GDSStoreTessFactor&>(lhs);
+   return m_value == other.m_value;
+}
+
+void GDSStoreTessFactor::do_print(std::ostream& os) const
+{
+   os << "TF_WRITE " << m_value;
+}
+
 }
index 1499d7fb736d2e02d78134ffdcd4b8fb68b03149..72708d09990ac58b228896480290b888b7693395 100644 (file)
@@ -190,6 +190,20 @@ private:
 
 };
 
+class GDSStoreTessFactor : public Instruction {
+public:
+      GDSStoreTessFactor(GPRVector& value);
+      int sel() const {return m_value.sel();}
+      int chan(int i ) const {return m_value.chan_i(i);}
+
+      void replace_values(const ValueSet& candiates, PValue new_value) override;
+private:
+      bool is_equal_to(const Instruction& lhs) const override;
+      void do_print(std::ostream& os) const override;
+
+      GPRVector m_value;
+};
+
 }
 
 #endif // SFN_GDSINSTR_H
index 762439a33f2b2b85a42a94a81346451c52d0edf7..9794057df93a45d4c98d1a57ff04670a6018a003 100644 (file)
@@ -67,6 +67,7 @@ private:
    bool emit_rat(const RatInstruction& instr);
    bool emit_ldswrite(const LDSWriteInstruction& instr);
    bool emit_ldsread(const LDSReadInstruction& instr);
+   bool emit_tf_write(const GDSStoreTessFactor& instr);
 
    bool emit_load_addr(PValue addr);
    bool emit_fs_pixel_export(const ExportInstruction & exi);
@@ -196,6 +197,8 @@ bool AssemblyFromShaderLegacyImpl::emit(const Instruction::Pointer i)
       return emit_ldswrite(static_cast<const LDSWriteInstruction&>(*i));
    case Instruction::lds_read:
       return emit_ldsread(static_cast<const LDSReadInstruction&>(*i));
+   case Instruction::tf_write:
+      return emit_tf_write(static_cast<const GDSStoreTessFactor&>(*i));
    default:
       return false;
    }
@@ -950,6 +953,42 @@ bool AssemblyFromShaderLegacyImpl::emit_gds(const GDSInstr& instr)
    return true;
 }
 
+bool AssemblyFromShaderLegacyImpl::emit_tf_write(const GDSStoreTessFactor& instr)
+{
+   struct r600_bytecode_gds gds;
+
+   memset(&gds, 0, sizeof(struct r600_bytecode_gds));
+   gds.src_gpr = instr.sel();
+   gds.src_sel_x = instr.chan(0);
+   gds.src_sel_y = instr.chan(1);
+   gds.src_sel_z = 4;
+   gds.dst_sel_x = 7;
+   gds.dst_sel_y = 7;
+   gds.dst_sel_z = 7;
+   gds.dst_sel_w = 7;
+   gds.op = FETCH_OP_TF_WRITE;
+
+   if (r600_bytecode_add_gds(m_bc, &gds) != 0)
+         return false;
+
+   if (instr.chan(2) != 7) {
+      memset(&gds, 0, sizeof(struct r600_bytecode_gds));
+      gds.src_gpr = instr.sel();
+      gds.src_sel_x = instr.chan(2);
+      gds.src_sel_y = instr.chan(3);
+      gds.src_sel_z = 4;
+      gds.dst_sel_x = 7;
+      gds.dst_sel_y = 7;
+      gds.dst_sel_z = 7;
+      gds.dst_sel_w = 7;
+      gds.op = FETCH_OP_TF_WRITE;
+
+      if (r600_bytecode_add_gds(m_bc, &gds))
+         return false;
+   }
+   return true;
+}
+
 bool AssemblyFromShaderLegacyImpl::emit_ldswrite(const LDSWriteInstruction& instr)
 {
    r600_bytecode_alu alu;