diff options
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/r600/sb/sb_bc.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/r600/sb/sb_bc_builder.cpp | 31 | ||||
-rw-r--r-- | src/gallium/drivers/r600/sb/sb_bc_decoder.cpp | 55 | ||||
-rw-r--r-- | src/gallium/drivers/r600/sb/sb_bc_dump.cpp | 26 |
4 files changed, 105 insertions, 9 deletions
diff --git a/src/gallium/drivers/r600/sb/sb_bc.h b/src/gallium/drivers/r600/sb/sb_bc.h index b0b12ce11c7..b23d4820b19 100644 --- a/src/gallium/drivers/r600/sb/sb_bc.h +++ b/src/gallium/drivers/r600/sb/sb_bc.h @@ -518,6 +518,8 @@ struct bc_alu { unsigned slot:3; + unsigned lds_idx_offset:6; + alu_op_flags slot_flags; void set_op(unsigned op) { diff --git a/src/gallium/drivers/r600/sb/sb_bc_builder.cpp b/src/gallium/drivers/r600/sb/sb_bc_builder.cpp index 55e2a8508ec..5dec169bac9 100644 --- a/src/gallium/drivers/r600/sb/sb_bc_builder.cpp +++ b/src/gallium/drivers/r600/sb/sb_bc_builder.cpp @@ -371,6 +371,37 @@ int bc_builder::build_alu(alu_node* n) { const bc_alu &bc = n->bc; const alu_op_info *aop = bc.op_ptr; + if (n->bc.op_ptr->flags & AF_LDS) { + assert(ctx.is_egcm()); + bb << ALU_WORD0_LDS_IDX_OP_EGCM() + .SRC0_SEL(bc.src[0].sel) + .SRC0_REL(bc.src[0].rel) + .SRC0_CHAN(bc.src[0].chan) + .IDX_OFFSET_4((bc.lds_idx_offset >> 4) & 1) + .SRC1_SEL(bc.src[1].sel) + .SRC1_REL(bc.src[1].rel) + .SRC1_CHAN(bc.src[1].chan) + .IDX_OFFSET_5((bc.lds_idx_offset >> 5) & 1) + .INDEX_MODE(bc.index_mode) + .PRED_SEL(bc.pred_sel) + .LAST(bc.last); + + bb << ALU_WORD1_LDS_IDX_OP_EGCM() + .SRC2_SEL(bc.src[2].sel) + .SRC2_REL(bc.src[2].rel) + .SRC2_CHAN(bc.src[2].chan) + .IDX_OFFSET_1((bc.lds_idx_offset >> 1) & 1) + .ALU_INST(ctx.alu_opcode(ALU_OP3_LDS_IDX_OP)) + .BANK_SWIZZLE(bc.bank_swizzle) + .LDS_OP((bc.op_ptr->opcode[1] >> 8) & 0xff) + .IDX_OFFSET_0((bc.lds_idx_offset >> 0) & 1) + .IDX_OFFSET_2((bc.lds_idx_offset >> 2) & 1) + .DST_CHAN(bc.dst_chan) + .IDX_OFFSET_3((bc.lds_idx_offset >> 3) & 1); + + return 0; + } + bb << ALU_WORD0_ALL() .INDEX_MODE(bc.index_mode) .LAST(bc.last) diff --git a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp index 48cbb33153f..1832e2d3e6a 100644 --- a/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp +++ b/src/gallium/drivers/r600/sb/sb_bc_decoder.cpp @@ -310,16 +310,53 @@ int bc_decoder::decode_alu(unsigned & i, bc_alu& bc) { ALU_WORD1_OP3_ALL w1(dw1); bc.set_op(r600_isa_alu_by_opcode(ctx.isa, w1.get_ALU_INST(), 1)); - bc.bank_swizzle = w1.get_BANK_SWIZZLE(); - bc.clamp = w1.get_CLAMP(); - bc.dst_chan = w1.get_DST_CHAN(); - bc.dst_gpr = w1.get_DST_GPR(); - bc.dst_rel = w1.get_DST_REL(); + if (bc.op == ALU_OP3_LDS_IDX_OP) { + ALU_WORD0_LDS_IDX_OP_EGCM iw0(dw0); + ALU_WORD1_LDS_IDX_OP_EGCM iw1(dw1); + bc.index_mode = iw0.get_INDEX_MODE(); + bc.last = iw0.get_LAST(); + bc.pred_sel = iw0.get_PRED_SEL(); + bc.src[0].chan = iw0.get_SRC0_CHAN(); + bc.src[0].sel = iw0.get_SRC0_SEL(); + bc.src[0].rel = iw0.get_SRC0_REL(); + + bc.src[1].chan = iw0.get_SRC1_CHAN(); + bc.src[1].sel = iw0.get_SRC1_SEL(); + bc.src[1].rel = iw0.get_SRC1_REL(); + + bc.bank_swizzle = iw1.get_BANK_SWIZZLE(); + bc.src[2].chan = iw1.get_SRC2_CHAN(); + bc.src[2].sel = iw1.get_SRC2_SEL(); + bc.src[2].rel = iw1.get_SRC2_REL(); + bc.dst_chan = iw1.get_DST_CHAN(); + // TODO: clean up + for (size_t k = 0; k < sizeof(alu_op_table) / sizeof(alu_op_table[0]); k++) { + if (((alu_op_table[k].opcode[1] >> 8) & 0xff) == iw1.get_LDS_OP()) { + bc.op_ptr = &alu_op_table[k]; + bc.op = k; + break; + } + } + bc.lds_idx_offset = + (iw0.get_IDX_OFFSET_4() << 4) | + (iw0.get_IDX_OFFSET_5() << 5) | + (iw1.get_IDX_OFFSET_1() << 1) | + (iw1.get_IDX_OFFSET_0() << 0) | + (iw1.get_IDX_OFFSET_2() << 2) | + (iw1.get_IDX_OFFSET_3() << 3); + } + else { + bc.bank_swizzle = w1.get_BANK_SWIZZLE(); + bc.clamp = w1.get_CLAMP(); + bc.dst_chan = w1.get_DST_CHAN(); + bc.dst_gpr = w1.get_DST_GPR(); + bc.dst_rel = w1.get_DST_REL(); - bc.src[2].chan = w1.get_SRC2_CHAN(); - bc.src[2].sel = w1.get_SRC2_SEL(); - bc.src[2].neg = w1.get_SRC2_NEG(); - bc.src[2].rel = w1.get_SRC2_REL(); + bc.src[2].chan = w1.get_SRC2_CHAN(); + bc.src[2].sel = w1.get_SRC2_SEL(); + bc.src[2].neg = w1.get_SRC2_NEG(); + bc.src[2].rel = w1.get_SRC2_REL(); + } } else { // op2 if (ctx.is_r600()) { diff --git a/src/gallium/drivers/r600/sb/sb_bc_dump.cpp b/src/gallium/drivers/r600/sb/sb_bc_dump.cpp index 3c051adf309..788450b3c9c 100644 --- a/src/gallium/drivers/r600/sb/sb_bc_dump.cpp +++ b/src/gallium/drivers/r600/sb/sb_bc_dump.cpp @@ -280,6 +280,28 @@ static void print_src(sb_ostream &s, bc_alu &alu, unsigned idx) need_sel = 0; need_chan = 0; switch (sel) { + case ALU_SRC_LDS_OQ_A: + s << "LDS_OQ_A"; + need_chan = 1; + break; + case ALU_SRC_LDS_OQ_B: + s << "LDS_OQ_B"; + need_chan = 1; + break; + case ALU_SRC_LDS_OQ_A_POP: + s << "LDS_OQ_A_POP"; + need_chan = 1; + break; + case ALU_SRC_LDS_OQ_B_POP: + s << "LDS_OQ_B_POP"; + need_chan = 1; + break; + case ALU_SRC_LDS_DIRECT_A: + s << "LDS_A["; s.print_zw_hex(src->value.u, 8); s << "]"; + break; + case ALU_SRC_LDS_DIRECT_B: + s << "LDS_B["; s.print_zw_hex(src->value.u, 8); s << "]"; + break; case ALU_SRC_PS: s << "PS"; break; @@ -363,6 +385,10 @@ void bc_dump::dump(alu_node& n) { } } + if (n.bc.lds_idx_offset) { + s << " IDX_OFFSET:" << n.bc.lds_idx_offset; + } + sblog << s.str() << "\n"; } |