aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorGert Wollny <[email protected]>2019-12-28 16:48:45 +0100
committerMarge Bot <[email protected]>2020-02-10 19:09:08 +0000
commit110ee7ff93a42624b1e89065ec75b7649047715e (patch)
tree12b49d3160631578c761013f0f79b97228f63198 /src/gallium
parent148f0ad4f9c4b4c291abcaa1722f5ae91f9c4014 (diff)
r600/sfn: Add support for SSBO load and store
Signed-off-by: Gert Wollny <[email protected]> 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_emitssboinstruction.cpp94
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.h2
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_shader_base.cpp3
3 files changed, 99 insertions, 0 deletions
diff --git a/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.cpp b/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.cpp
index 0b5bc5fa15d..302e8ef3086 100644
--- a/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.cpp
+++ b/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.cpp
@@ -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;
diff --git a/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.h b/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.h
index 300f2ec2e92..f2951c9b3fb 100644
--- a/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.h
+++ b/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.h
@@ -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);
diff --git a/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp b/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp
index 7ea7bc69893..0e2d1a81350 100644
--- a/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp
+++ b/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp
@@ -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: