From a100d906b2a66cc1f192b70a6873dbc931d034f7 Mon Sep 17 00:00:00 2001 From: Glenn Kennard Date: Sun, 5 Mar 2017 18:26:52 +0100 Subject: r600g/sb: Support scratch ops Signed-off-by: Glenn Kennard Reviewed-by: Dave Airlie --- src/gallium/drivers/r600/sb/sb_bc.h | 10 ++++++ src/gallium/drivers/r600/sb/sb_bc_builder.cpp | 44 ++++++++++++++++++++++++ src/gallium/drivers/r600/sb/sb_bc_decoder.cpp | 49 ++++++++++++++++++++++++++- src/gallium/drivers/r600/sb/sb_bc_dump.cpp | 15 ++++++++ src/gallium/drivers/r600/sb/sb_bc_fmt_def.inc | 36 ++++++++++++++++++++ 5 files changed, 153 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gallium/drivers/r600/sb/sb_bc.h b/src/gallium/drivers/r600/sb/sb_bc.h index a249395474f..e7231702d80 100644 --- a/src/gallium/drivers/r600/sb/sb_bc.h +++ b/src/gallium/drivers/r600/sb/sb_bc.h @@ -586,6 +586,14 @@ struct bc_fetch { unsigned uav_index_mode:2; unsigned bcast_first_req:1; + /* for MEM ops */ + unsigned elem_size:2; + unsigned uncached:1; + unsigned indexed:1; + unsigned burst_count:4; + unsigned array_base:13; + unsigned array_size:12; + void set_op(unsigned op) { this->op = op; op_ptr = r600_isa_fetch(op); } }; @@ -761,6 +769,7 @@ private: int decode_fetch_vtx(unsigned &i, bc_fetch &bc); int decode_fetch_gds(unsigned &i, bc_fetch &bc); + int decode_fetch_mem(unsigned &i, bc_fetch &bc); }; // bytecode format definition @@ -981,6 +990,7 @@ private: int build_fetch_tex(fetch_node *n); int build_fetch_vtx(fetch_node *n); int build_fetch_gds(fetch_node *n); + int build_fetch_mem(fetch_node* n); }; } // namespace r600_sb diff --git a/src/gallium/drivers/r600/sb/sb_bc_builder.cpp b/src/gallium/drivers/r600/sb/sb_bc_builder.cpp index ea91e197c09..5681fdc4425 100644 --- a/src/gallium/drivers/r600/sb/sb_bc_builder.cpp +++ b/src/gallium/drivers/r600/sb/sb_bc_builder.cpp @@ -131,6 +131,8 @@ int bc_builder::build_fetch_clause(cf_node* n) { if (f->bc.op_ptr->flags & FF_GDS) build_fetch_gds(f); + else if (f->bc.op_ptr->flags & FF_MEM) + build_fetch_mem(f); else if (f->bc.op_ptr->flags & FF_VTX) build_fetch_vtx(f); else @@ -699,4 +701,46 @@ int bc_builder::build_fetch_vtx(fetch_node* n) { return 0; } +int bc_builder::build_fetch_mem(fetch_node* n) { + const bc_fetch &bc = n->bc; + const fetch_op_info *fop = bc.op_ptr; + + assert(fop->flags & FF_MEM); + + bb << MEM_RD_WORD0_R7EGCM() + .MEM_INST(2) + .ELEM_SIZE(bc.elem_size) + .FETCH_WHOLE_QUAD(bc.fetch_whole_quad) + .MEM_OP(0) + .UNCACHED(bc.uncached) + .INDEXED(bc.indexed) + .SRC_SEL_Y(bc.src_sel[1]) + .SRC_GPR(bc.src_gpr) + .SRC_REL(bc.src_rel) + .SRC_SEL_X(bc.src_sel[0]) + .BURST_COUNT(bc.burst_count) + .LDS_REQ(bc.lds_req) + .COALESCED_READ(bc.coalesced_read); + + bb << MEM_RD_WORD1_R7EGCM() + .DST_GPR(bc.dst_gpr) + .DST_REL(bc.dst_rel) + .DST_SEL_X(bc.dst_sel[0]) + .DST_SEL_Y(bc.dst_sel[1]) + .DST_SEL_Z(bc.dst_sel[2]) + .DST_SEL_W(bc.dst_sel[3]) + .DATA_FORMAT(bc.data_format) + .NUM_FORMAT_ALL(bc.num_format_all) + .FORMAT_COMP_ALL(bc.format_comp_all) + .SRF_MODE_ALL(bc.srf_mode_all); + + bb << MEM_RD_WORD2_R7EGCM() + .ARRAY_BASE(bc.array_base) + .ENDIAN_SWAP(bc.endian_swap) + .ARR_SIZE(bc.array_size); + + bb << 0; + return 0; +} + } diff --git a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp index 1fa580e66d6..4a7f82ba753 100644 --- a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp +++ b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp @@ -413,7 +413,9 @@ int bc_decoder::decode_fetch(unsigned & i, bc_fetch& bc) { if (fetch_opcode == 2) { // MEM_INST_MEM unsigned mem_op = (dw0 >> 8) & 0x7; unsigned gds_op; - if (mem_op == 4) { + if (mem_op == 0 || mem_op == 2) { + fetch_opcode = mem_op == 0 ? FETCH_OP_READ_SCRATCH : FETCH_OP_READ_MEM; + } else if (mem_op == 4) { gds_op = (dw1 >> 9) & 0x1f; if ((dw1 >> 9) & 0x20) fetch_opcode = FETCH_OP_GDS_ADD_RET + gds_op; @@ -425,6 +427,9 @@ int bc_decoder::decode_fetch(unsigned & i, bc_fetch& bc) { } else bc.set_op(r600_isa_fetch_by_opcode(ctx.isa, fetch_opcode)); + if (bc.op_ptr->flags & FF_MEM) + return decode_fetch_mem(i, bc); + if (bc.op_ptr->flags & FF_GDS) return decode_fetch_gds(i, bc); @@ -528,6 +533,48 @@ int bc_decoder::decode_fetch_gds(unsigned & i, bc_fetch& bc) { return r; } +int bc_decoder::decode_fetch_mem(unsigned & i, bc_fetch& bc) { + int r = 0; + uint32_t dw0 = dw[i]; + uint32_t dw1 = dw[i+1]; + uint32_t dw2 = dw[i+2]; + + i += 4; // MEM instructions align to 4 words boundaries + assert(i < ndw); + + MEM_RD_WORD0_R7EGCM w0(dw0); + bc.elem_size = w0.get_ELEM_SIZE(); + bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD(); + bc.uncached = w0.get_UNCACHED(); + bc.indexed = w0.get_INDEXED(); + bc.src_sel[1] = w0.get_SRC_SEL_Y(); + bc.src_gpr = w0.get_SRC_GPR(); + bc.src_rel = w0.get_SRC_REL(); + bc.src_sel[0] = w0.get_SRC_SEL_X(); + bc.burst_count = w0.get_BURST_COUNT(); + bc.lds_req = w0.get_LDS_REQ(); + bc.coalesced_read = w0.get_COALESCED_READ(); + + MEM_RD_WORD1_R7EGCM w1(dw1); + bc.dst_gpr = w1.get_DST_GPR(); + bc.dst_rel = w1.get_DST_REL(); + bc.dst_sel[0] = w1.get_DST_SEL_X(); + bc.dst_sel[1] = w1.get_DST_SEL_Y(); + bc.dst_sel[2] = w1.get_DST_SEL_Z(); + bc.dst_sel[3] = w1.get_DST_SEL_W(); + bc.data_format = w1.get_DATA_FORMAT(); + bc.num_format_all = w1.get_NUM_FORMAT_ALL(); + bc.format_comp_all = w1.get_FORMAT_COMP_ALL(); + bc.srf_mode_all = w1.get_SRF_MODE_ALL(); + + MEM_RD_WORD2_R7EGCM w2(dw2); + bc.array_base = w2.get_ARRAY_BASE(); + bc.endian_swap = w2.get_ENDIAN_SWAP(); + bc.array_size = w2.get_ARR_SIZE(); + + return r; +} + int bc_decoder::decode_fetch_vtx(unsigned & i, bc_fetch& bc) { int r = 0; uint32_t dw0 = dw[i]; diff --git a/src/gallium/drivers/r600/sb/sb_bc_dump.cpp b/src/gallium/drivers/r600/sb/sb_bc_dump.cpp index 9093531fb3c..a3acb21e2fd 100644 --- a/src/gallium/drivers/r600/sb/sb_bc_dump.cpp +++ b/src/gallium/drivers/r600/sb/sb_bc_dump.cpp @@ -157,6 +157,9 @@ void bc_dump::dump(cf_node& n) { s << " ES:" << n.bc.elem_size; + if (n.bc.mark) + s << " MARK"; + } else { if (n.bc.op_ptr->flags & CF_CLAUSE) { @@ -540,6 +543,18 @@ void bc_dump::dump(fetch_node& n) { s << " SID:SQ_CF_INDEX_" << (n.bc.sampler_index_mode - V_SQ_CF_INDEX_0); } + if (n.bc.op_ptr->flags & FF_MEM) { + s << ", ELEM_SIZE:" << n.bc.elem_size; + if (n.bc.uncached) + s << ", UNCACHED"; + if (n.bc.indexed) + s << ", INDEXED"; + if (n.bc.burst_count) + s << ", BURST_COUNT:" << n.bc.burst_count; + s << ", ARRAY_BASE:" << n.bc.array_base; + s << ", ARRAY_SIZE:" << n.bc.array_size; + } + sblog << s.str() << "\n"; } diff --git a/src/gallium/drivers/r600/sb/sb_bc_fmt_def.inc b/src/gallium/drivers/r600/sb/sb_bc_fmt_def.inc index 5e6fb25a5b2..c6b9ddbd26b 100644 --- a/src/gallium/drivers/r600/sb/sb_bc_fmt_def.inc +++ b/src/gallium/drivers/r600/sb/sb_bc_fmt_def.inc @@ -569,3 +569,39 @@ BC_FIELD(MEM_GDS_WORD2, DST_SEL_Y, DSY, 5, 3) BC_FIELD(MEM_GDS_WORD2, DST_SEL_Z, DSZ, 8, 6) BC_FIELD(MEM_GDS_WORD2, DST_SEL_W, DSW, 11, 9) BC_FORMAT_END(MEM_GDS_WORD2) + +// MEM_RD_ +BC_FORMAT_BEGIN_HW(MEM_RD_WORD0, R7EGCM) +BC_FIELD(MEM_RD_WORD0, MEM_INST, M_INST, 4, 0) +BC_FIELD(MEM_RD_WORD0, ELEM_SIZE, ES, 6, 5) +BC_FIELD(MEM_RD_WORD0, FETCH_WHOLE_QUAD, FWQ, 7, 7) +BC_FIELD(MEM_RD_WORD0, MEM_OP, M_OP, 10, 8) +BC_FIELD(MEM_RD_WORD0, UNCACHED, UC, 11, 11) +BC_FIELD(MEM_RD_WORD0, INDEXED, INDEXED, 12, 12) +BC_FIELD(MEM_RD_WORD0, SRC_SEL_Y, SSY, 14, 13) +BC_FIELD(MEM_RD_WORD0, SRC_GPR, S_GPR, 22, 16) +BC_FIELD(MEM_RD_WORD0, SRC_REL, SR, 23, 23) +BC_FIELD(MEM_RD_WORD0, SRC_SEL_X, SSX, 25, 24) +BC_FIELD(MEM_RD_WORD0, BURST_COUNT, BURST, 29, 26) +BC_FIELD(MEM_RD_WORD0, LDS_REQ, LDS_REQ, 30, 30) +BC_FIELD(MEM_RD_WORD0, COALESCED_READ, COALESCED, 31, 31) +BC_FORMAT_END(MEM_RD_WORD0) + +BC_FORMAT_BEGIN_HW(MEM_RD_WORD1, R7EGCM) +BC_FIELD(MEM_RD_WORD1, DST_GPR, D_GPR, 6, 0) +BC_FIELD(MEM_RD_WORD1, DST_REL, DR, 7, 7) +BC_FIELD(MEM_RD_WORD1, DST_SEL_X, DSX, 11, 9) +BC_FIELD(MEM_RD_WORD1, DST_SEL_Y, DSY, 14, 12) +BC_FIELD(MEM_RD_WORD1, DST_SEL_Z, DSZ, 17, 15) +BC_FIELD(MEM_RD_WORD1, DST_SEL_W, DSW, 20, 18) +BC_FIELD(MEM_RD_WORD1, DATA_FORMAT, DFMT, 27, 22) +BC_FIELD(MEM_RD_WORD1, NUM_FORMAT_ALL, NFA, 29, 28) +BC_FIELD(MEM_RD_WORD1, FORMAT_COMP_ALL, FCA, 30, 30) +BC_FIELD(MEM_RD_WORD1, SRF_MODE_ALL, SMA, 31, 31) +BC_FORMAT_END(MEM_RD_WORD1) + +BC_FORMAT_BEGIN_HW(MEM_RD_WORD2, R7EGCM) +BC_FIELD(MEM_RD_WORD1, ARRAY_BASE, ARR_BS, 12, 0) +BC_FIELD(MEM_RD_WORD1, ENDIAN_SWAP, ES, 17, 16) +BC_FIELD(MEM_RD_WORD1, ARR_SIZE, ARR_SZ, 31, 20) +BC_FORMAT_END(MEM_RD_WORD2) -- cgit v1.2.3