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>
This commit is contained in:
Gert Wollny 2019-12-27 17:49:27 +01:00 committed by Marge Bot
parent 1b17316bf3
commit f7ec616bed
3 changed files with 143 additions and 1 deletions

View file

@ -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;
}
}

View file

@ -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

View file

@ -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();