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>
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;
+}
+
}
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
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);
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:
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();