aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorGert Wollny <[email protected]>2020-04-12 16:58:05 +0200
committerMarge Bot <[email protected]>2020-04-28 08:06:33 +0000
commit230beac5f8e5366082791b7b505583a5455e5495 (patch)
tree9c9ec49194a14aa9064560bf9917766531d6e08a /src/gallium
parentb9d175bed260995affc4aea0b511f8b1f0c1440d (diff)
r600/sfn: Add LDS instruction to assembly conversion
Signed-off-by: Gert Wollny <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4714>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp78
1 files changed, 78 insertions, 0 deletions
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 e6a9f202819..762439a33f2 100644
--- a/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp
+++ b/src/gallium/drivers/r600/sfn/sfn_ir_to_assembly.cpp
@@ -30,6 +30,7 @@
#include "sfn_instruction_gds.h"
#include "sfn_instruction_misc.h"
#include "sfn_instruction_fetch.h"
+#include "sfn_instruction_lds.h"
#include "../r600_shader.h"
#include "../r600_sq.h"
@@ -64,6 +65,8 @@ private:
bool emit_wr_scratch(const WriteScratchInstruction& instr);
bool emit_gds(const GDSInstr& instr);
bool emit_rat(const RatInstruction& instr);
+ bool emit_ldswrite(const LDSWriteInstruction& instr);
+ bool emit_ldsread(const LDSReadInstruction& instr);
bool emit_load_addr(PValue addr);
bool emit_fs_pixel_export(const ExportInstruction & exi);
@@ -189,6 +192,10 @@ bool AssemblyFromShaderLegacyImpl::emit(const Instruction::Pointer i)
return emit_gds(static_cast<const GDSInstr&>(*i));
case Instruction::rat:
return emit_rat(static_cast<const RatInstruction&>(*i));
+ case Instruction::lds_write:
+ return emit_ldswrite(static_cast<const LDSWriteInstruction&>(*i));
+ case Instruction::lds_read:
+ return emit_ldsread(static_cast<const LDSReadInstruction&>(*i));
default:
return false;
}
@@ -943,6 +950,77 @@ bool AssemblyFromShaderLegacyImpl::emit_gds(const GDSInstr& instr)
return true;
}
+bool AssemblyFromShaderLegacyImpl::emit_ldswrite(const LDSWriteInstruction& instr)
+{
+ r600_bytecode_alu alu;
+ memset(&alu, 0, sizeof(r600_bytecode_alu));
+
+ alu.last = true;
+ alu.is_lds_idx_op = true;
+ copy_src(alu.src[0], instr.address());
+ copy_src(alu.src[1], instr.value0());
+
+ if (instr.num_components() == 1) {
+ alu.op = LDS_OP2_LDS_WRITE;
+ } else {
+ alu.op = LDS_OP3_LDS_WRITE_REL;
+ alu.lds_idx = 1;
+ copy_src(alu.src[2], instr.value1());
+ }
+
+ return r600_bytecode_add_alu(m_bc, &alu) == 0;
+}
+
+bool AssemblyFromShaderLegacyImpl::emit_ldsread(const LDSReadInstruction& instr)
+{
+ int r;
+ unsigned nread = 0;
+ unsigned nfetch = 0;
+ unsigned n_values = instr.num_values();
+
+ r600_bytecode_alu alu_fetch;
+ r600_bytecode_alu alu_read;
+
+ /* We must add a new ALU clause if the fetch and read op would be split otherwise
+ * r600_asm limites at 120 slots = 240 dwords */
+ if (m_bc->cf_last->ndw > 240 - 4 * n_values)
+ m_bc->force_add_cf = 1;
+
+ while (nread < n_values) {
+ if (nfetch < n_values) {
+ memset(&alu_fetch, 0, sizeof(r600_bytecode_alu));
+ alu_fetch.is_lds_idx_op = true;
+ alu_fetch.op = LDS_OP1_LDS_READ_RET;
+
+ copy_src(alu_fetch.src[0], instr.address(nfetch));
+ alu_fetch.src[1].sel = V_SQ_ALU_SRC_0;
+ alu_fetch.src[2].sel = V_SQ_ALU_SRC_0;
+ alu_fetch.last = 1;
+ r = r600_bytecode_add_alu(m_bc, &alu_fetch);
+ m_bc->cf_last->nlds_read++;
+ if (r)
+ return false;
+ }
+
+ if (nfetch >= n_values) {
+ memset(&alu_read, 0, sizeof(r600_bytecode_alu));
+ copy_dst(alu_read.dst, instr.dest(nread));
+ alu_read.op = ALU_OP1_MOV;
+ alu_read.src[0].sel = EG_V_SQ_ALU_SRC_LDS_OQ_A_POP;
+ alu_read.last = 1;
+ alu_read.dst.write = 1;
+ r = r600_bytecode_add_alu(m_bc, &alu_read);
+ m_bc->cf_last->nqueue_read++;
+ if (r)
+ return false;
+ ++nread;
+ }
+ ++nfetch;
+ }
+ assert(m_bc->cf_last->nlds_read == m_bc->cf_last->nqueue_read);
+
+ return true;
+}
bool AssemblyFromShaderLegacyImpl::emit_rat(const RatInstruction& instr)
{