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