summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/sb
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2018-01-10 04:20:52 +0000
committerDave Airlie <[email protected]>2018-01-18 03:37:13 +0000
commit9f3a1e9b0c75a202ede2718bd4d2b2a61b539e5d (patch)
tree7bc789955b056e668545cd89687ba8ade5f0603f /src/gallium/drivers/r600/sb
parent795512b235730c2ddb834b3082170521abb59811 (diff)
r600/sb: add initial support for parsing lds operations.
This handles parsing the LDS ops and queue accessess. Acked-By: Roland Scheidegger <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/sb')
-rw-r--r--src/gallium/drivers/r600/sb/sb_bc_parser.cpp52
1 files changed, 50 insertions, 2 deletions
diff --git a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
index 8ab4083a3c9..970e4141d54 100644
--- a/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
+++ b/src/gallium/drivers/r600/sb/sb_bc_parser.cpp
@@ -384,7 +384,40 @@ int bc_parser::prepare_alu_group(cf_node* cf, alu_group_node *g) {
unsigned flags = n->bc.op_ptr->flags;
- if (flags & AF_PRED) {
+ if (flags & AF_LDS) {
+ bool need_rw = false, need_oqa = false, need_oqb = false;
+ int ndst = 0, ncount = 0;
+
+ /* all non-read operations have side effects */
+ if (n->bc.op != LDS_OP2_LDS_READ2_RET &&
+ n->bc.op != LDS_OP1_LDS_READ_REL_RET &&
+ n->bc.op != LDS_OP1_LDS_READ_RET) {
+ n->flags |= NF_DONT_KILL;
+ ndst++;
+ need_rw = true;
+ }
+
+ if (n->bc.op >= LDS_OP2_LDS_ADD_RET && n->bc.op <= LDS_OP1_LDS_USHORT_READ_RET) {
+ need_oqa = true;
+ ndst++;
+ }
+
+ if (n->bc.op == LDS_OP2_LDS_READ2_RET || n->bc.op == LDS_OP1_LDS_READ_REL_RET) {
+ need_oqb = true;
+ ndst++;
+ }
+
+ n->dst.resize(ndst);
+ if (need_oqa)
+ n->dst[ncount++] = sh->get_special_value(SV_LDS_OQA);
+ if (need_oqb)
+ n->dst[ncount++] = sh->get_special_value(SV_LDS_OQB);
+ if (need_rw)
+ n->dst[ncount++] = sh->get_special_value(SV_LDS_RW);
+
+ n->flags |= NF_DONT_MOVE | NF_DONT_HOIST;
+
+ } else if (flags & AF_PRED) {
n->dst.resize(3);
if (n->bc.update_pred)
n->dst[1] = sh->get_special_value(SV_ALU_PRED);
@@ -417,7 +450,7 @@ int bc_parser::prepare_alu_group(cf_node* cf, alu_group_node *g) {
n->flags |= NF_DONT_HOIST;
- } else if (n->bc.op_ptr->src_count == 3 || n->bc.write_mask) {
+ } else if ((n->bc.op_ptr->src_count == 3 || n->bc.write_mask) && !(flags & AF_LDS)) {
assert(!n->bc.dst_rel || n->bc.index_mode == INDEX_AR_X);
value *v = sh->get_gpr_value(false, n->bc.dst_gpr, n->bc.dst_chan,
@@ -487,6 +520,21 @@ int bc_parser::prepare_alu_group(cf_node* cf, alu_group_node *g) {
// param index as equal instructions and leave only one of them
n->src[s] = sh->get_special_ro_value(sel_chan(src.sel,
n->bc.slot));
+ } else if (ctx.is_lds_oq(src.sel)) {
+ switch (src.sel) {
+ case ALU_SRC_LDS_OQ_A:
+ case ALU_SRC_LDS_OQ_B:
+ assert(!"Unsupported LDS queue access in SB");
+ break;
+ case ALU_SRC_LDS_OQ_A_POP:
+ n->src[s] = sh->get_special_value(SV_LDS_OQA);
+ break;
+ case ALU_SRC_LDS_OQ_B_POP:
+ n->src[s] = sh->get_special_value(SV_LDS_OQB);
+ break;
+ }
+ n->flags |= NF_DONT_HOIST | NF_DONT_MOVE;
+
} else {
switch (src.sel) {
case ALU_SRC_0: