summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorGert Wollny <gert.wollny@collabora.com>2019-12-27 17:49:27 +0100
committerMarge Bot <eric+marge@anholt.net>2020-02-10 19:09:08 +0000
commitf7ec616bedce226e0f710727d21ba2059b36d66c (patch)
treec61808c0763f4741329289609a51e057fada7af1 /src/gallium
parent1b17316bf38b7f2c23ce648ddd718e1f48641309 (diff)
r600/sfn: Add MemRingOut instructions
Preparing support for Geometry shaders. Signed-off-by: Gert Wollny <gert.wollny@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3225>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp85
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_instruction_export.h30
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp29
3 files changed, 143 insertions, 1 deletions
diff --git a/src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp b/src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp
index fffcb09537c..b109846489f 100644
--- a/src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp
+++ b/src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp
@@ -244,4 +244,89 @@ void StreamOutIntruction::do_print(std::ostream& os) const
os << "+" << m_array_size;
}
+MemRingOutIntruction::MemRingOutIntruction(ECFOpCode ring, EMemWriteType type,
+ const GPRVector& value,
+ unsigned base_addr, unsigned ncomp,
+ PValue index):
+ WriteoutInstruction(Instruction::ring, value),
+ m_ring_op(ring),
+ m_type(type),
+ m_base_address(base_addr),
+ m_num_comp(ncomp),
+ m_index(index)
+{
+ add_remappable_src_value(&m_index);
+
+ assert(m_ring_op == cf_mem_ring || m_ring_op == cf_mem_ring1||
+ m_ring_op == cf_mem_ring2 || m_ring_op == cf_mem_ring3);
+ assert(m_num_comp <= 4);
+}
+
+unsigned MemRingOutIntruction::ncomp() const
+{
+ switch (m_num_comp) {
+ case 1: return 0;
+ case 2: return 1;
+ case 3:
+ case 4: return 3;
+ default:
+ assert(0);
+ }
+ return 3;
+}
+
+bool MemRingOutIntruction::is_equal_to(const Instruction& lhs) const
+{
+ assert(lhs.type() == streamout);
+ const auto& oth = static_cast<const MemRingOutIntruction&>(lhs);
+
+ bool equal = gpr() == oth.gpr() &&
+ m_ring_op == oth.m_ring_op &&
+ m_type == oth.m_type &&
+ m_num_comp == oth.m_num_comp &&
+ m_base_address == oth.m_base_address;
+
+ if (m_type == mem_write_ind || m_type == mem_write_ind_ack)
+ equal &= (*m_index == *oth.m_index);
+ return equal;
+
+}
+
+static const char *write_type_str[4] = {"WRITE", "WRITE_IDX", "WRITE_ACK", "WRITE_IDX_ACK" };
+void MemRingOutIntruction::do_print(std::ostream& os) const
+{
+ os << "MEM_RING" << m_ring_op;
+ os << " " << write_type_str[m_type] << " " << m_base_address;
+ os << " " << gpr();
+ if (m_type == mem_write_ind || m_type == mem_write_ind_ack)
+ os << " @" << *m_index;
+ os << " ES:" << m_num_comp;
+}
+
+
+void MemRingOutIntruction::replace_values_child(const ValueSet& candiates,
+ PValue new_value)
+{
+ if (!m_index)
+ return;
+
+ for (auto c: candiates) {
+ if (*c == *m_index)
+ m_index = new_value;
+ }
+}
+
+void MemRingOutIntruction::remap_registers_child(std::vector<rename_reg_pair>& map,
+ ValueMap& values)
+{
+ if (!m_index)
+ return;
+
+ assert(m_index->type() == Value::gpr);
+ auto new_index = map[m_index->sel()];
+ if (new_index.valid)
+ m_index = values.get_or_inject(new_index.new_reg, m_index->chan());
+ map[m_index->sel()].used = true;
+}
+
}
diff --git a/src/gallium/drivers/r600/sfn/sfn_instruction_export.h b/src/gallium/drivers/r600/sfn/sfn_instruction_export.h
index f32800381c4..8ab827e71b2 100644
--- a/src/gallium/drivers/r600/sfn/sfn_instruction_export.h
+++ b/src/gallium/drivers/r600/sfn/sfn_instruction_export.h
@@ -136,7 +136,35 @@ enum EMemWriteType {
mem_write_ind_ack = 3,
};
+class MemRingOutIntruction: public WriteoutInstruction {
+public:
+
+ MemRingOutIntruction(ECFOpCode ring, EMemWriteType type,
+ const GPRVector& value, unsigned base_addr,
+ unsigned ncomp, PValue m_index);
+
+ unsigned op() const{return m_ring_op;}
+ unsigned ncomp() const;
+ unsigned addr() const {return m_base_address;}
+ EMemWriteType type() const {return m_type;}
+ unsigned index_reg() const {return m_index->sel();}
+ unsigned array_base() const {return m_base_address; }
+ void replace_values_child(const ValueSet& candiates, PValue new_value) override;
+ void remap_registers_child(std::vector<rename_reg_pair>& map,
+ ValueMap& values) override;
+private:
+ bool is_equal_to(const Instruction& lhs) const override;
+ void do_print(std::ostream& os) const override;
+
+ ECFOpCode m_ring_op;
+ EMemWriteType m_type;
+ unsigned m_base_address;
+ unsigned m_num_comp;
+ PValue m_index;
+
+};
+
}
-#endif // SFN_EXPORTINSTRUCTION_H
+#endif // SFN_EXPORTINSTRUCTION_H \ No newline at end of file
diff --git a/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp b/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp
index e9624c58b2b..c6beddd79c7 100644
--- a/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp
+++ b/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp
@@ -47,6 +47,7 @@ private:
bool emit_alu(const AluInstruction& ai, ECFAluOpCode cf_op);
bool emit_export(const ExportInstruction & exi);
bool emit_streamout(const StreamOutIntruction& instr);
+ bool emit_memringwrite(const MemRingOutIntruction& instr);
bool emit_tex(const TexInstruction & tex_instr);
bool emit_vtx(const FetchInstruction& fetch_instr);
bool emit_if_start(const IfInstruction & if_instr);
@@ -164,6 +165,8 @@ bool AssemblyFromShaderLegacyImpl::emit(const Instruction::Pointer i)
return emit_loop_continue(static_cast<const LoopContInstruction&>(*i));
case Instruction::streamout:
return emit_streamout(static_cast<const StreamOutIntruction&>(*i));
+ case Instruction::ring:
+ return emit_memringwrite(static_cast<const MemRingOutIntruction&>(*i));
case Instruction::wait_ack:
return emit_wait_ack(static_cast<const WaitAck&>(*i));
case Instruction::mem_wr_scratch:
@@ -577,6 +580,32 @@ bool AssemblyFromShaderLegacyImpl::emit_streamout(const StreamOutIntruction& so_
return true;
}
+
+bool AssemblyFromShaderLegacyImpl::emit_memringwrite(const MemRingOutIntruction& instr)
+{
+ struct r600_bytecode_output output;
+ memset(&output, 0, sizeof(struct r600_bytecode_output));
+
+ output.gpr = instr.gpr().sel();
+ output.type = instr.type();
+ output.elem_size = instr.ncomp();
+ output.comp_mask = 0xF;
+ output.burst_count = 1;
+ output.op = instr.op();
+ if (instr.type() == mem_write_ind || instr.type() == mem_write_ind_ack) {
+ output.index_gpr = instr.index_reg();
+ output.array_size = 0xfff;
+ }
+ output.array_base = instr.array_base();
+
+ if (r600_bytecode_add_output(m_bc, &output)) {
+ R600_ERR("shader_from_nir: Error creating mem ring write instruction\n");
+ return false;
+ }
+ return true;
+}
+
+
bool AssemblyFromShaderLegacyImpl::emit_tex(const TexInstruction & tex_instr)
{
auto addr = tex_instr.sampler_offset();