From f7ec616bedce226e0f710727d21ba2059b36d66c Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Fri, 27 Dec 2019 17:49:27 +0100 Subject: [PATCH] r600/sfn: Add MemRingOut instructions Preparing support for Geometry shaders. Signed-off-by: Gert Wollny Part-of: --- .../r600/sfn/sfn_instruction_export.cpp | 85 +++++++++++++++++++ .../drivers/r600/sfn/sfn_instruction_export.h | 30 ++++++- .../drivers/r600/sfn/sfn_ir_to_assembly.cpp | 29 +++++++ 3 files changed, 143 insertions(+), 1 deletion(-) 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(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& 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& 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(*i)); case Instruction::streamout: return emit_streamout(static_cast(*i)); + case Instruction::ring: + return emit_memringwrite(static_cast(*i)); case Instruction::wait_ack: return emit_wait_ack(static_cast(*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(); -- 2.30.2