diff options
author | Dave Airlie <[email protected]> | 2018-01-10 04:20:52 +0000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2018-01-18 03:37:13 +0000 |
commit | 9f3a1e9b0c75a202ede2718bd4d2b2a61b539e5d (patch) | |
tree | 7bc789955b056e668545cd89687ba8ade5f0603f /src/gallium | |
parent | 795512b235730c2ddb834b3082170521abb59811 (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')
-rw-r--r-- | src/gallium/drivers/r600/sb/sb_bc_parser.cpp | 52 |
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: |