Home | History | Annotate | Download | only in sb
      1 /*
      2  * Copyright 2013 Vadim Girlin <vadimgirlin (at) gmail.com>
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * on the rights to use, copy, modify, merge, publish, distribute, sub
      8  * license, and/or sell copies of the Software, and to permit persons to whom
      9  * the Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     22  *
     23  * Authors:
     24  *      Vadim Girlin
     25  */
     26 
     27 #include "sb_bc.h"
     28 
     29 namespace r600_sb {
     30 
     31 int bc_decoder::decode_cf(unsigned &i, bc_cf& bc) {
     32 	int r = 0;
     33 	uint32_t dw0 = dw[i];
     34 	uint32_t dw1 = dw[i+1];
     35 	assert(i+1 <= ndw);
     36 
     37 	if ((dw1 >> 29) & 1) { // CF_ALU
     38 		return decode_cf_alu(i, bc);
     39 	} else {
     40 		// CF_INST field encoding on cayman is the same as on evergreen
     41 		unsigned opcode = ctx.is_egcm() ?
     42 				CF_WORD1_EG(dw1).get_CF_INST() :
     43 				CF_WORD1_R6R7(dw1).get_CF_INST();
     44 
     45 		bc.set_op(r600_isa_cf_by_opcode(ctx.isa, opcode, 0));
     46 
     47 		if (bc.op_ptr->flags & CF_EXP) {
     48 			return decode_cf_exp(i, bc);
     49 		} else if (bc.op_ptr->flags & CF_MEM) {
     50 			return decode_cf_mem(i, bc);
     51 		}
     52 
     53 		if (ctx.is_egcm()) {
     54 			CF_WORD0_EGCM w0(dw0);
     55 			bc.addr = w0.get_ADDR();
     56 			bc.jumptable_sel = w0.get_JUMPTABLE_SEL();
     57 
     58 			if (ctx.is_evergreen()) {
     59 				CF_WORD1_EG w1(dw1);
     60 
     61 				bc.barrier = w1.get_BARRIER();
     62 				bc.cf_const = w1.get_CF_CONST();
     63 				bc.cond = w1.get_COND();
     64 				bc.count = w1.get_COUNT();
     65 				bc.end_of_program = w1.get_END_OF_PROGRAM();
     66 				bc.pop_count = w1.get_POP_COUNT();
     67 				bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
     68 				bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
     69 
     70 			} else { // cayman
     71 				CF_WORD1_CM w1(dw1);
     72 
     73 				bc.barrier = w1.get_BARRIER();
     74 				bc.cf_const = w1.get_CF_CONST();
     75 				bc.cond = w1.get_COND();
     76 				bc.count = w1.get_COUNT();
     77 				bc.pop_count = w1.get_POP_COUNT();
     78 				bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
     79 			}
     80 
     81 
     82 		} else {
     83 			CF_WORD0_R6R7 w0(dw0);
     84 			bc.addr = w0.get_ADDR();
     85 
     86 			CF_WORD1_R6R7 w1(dw1);
     87 			bc.barrier = w1.get_BARRIER();
     88 			bc.cf_const = w1.get_CF_CONST();
     89 			bc.cond = w1.get_COND();
     90 
     91 			if (ctx.is_r600())
     92 				bc.count = w1.get_COUNT();
     93 			else
     94 				bc.count = w1.get_COUNT() + (w1.get_COUNT_3() << 3);
     95 
     96 			bc.end_of_program = w1.get_END_OF_PROGRAM();
     97 			bc.pop_count = w1.get_POP_COUNT();
     98 			bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
     99 			bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
    100 			bc.call_count = w1.get_CALL_COUNT();
    101 		}
    102 	}
    103 
    104 	i += 2;
    105 
    106 	return r;
    107 }
    108 
    109 int bc_decoder::decode_cf_alu(unsigned & i, bc_cf& bc) {
    110 	int r = 0;
    111 	uint32_t dw0 = dw[i++];
    112 	uint32_t dw1 = dw[i++];
    113 
    114 	assert(i <= ndw);
    115 
    116 	CF_ALU_WORD0_ALL w0(dw0);
    117 
    118 	bc.kc[0].bank = w0.get_KCACHE_BANK0();
    119 	bc.kc[1].bank = w0.get_KCACHE_BANK1();
    120 	bc.kc[0].mode = w0.get_KCACHE_MODE0();
    121 
    122 	bc.addr = w0.get_ADDR();
    123 
    124 	if (ctx.is_r600()) {
    125 		CF_ALU_WORD1_R6 w1(dw1);
    126 
    127 		bc.set_op(r600_isa_cf_by_opcode(ctx.isa, w1.get_CF_INST(), 1));
    128 
    129 		bc.kc[0].addr = w1.get_KCACHE_ADDR0();
    130 		bc.kc[1].mode = w1.get_KCACHE_MODE1();
    131 		bc.kc[1].addr = w1.get_KCACHE_ADDR1();
    132 
    133 		bc.barrier = w1.get_BARRIER();
    134 		bc.count = w1.get_COUNT();
    135 		bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
    136 
    137 		bc.uses_waterfall = w1.get_USES_WATERFALL();
    138 	} else {
    139 		CF_ALU_WORD1_R7EGCM w1(dw1);
    140 
    141 		bc.set_op(r600_isa_cf_by_opcode(ctx.isa, w1.get_CF_INST(), 1));
    142 
    143 		if (bc.op == CF_OP_ALU_EXT) {
    144 			CF_ALU_WORD0_EXT_EGCM w0(dw0);
    145 			CF_ALU_WORD1_EXT_EGCM w1(dw1);
    146 
    147 			bc.kc[0].index_mode = w0.get_KCACHE_BANK_INDEX_MODE0();
    148 			bc.kc[1].index_mode = w0.get_KCACHE_BANK_INDEX_MODE1();
    149 			bc.kc[2].index_mode = w0.get_KCACHE_BANK_INDEX_MODE2();
    150 			bc.kc[3].index_mode = w0.get_KCACHE_BANK_INDEX_MODE3();
    151 			bc.kc[2].bank = w0.get_KCACHE_BANK2();
    152 			bc.kc[3].bank = w0.get_KCACHE_BANK3();
    153 			bc.kc[2].mode = w0.get_KCACHE_MODE2();
    154 			bc.kc[3].mode = w1.get_KCACHE_MODE3();
    155 			bc.kc[2].addr = w1.get_KCACHE_ADDR2();
    156 			bc.kc[3].addr = w1.get_KCACHE_ADDR3();
    157 
    158 			r = decode_cf_alu(i, bc);
    159 
    160 		} else {
    161 
    162 			bc.kc[0].addr = w1.get_KCACHE_ADDR0();
    163 			bc.kc[1].mode = w1.get_KCACHE_MODE1();
    164 			bc.kc[1].addr = w1.get_KCACHE_ADDR1();
    165 			bc.barrier = w1.get_BARRIER();
    166 			bc.count = w1.get_COUNT();
    167 			bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
    168 
    169 			bc.alt_const = w1.get_ALT_CONST();
    170 		}
    171 	}
    172 	return r;
    173 }
    174 
    175 int bc_decoder::decode_cf_exp(unsigned & i, bc_cf& bc) {
    176 	int r = 0;
    177 	uint32_t dw0 = dw[i++];
    178 	uint32_t dw1 = dw[i++];
    179 	assert(i <= ndw);
    180 
    181 	CF_ALLOC_EXPORT_WORD0_ALL w0(dw0);
    182 	bc.array_base = w0.get_ARRAY_BASE();
    183 	bc.elem_size = w0.get_ELEM_SIZE();
    184 	bc.index_gpr = w0.get_INDEX_GPR();
    185 	bc.rw_gpr = w0.get_RW_GPR();
    186 	bc.rw_rel = w0.get_RW_REL();
    187 	bc.type = w0.get_TYPE();
    188 
    189 	if (ctx.is_evergreen()) {
    190 		CF_ALLOC_EXPORT_WORD1_SWIZ_EG w1(dw1);
    191 		bc.barrier = w1.get_BARRIER();
    192 		bc.burst_count = w1.get_BURST_COUNT();
    193 		bc.end_of_program = w1.get_END_OF_PROGRAM();
    194 		bc.sel[0] = w1.get_SEL_X();
    195 		bc.sel[1] = w1.get_SEL_Y();
    196 		bc.sel[2] = w1.get_SEL_Z();
    197 		bc.sel[3] = w1.get_SEL_W();
    198 		bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
    199 		bc.mark = w1.get_MARK();
    200 
    201 	} else if (ctx.is_cayman()) {
    202 		CF_ALLOC_EXPORT_WORD1_SWIZ_CM w1(dw1);
    203 		bc.barrier = w1.get_BARRIER();
    204 		bc.burst_count = w1.get_BURST_COUNT();
    205 		bc.mark = w1.get_MARK();
    206 		bc.sel[0] = w1.get_SEL_X();
    207 		bc.sel[1] = w1.get_SEL_Y();
    208 		bc.sel[2] = w1.get_SEL_Z();
    209 		bc.sel[3] = w1.get_SEL_W();
    210 		bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
    211 
    212 	} else { // r67
    213 		CF_ALLOC_EXPORT_WORD1_SWIZ_R6R7 w1(dw1);
    214 		bc.barrier = w1.get_BARRIER();
    215 		bc.burst_count = w1.get_BURST_COUNT();
    216 		bc.end_of_program = w1.get_END_OF_PROGRAM();
    217 		bc.sel[0] = w1.get_SEL_X();
    218 		bc.sel[1] = w1.get_SEL_Y();
    219 		bc.sel[2] = w1.get_SEL_Z();
    220 		bc.sel[3] = w1.get_SEL_W();
    221 		bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
    222 		bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
    223 	}
    224 
    225 	return r;
    226 }
    227 
    228 
    229 int bc_decoder::decode_cf_mem(unsigned & i, bc_cf& bc) {
    230 	int r = 0;
    231 	uint32_t dw0 = dw[i++];
    232 	uint32_t dw1 = dw[i++];
    233 	assert(i <= ndw);
    234 
    235 	if (!(bc.op_ptr->flags & CF_RAT)) {
    236 		CF_ALLOC_EXPORT_WORD0_ALL w0(dw0);
    237 		bc.array_base = w0.get_ARRAY_BASE();
    238 		bc.elem_size = w0.get_ELEM_SIZE();
    239 		bc.index_gpr = w0.get_INDEX_GPR();
    240 		bc.rw_gpr = w0.get_RW_GPR();
    241 		bc.rw_rel = w0.get_RW_REL();
    242 		bc.type = w0.get_TYPE();
    243 	} else {
    244 		assert(ctx.is_egcm());
    245 		CF_ALLOC_EXPORT_WORD0_RAT_EGCM w0(dw0);
    246 		bc.elem_size = w0.get_ELEM_SIZE();
    247 		bc.index_gpr = w0.get_INDEX_GPR();
    248 		bc.rw_gpr = w0.get_RW_GPR();
    249 		bc.rw_rel = w0.get_RW_REL();
    250 		bc.type = w0.get_TYPE();
    251 		bc.rat_id = w0.get_RAT_ID();
    252 		bc.rat_inst = w0.get_RAT_INST();
    253 		bc.rat_index_mode = w0.get_RAT_INDEX_MODE();
    254 	}
    255 
    256 	if (ctx.is_evergreen()) {
    257 		CF_ALLOC_EXPORT_WORD1_BUF_EG w1(dw1);
    258 		bc.barrier = w1.get_BARRIER();
    259 		bc.burst_count = w1.get_BURST_COUNT();
    260 		bc.end_of_program = w1.get_END_OF_PROGRAM();
    261 		bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
    262 		bc.mark = w1.get_MARK();
    263 		bc.array_size = w1.get_ARR_SIZE();
    264 		bc.comp_mask = w1.get_COMP_MASK();
    265 
    266 	} else if (ctx.is_cayman()) {
    267 		CF_ALLOC_EXPORT_WORD1_BUF_CM w1(dw1);
    268 		bc.barrier = w1.get_BARRIER();
    269 		bc.burst_count = w1.get_BURST_COUNT();
    270 		bc.mark = w1.get_MARK();
    271 		bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
    272 		bc.array_size = w1.get_ARR_SIZE();
    273 		bc.comp_mask = w1.get_COMP_MASK();
    274 
    275 	} else { // r67
    276 		CF_ALLOC_EXPORT_WORD1_BUF_R6R7 w1(dw1);
    277 		bc.barrier = w1.get_BARRIER();
    278 		bc.burst_count = w1.get_BURST_COUNT();
    279 		bc.end_of_program = w1.get_END_OF_PROGRAM();
    280 		bc.valid_pixel_mode = w1.get_VALID_PIXEL_MODE();
    281 		bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
    282 		bc.array_size = w1.get_ARR_SIZE();
    283 		bc.comp_mask = w1.get_COMP_MASK();
    284 		bc.whole_quad_mode = w1.get_WHOLE_QUAD_MODE();
    285 	}
    286 
    287 	return r;
    288 }
    289 
    290 int bc_decoder::decode_alu(unsigned & i, bc_alu& bc) {
    291 	int r = 0;
    292 	uint32_t dw0 = dw[i++];
    293 	uint32_t dw1 = dw[i++];
    294 	assert(i <= ndw);
    295 
    296 	ALU_WORD0_ALL w0(dw0);
    297 	bc.index_mode = w0.get_INDEX_MODE();
    298 	bc.last = w0.get_LAST();
    299 	bc.pred_sel = w0.get_PRED_SEL();
    300 	bc.src[0].chan = w0.get_SRC0_CHAN();
    301 	bc.src[0].sel = w0.get_SRC0_SEL();
    302 	bc.src[0].neg = w0.get_SRC0_NEG();
    303 	bc.src[0].rel = w0.get_SRC0_REL();
    304 	bc.src[1].chan = w0.get_SRC1_CHAN();
    305 	bc.src[1].sel = w0.get_SRC1_SEL();
    306 	bc.src[1].neg = w0.get_SRC1_NEG();
    307 	bc.src[1].rel = w0.get_SRC1_REL();
    308 
    309 	if ((dw1 >> 15) & 7) { // op3
    310 		ALU_WORD1_OP3_ALL w1(dw1);
    311 		bc.set_op(r600_isa_alu_by_opcode(ctx.isa, w1.get_ALU_INST(), 1));
    312 
    313 		if (bc.op == ALU_OP3_LDS_IDX_OP) {
    314 			ALU_WORD0_LDS_IDX_OP_EGCM iw0(dw0);
    315 			ALU_WORD1_LDS_IDX_OP_EGCM iw1(dw1);
    316 			bc.index_mode = iw0.get_INDEX_MODE();
    317 			bc.last = iw0.get_LAST();
    318 			bc.pred_sel = iw0.get_PRED_SEL();
    319 			bc.src[0].chan = iw0.get_SRC0_CHAN();
    320 			bc.src[0].sel = iw0.get_SRC0_SEL();
    321 			bc.src[0].rel = iw0.get_SRC0_REL();
    322 
    323 			bc.src[1].chan = iw0.get_SRC1_CHAN();
    324 			bc.src[1].sel = iw0.get_SRC1_SEL();
    325 			bc.src[1].rel = iw0.get_SRC1_REL();
    326 
    327 			bc.bank_swizzle = iw1.get_BANK_SWIZZLE();
    328 			bc.src[2].chan = iw1.get_SRC2_CHAN();
    329 			bc.src[2].sel = iw1.get_SRC2_SEL();
    330 			bc.src[2].rel = iw1.get_SRC2_REL();
    331 			bc.dst_chan = iw1.get_DST_CHAN();
    332 			// TODO: clean up
    333 			for (size_t k = 0, e = r600_alu_op_table_size(); k != e; k++) {
    334 				if (((r600_alu_op_table[k].opcode[1] >> 8) & 0xff) == iw1.get_LDS_OP()) {
    335 					bc.op_ptr = &r600_alu_op_table[k];
    336 					bc.op = k;
    337 					break;
    338 				}
    339 			}
    340 			bc.lds_idx_offset =
    341 				(iw0.get_IDX_OFFSET_4() << 4) |
    342 				(iw0.get_IDX_OFFSET_5() << 5) |
    343 				(iw1.get_IDX_OFFSET_1() << 1) |
    344 				(iw1.get_IDX_OFFSET_0() << 0) |
    345 				(iw1.get_IDX_OFFSET_2() << 2) |
    346 				(iw1.get_IDX_OFFSET_3() << 3);
    347 		}
    348 		else {
    349 			bc.bank_swizzle = w1.get_BANK_SWIZZLE();
    350 			bc.clamp = w1.get_CLAMP();
    351 			bc.dst_chan = w1.get_DST_CHAN();
    352 			bc.dst_gpr = w1.get_DST_GPR();
    353 			bc.dst_rel = w1.get_DST_REL();
    354 
    355 			bc.src[2].chan = w1.get_SRC2_CHAN();
    356 			bc.src[2].sel = w1.get_SRC2_SEL();
    357 			bc.src[2].neg = w1.get_SRC2_NEG();
    358 			bc.src[2].rel = w1.get_SRC2_REL();
    359 		}
    360 
    361 	} else { // op2
    362 		if (ctx.is_r600()) {
    363 			ALU_WORD1_OP2_R6 w1(dw1);
    364 			bc.set_op(r600_isa_alu_by_opcode(ctx.isa, w1.get_ALU_INST(), 0));
    365 
    366 			bc.bank_swizzle = w1.get_BANK_SWIZZLE();
    367 			bc.clamp = w1.get_CLAMP();
    368 			bc.dst_chan = w1.get_DST_CHAN();
    369 			bc.dst_gpr = w1.get_DST_GPR();
    370 			bc.dst_rel = w1.get_DST_REL();
    371 
    372 			bc.omod = w1.get_OMOD();
    373 			bc.src[0].abs = w1.get_SRC0_ABS();
    374 			bc.src[1].abs = w1.get_SRC1_ABS();
    375 			bc.write_mask = w1.get_WRITE_MASK();
    376 			bc.update_exec_mask = w1.get_UPDATE_EXEC_MASK();
    377 			bc.update_pred = w1.get_UPDATE_PRED();
    378 
    379 			bc.fog_merge = w1.get_FOG_MERGE();
    380 
    381 		} else {
    382 			ALU_WORD1_OP2_R7EGCM w1(dw1);
    383 			bc.set_op(r600_isa_alu_by_opcode(ctx.isa, w1.get_ALU_INST(), 0));
    384 
    385 			bc.bank_swizzle = w1.get_BANK_SWIZZLE();
    386 			bc.clamp = w1.get_CLAMP();
    387 			bc.dst_chan = w1.get_DST_CHAN();
    388 			bc.dst_gpr = w1.get_DST_GPR();
    389 			bc.dst_rel = w1.get_DST_REL();
    390 
    391 			bc.omod = w1.get_OMOD();
    392 			bc.src[0].abs = w1.get_SRC0_ABS();
    393 			bc.src[1].abs = w1.get_SRC1_ABS();
    394 			bc.write_mask = w1.get_WRITE_MASK();
    395 			bc.update_exec_mask = w1.get_UPDATE_EXEC_MASK();
    396 			bc.update_pred = w1.get_UPDATE_PRED();
    397 		}
    398 	}
    399 
    400 	bc.slot_flags = (alu_op_flags)bc.op_ptr->slots[ctx.isa->hw_class];
    401 	return r;
    402 }
    403 
    404 int bc_decoder::decode_fetch(unsigned & i, bc_fetch& bc) {
    405 	int r = 0;
    406 	uint32_t dw0 = dw[i];
    407 	uint32_t dw1 = dw[i+1];
    408 	uint32_t dw2 = dw[i+2];
    409 	assert(i + 4 <= ndw);
    410 
    411 	unsigned fetch_opcode = dw0 & 0x1F;
    412 
    413 	if (fetch_opcode == 2) { // MEM_INST_MEM
    414 		unsigned mem_op = (dw0 >> 8) & 0x7;
    415 		unsigned gds_op;
    416 		if (mem_op == 4) {
    417 			gds_op = (dw1 >> 9) & 0x1f;
    418 			fetch_opcode = FETCH_OP_GDS_ADD + gds_op;
    419 		} else if (mem_op == 5)
    420 			fetch_opcode = FETCH_OP_TF_WRITE;
    421 		bc.set_op(fetch_opcode);
    422 	} else
    423 		bc.set_op(r600_isa_fetch_by_opcode(ctx.isa, fetch_opcode));
    424 
    425 	if (bc.op_ptr->flags & FF_GDS)
    426 		return decode_fetch_gds(i, bc);
    427 
    428 	if (bc.op_ptr->flags & FF_VTX)
    429 		return decode_fetch_vtx(i, bc);
    430 
    431 	// tex
    432 
    433 	if (ctx.is_r600()) {
    434 		TEX_WORD0_R6 w0(dw0);
    435 
    436 		bc.bc_frac_mode = w0.get_BC_FRAC_MODE();
    437 		bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
    438 		bc.resource_id = w0.get_RESOURCE_ID();
    439 		bc.src_gpr = w0.get_SRC_GPR();
    440 		bc.src_rel = w0.get_SRC_REL();
    441 
    442 	} else if (ctx.is_r600()) {
    443 		TEX_WORD0_R7 w0(dw0);
    444 
    445 		bc.bc_frac_mode = w0.get_BC_FRAC_MODE();
    446 		bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
    447 		bc.resource_id = w0.get_RESOURCE_ID();
    448 		bc.src_gpr = w0.get_SRC_GPR();
    449 		bc.src_rel = w0.get_SRC_REL();
    450 		bc.alt_const = w0.get_ALT_CONST();
    451 
    452 	} else { // eg/cm
    453 		TEX_WORD0_EGCM w0(dw0);
    454 
    455 		bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
    456 		bc.resource_id = w0.get_RESOURCE_ID();
    457 		bc.src_gpr = w0.get_SRC_GPR();
    458 		bc.src_rel = w0.get_SRC_REL();
    459 		bc.alt_const = w0.get_ALT_CONST();
    460 		bc.inst_mod = w0.get_INST_MOD();
    461 		bc.resource_index_mode = w0.get_RESOURCE_INDEX_MODE();
    462 		bc.sampler_index_mode = w0.get_SAMPLER_INDEX_MODE();
    463 	}
    464 
    465 	TEX_WORD1_ALL w1(dw1);
    466 	bc.coord_type[0] = w1.get_COORD_TYPE_X();
    467 	bc.coord_type[1] = w1.get_COORD_TYPE_Y();
    468 	bc.coord_type[2] = w1.get_COORD_TYPE_Z();
    469 	bc.coord_type[3] = w1.get_COORD_TYPE_W();
    470 	bc.dst_gpr = w1.get_DST_GPR();
    471 	bc.dst_rel = w1.get_DST_REL();
    472 	bc.dst_sel[0] = w1.get_DST_SEL_X();
    473 	bc.dst_sel[1] = w1.get_DST_SEL_Y();
    474 	bc.dst_sel[2] = w1.get_DST_SEL_Z();
    475 	bc.dst_sel[3] = w1.get_DST_SEL_W();
    476 	bc.lod_bias = w1.get_LOD_BIAS();
    477 
    478 	TEX_WORD2_ALL w2(dw2);
    479 	bc.offset[0] = w2.get_OFFSET_X();
    480 	bc.offset[1] = w2.get_OFFSET_Y();
    481 	bc.offset[2] = w2.get_OFFSET_Z();
    482 	bc.sampler_id = w2.get_SAMPLER_ID();
    483 	bc.src_sel[0] = w2.get_SRC_SEL_X();
    484 	bc.src_sel[1] = w2.get_SRC_SEL_Y();
    485 	bc.src_sel[2] = w2.get_SRC_SEL_Z();
    486 	bc.src_sel[3] = w2.get_SRC_SEL_W();
    487 
    488 	i += 4;
    489 	return r;
    490 }
    491 
    492 int bc_decoder::decode_fetch_gds(unsigned & i, bc_fetch& bc) {
    493 	int r = 0;
    494 	uint32_t dw0 = dw[i];
    495 	uint32_t dw1 = dw[i+1];
    496 	uint32_t dw2 = dw[i+2];
    497 	uint32_t tmp;
    498 	/* GDS instructions align to 4 words boundaries */
    499 	i+= 4;
    500 	assert(i <= ndw);
    501 
    502 	MEM_GDS_WORD0_EGCM w0(dw0);
    503 	bc.src_gpr = w0.get_SRC_GPR();
    504 	tmp = w0.get_SRC_REL_MODE();
    505 	bc.src_rel_global = (tmp == 2);
    506 	bc.src_sel[0] = w0.get_SRC_SEL_X();
    507 	bc.src_sel[1] = w0.get_SRC_SEL_Y();
    508 	bc.src_sel[2] = w0.get_SRC_SEL_Z();
    509 
    510 	MEM_GDS_WORD1_EGCM w1(dw1);
    511 	bc.dst_gpr = w1.get_DST_GPR();
    512 	tmp = w1.get_DST_REL_MODE();
    513 	bc.dst_rel_global = (tmp == 2);
    514 	bc.src2_gpr = w1.get_SRC_GPR();
    515 
    516 	MEM_GDS_WORD2_EGCM w2(dw2);
    517 	bc.dst_sel[0] = w2.get_DST_SEL_X();
    518 	bc.dst_sel[1] = w2.get_DST_SEL_Y();
    519 	bc.dst_sel[2] = w2.get_DST_SEL_Z();
    520 	bc.dst_sel[3] = w2.get_DST_SEL_W();
    521 	return r;
    522 }
    523 
    524 int bc_decoder::decode_fetch_vtx(unsigned & i, bc_fetch& bc) {
    525 	int r = 0;
    526 	uint32_t dw0 = dw[i];
    527 	uint32_t dw1 = dw[i+1];
    528 	uint32_t dw2 = dw[i+2];
    529 	i+= 4;
    530 	assert(i <= ndw);
    531 
    532 	if (ctx.is_cayman()) {
    533 		VTX_WORD0_CM w0(dw0);
    534 		bc.resource_id = w0.get_BUFFER_ID();
    535 		bc.fetch_type = w0.get_FETCH_TYPE();
    536 		bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
    537 		bc.src_gpr = w0.get_SRC_GPR();
    538 		bc.src_rel = w0.get_SRC_REL();
    539 		bc.src_sel[0] = w0.get_SRC_SEL_X();
    540 		bc.coalesced_read = w0.get_COALESCED_READ();
    541 		bc.lds_req = w0.get_LDS_REQ();
    542 		bc.structured_read = w0.get_STRUCTURED_READ();
    543 
    544 	} else {
    545 		VTX_WORD0_R6R7EG w0(dw0);
    546 		bc.resource_id = w0.get_BUFFER_ID();
    547 		bc.fetch_type = w0.get_FETCH_TYPE();
    548 		bc.fetch_whole_quad = w0.get_FETCH_WHOLE_QUAD();
    549 		bc.mega_fetch_count = w0.get_MEGA_FETCH_COUNT();
    550 		bc.src_gpr = w0.get_SRC_GPR();
    551 		bc.src_rel = w0.get_SRC_REL();
    552 		bc.src_sel[0] = w0.get_SRC_SEL_X();
    553 	}
    554 
    555 	if (bc.op == FETCH_OP_SEMFETCH) {
    556 		VTX_WORD1_SEM_ALL w1(dw1);
    557 		bc.data_format = w1.get_DATA_FORMAT();
    558 		bc.dst_sel[0] = w1.get_DST_SEL_X();
    559 		bc.dst_sel[1] = w1.get_DST_SEL_Y();
    560 		bc.dst_sel[2] = w1.get_DST_SEL_Z();
    561 		bc.dst_sel[3] = w1.get_DST_SEL_W();
    562 		bc.format_comp_all = w1.get_FORMAT_COMP_ALL();
    563 		bc.num_format_all = w1.get_NUM_FORMAT_ALL();
    564 		bc.srf_mode_all = w1.get_SRF_MODE_ALL();
    565 		bc.use_const_fields = w1.get_USE_CONST_FIELDS();
    566 
    567 		bc.semantic_id = w1.get_SEMANTIC_ID();
    568 
    569 	} else {
    570 		VTX_WORD1_GPR_ALL w1(dw1);
    571 		bc.data_format = w1.get_DATA_FORMAT();
    572 		bc.dst_sel[0] = w1.get_DST_SEL_X();
    573 		bc.dst_sel[1] = w1.get_DST_SEL_Y();
    574 		bc.dst_sel[2] = w1.get_DST_SEL_Z();
    575 		bc.dst_sel[3] = w1.get_DST_SEL_W();
    576 		bc.format_comp_all = w1.get_FORMAT_COMP_ALL();
    577 		bc.num_format_all = w1.get_NUM_FORMAT_ALL();
    578 		bc.srf_mode_all = w1.get_SRF_MODE_ALL();
    579 		bc.use_const_fields = w1.get_USE_CONST_FIELDS();
    580 
    581 		bc.dst_gpr = w1.get_DST_GPR();
    582 		bc.dst_rel = w1.get_DST_REL();
    583 	}
    584 
    585 	switch (ctx.hw_class) {
    586 	case HW_CLASS_R600:
    587 	{
    588 		VTX_WORD2_R6 w2(dw2);
    589 		bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
    590 		bc.endian_swap = w2.get_ENDIAN_SWAP();
    591 		bc.mega_fetch = w2.get_MEGA_FETCH();
    592 		bc.offset[0] = w2.get_OFFSET();
    593 		break;
    594 	}
    595 	case HW_CLASS_R700:
    596 	{
    597 		VTX_WORD2_R7 w2(dw2);
    598 		bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
    599 		bc.endian_swap = w2.get_ENDIAN_SWAP();
    600 		bc.mega_fetch = w2.get_MEGA_FETCH();
    601 		bc.offset[0] = w2.get_OFFSET();
    602 		bc.alt_const = w2.get_ALT_CONST();
    603 		break;
    604 	}
    605 	case HW_CLASS_EVERGREEN:
    606 	{
    607 		VTX_WORD2_EG w2(dw2);
    608 		bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
    609 		bc.endian_swap = w2.get_ENDIAN_SWAP();
    610 		bc.mega_fetch = w2.get_MEGA_FETCH();
    611 		bc.offset[0] = w2.get_OFFSET();
    612 		bc.alt_const = w2.get_ALT_CONST();
    613 		bc.resource_index_mode = w2.get_BUFFER_INDEX_MODE();
    614 		break;
    615 	}
    616 	case HW_CLASS_CAYMAN:
    617 	{
    618 		VTX_WORD2_CM w2(dw2);
    619 		bc.const_buf_no_stride = w2.get_CONST_BUF_NO_STRIDE();
    620 		bc.endian_swap = w2.get_ENDIAN_SWAP();
    621 		bc.offset[0] = w2.get_OFFSET();
    622 		bc.alt_const = w2.get_ALT_CONST();
    623 		bc.resource_index_mode = w2.get_BUFFER_INDEX_MODE();
    624 		break;
    625 	}
    626 	default:
    627 		assert(!"unknown hw class");
    628 		return -1;
    629 	}
    630 
    631 	return r;
    632 }
    633 
    634 }
    635