r600/sfn: Add support for SSBO load and store
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:
@@ -27,6 +27,10 @@ bool EmitSSBOInstruction::do_emit(nir_instr* instr)
|
||||
return emit_atomic_inc(intr);
|
||||
case nir_intrinsic_atomic_counter_pre_dec:
|
||||
return emit_atomic_pre_dec(intr);
|
||||
case nir_intrinsic_load_ssbo:
|
||||
return emit_load_ssbo(intr);
|
||||
case nir_intrinsic_store_ssbo:
|
||||
return emit_store_ssbo(intr);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -165,6 +169,96 @@ bool EmitSSBOInstruction::emit_atomic_pre_dec(const nir_intrinsic_instr *instr)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmitSSBOInstruction::emit_load_ssbo(const nir_intrinsic_instr* instr)
|
||||
{
|
||||
GPRVector dest = make_dest(instr);
|
||||
|
||||
/** src0 not used, should be some offset */
|
||||
auto addr = from_nir_with_fetch_constant(instr->src[1], 0);
|
||||
PValue addr_temp = create_register_from_nir_src(instr->src[1], 1);
|
||||
|
||||
/** Should be lowered in nir */
|
||||
emit_instruction(new AluInstruction(op2_lshr_int, addr_temp, {addr, PValue(new LiteralValue(2))},
|
||||
{alu_write, alu_last_instr}));
|
||||
|
||||
const EVTXDataFormat formats[4] = {
|
||||
fmt_32,
|
||||
fmt_32_32,
|
||||
fmt_32_32_32,
|
||||
fmt_32_32_32_32
|
||||
};
|
||||
|
||||
const std::array<int,4> dest_swt[4] = {
|
||||
{0,7,7,7},
|
||||
{0,1,7,7},
|
||||
{0,1,2,7},
|
||||
{0,1,2,3}
|
||||
};
|
||||
|
||||
/* TODO fix resource index */
|
||||
auto ir = new FetchInstruction(dest, addr_temp,
|
||||
R600_IMAGE_REAL_RESOURCE_OFFSET, from_nir(instr->src[0], 0),
|
||||
formats[instr->num_components-1], vtx_nf_int);
|
||||
ir->set_dest_swizzle(dest_swt[instr->num_components - 1]);
|
||||
ir->set_flag(vtx_use_tc);
|
||||
|
||||
emit_instruction(ir);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmitSSBOInstruction::emit_store_ssbo(const nir_intrinsic_instr* instr)
|
||||
{
|
||||
|
||||
GPRVector::Swizzle swz = {7,7,7,7};
|
||||
for (int i = 0; i < instr->src[0].ssa->num_components; ++i)
|
||||
swz[i] = i;
|
||||
|
||||
auto orig_addr = from_nir(instr->src[2], 0);
|
||||
|
||||
int temp1 = allocate_temp_register();
|
||||
GPRVector addr_vec(temp1, {0,1,2,7});
|
||||
|
||||
auto rat_id = from_nir(instr->src[1], 0);
|
||||
|
||||
emit_instruction(new AluInstruction(op2_lshr_int, addr_vec.reg_i(0), orig_addr,
|
||||
PValue(new LiteralValue(2)), write));
|
||||
emit_instruction(new AluInstruction(op1_mov, addr_vec.reg_i(1), Value::zero, write));
|
||||
emit_instruction(new AluInstruction(op1_mov, addr_vec.reg_i(2), Value::zero, last_write));
|
||||
|
||||
|
||||
//#define WRITE_AS_VECTOR
|
||||
#ifdef WRITE_AS_VECTOR
|
||||
std::unique_ptr<GPRVector> value(vec_from_nir_with_fetch_constant(instr->src[0],
|
||||
(1 << instr->src[0].ssa->num_components) - 1, swz));
|
||||
|
||||
/* TODO fix resource index */
|
||||
int nelements = instr->src[0].ssa->num_components - 1;
|
||||
if (nelements == 2)
|
||||
nelements = 3;
|
||||
auto ir = new RatInstruction(cf_mem_rat, RatInstruction::STORE_TYPED,
|
||||
*value, addr_vec, 0, rat_id, 11,
|
||||
(1 << instr->src[0].ssa->num_components) - 1,
|
||||
0, false);
|
||||
emit_instruction(ir);
|
||||
#else
|
||||
|
||||
PValue value(from_nir_with_fetch_constant(instr->src[0], 0));
|
||||
GPRVector out_vec({value, value, value, value});
|
||||
emit_instruction(new RatInstruction(cf_mem_rat, RatInstruction::STORE_TYPED,
|
||||
out_vec, addr_vec, 0, rat_id, 1,
|
||||
1, 0, false));
|
||||
for (int i = 1; i < instr->src[0].ssa->num_components; ++i) {
|
||||
emit_instruction(new AluInstruction(op1_mov, out_vec.reg_i(0), from_nir(instr->src[0], i), write));
|
||||
emit_instruction(new AluInstruction(op2_add_int, addr_vec.reg_i(0),
|
||||
{addr_vec.reg_i(0), Value::one_i}, last_write));
|
||||
emit_instruction(new RatInstruction(cf_mem_rat, RatInstruction::STORE_TYPED,
|
||||
out_vec, addr_vec, 0, rat_id, 1,
|
||||
1, 0, false));
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
GPRVector EmitSSBOInstruction::make_dest(const nir_intrinsic_instr* ir)
|
||||
{
|
||||
GPRVector::Values v;
|
||||
|
||||
@@ -17,6 +17,8 @@ private:
|
||||
bool emit_atomic_inc(const nir_intrinsic_instr* instr);
|
||||
bool emit_atomic_pre_dec(const nir_intrinsic_instr* instr);
|
||||
|
||||
bool emit_load_ssbo(const nir_intrinsic_instr* instr);
|
||||
bool emit_store_ssbo(const nir_intrinsic_instr* instr);
|
||||
ESDOp get_opcode(nir_intrinsic_op opcode);
|
||||
|
||||
GPRVector make_dest(const nir_intrinsic_instr* instr);
|
||||
|
||||
@@ -462,7 +462,10 @@ bool ShaderFromNirProcessor::emit_intrinsic_instruction(nir_intrinsic_instr* ins
|
||||
case nir_intrinsic_atomic_counter_post_dec:
|
||||
case nir_intrinsic_atomic_counter_inc:
|
||||
case nir_intrinsic_atomic_counter_pre_dec:
|
||||
case nir_intrinsic_store_ssbo:
|
||||
m_sel.info.writes_memory = true;
|
||||
/* fallthrough */
|
||||
case nir_intrinsic_load_ssbo:
|
||||
return m_ssbo_instr.emit(&instr->instr);
|
||||
break;
|
||||
case nir_intrinsic_copy_deref:
|
||||
|
||||
Reference in New Issue
Block a user