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 #include "sb_shader.h" 29 #include "sb_pass.h" 30 31 namespace r600_sb { 32 33 bc_builder::bc_builder(shader &s) 34 : sh(s), ctx(s.get_ctx()), bb(ctx.hw_class_bit()), error(0) {} 35 36 int bc_builder::build() { 37 38 container_node *root = sh.root; 39 int cf_cnt = 0; 40 41 // FIXME reserve total size to avoid reallocs 42 43 for (node_iterator it = root->begin(), end = root->end(); 44 it != end; ++it) { 45 46 cf_node *cf = static_cast<cf_node*>(*it); 47 assert(cf->is_cf_inst() || cf->is_alu_clause() || cf->is_fetch_clause()); 48 49 cf_op_flags flags = (cf_op_flags)cf->bc.op_ptr->flags; 50 51 cf->bc.id = cf_cnt++; 52 53 if (flags & CF_ALU) { 54 if (cf->bc.is_alu_extended()) 55 cf_cnt++; 56 } 57 } 58 59 bb.set_size(cf_cnt << 1); 60 bb.seek(cf_cnt << 1); 61 62 unsigned cf_pos = 0; 63 64 for (node_iterator I = root->begin(), end = root->end(); 65 I != end; ++I) { 66 67 cf_node *cf = static_cast<cf_node*>(*I); 68 cf_op_flags flags = (cf_op_flags)cf->bc.op_ptr->flags; 69 70 if (flags & CF_ALU) { 71 bb.seek(bb.ndw()); 72 cf->bc.addr = bb.ndw() >> 1; 73 build_alu_clause(cf); 74 cf->bc.count = (bb.ndw() >> 1) - cf->bc.addr - 1; 75 } else if (flags & CF_FETCH) { 76 bb.align(4); 77 bb.seek(bb.ndw()); 78 cf->bc.addr = bb.ndw() >> 1; 79 build_fetch_clause(cf); 80 cf->bc.count = (((bb.ndw() >> 1) - cf->bc.addr) >> 1) - 1; 81 } else if (cf->jump_target) { 82 cf->bc.addr = cf->jump_target->bc.id; 83 if (cf->jump_after_target) 84 cf->bc.addr += 1; 85 } 86 87 bb.seek(cf_pos); 88 build_cf(cf); 89 cf_pos = bb.get_pos(); 90 } 91 92 return 0; 93 } 94 95 int bc_builder::build_alu_clause(cf_node* n) { 96 for (node_iterator I = n->begin(), E = n->end(); 97 I != E; ++I) { 98 99 alu_group_node *g = static_cast<alu_group_node*>(*I); 100 assert(g->is_valid()); 101 102 build_alu_group(g); 103 } 104 return 0; 105 } 106 107 int bc_builder::build_alu_group(alu_group_node* n) { 108 109 for (node_iterator I = n->begin(), E = n->end(); 110 I != E; ++I) { 111 112 alu_node *a = static_cast<alu_node*>(*I); 113 assert(a->is_valid()); 114 build_alu(a); 115 } 116 117 for(int i = 0, ls = n->literals.size(); i < ls; ++i) { 118 bb << n->literals.at(i).u; 119 } 120 121 bb.align(2); 122 bb.seek(bb.ndw()); 123 124 return 0; 125 } 126 127 int bc_builder::build_fetch_clause(cf_node* n) { 128 for (node_iterator I = n->begin(), E = n->end(); 129 I != E; ++I) { 130 fetch_node *f = static_cast<fetch_node*>(*I); 131 132 if (f->bc.op_ptr->flags & FF_GDS) 133 build_fetch_gds(f); 134 else if (f->bc.op_ptr->flags & FF_VTX) 135 build_fetch_vtx(f); 136 else 137 build_fetch_tex(f); 138 } 139 return 0; 140 } 141 142 143 int bc_builder::build_cf(cf_node* n) { 144 const bc_cf &bc = n->bc; 145 const cf_op_info *cfop = bc.op_ptr; 146 147 if (cfop->flags & CF_ALU) 148 return build_cf_alu(n); 149 if (cfop->flags & (CF_EXP | CF_MEM)) 150 return build_cf_exp(n); 151 152 if (ctx.is_egcm()) { 153 bb << CF_WORD0_EGCM() 154 .ADDR(bc.addr) 155 .JUMPTABLE_SEL(bc.jumptable_sel); 156 157 if (ctx.is_evergreen()) 158 159 bb << CF_WORD1_EG() 160 .BARRIER(bc.barrier) 161 .CF_CONST(bc.cf_const) 162 .CF_INST(ctx.cf_opcode(bc.op)) 163 .COND(bc.cond) 164 .COUNT(bc.count) 165 .END_OF_PROGRAM(bc.end_of_program) 166 .POP_COUNT(bc.pop_count) 167 .VALID_PIXEL_MODE(bc.valid_pixel_mode) 168 .WHOLE_QUAD_MODE(bc.whole_quad_mode); 169 170 else //cayman 171 172 bb << CF_WORD1_CM() 173 .BARRIER(bc.barrier) 174 .CF_CONST(bc.cf_const) 175 .CF_INST(ctx.cf_opcode(bc.op)) 176 .COND(bc.cond) 177 .COUNT(bc.count) 178 .POP_COUNT(bc.pop_count) 179 .VALID_PIXEL_MODE(bc.valid_pixel_mode); 180 } else { 181 bb << CF_WORD0_R6R7() 182 .ADDR(bc.addr); 183 184 assert(bc.count < ctx.max_fetch); 185 186 bb << CF_WORD1_R6R7() 187 .BARRIER(bc.barrier) 188 .CALL_COUNT(bc.call_count) 189 .CF_CONST(bc.cf_const) 190 .CF_INST(ctx.cf_opcode(bc.op)) 191 .COND(bc.cond) 192 .COUNT(bc.count & 7) 193 .COUNT_3(bc.count >> 3) 194 .END_OF_PROGRAM(bc.end_of_program) 195 .POP_COUNT(bc.pop_count) 196 .VALID_PIXEL_MODE(bc.valid_pixel_mode) 197 .WHOLE_QUAD_MODE(bc.whole_quad_mode); 198 } 199 200 return 0; 201 } 202 203 int bc_builder::build_cf_alu(cf_node* n) { 204 const bc_cf &bc = n->bc; 205 206 assert(bc.count < 128); 207 208 if (n->bc.is_alu_extended()) { 209 assert(ctx.is_egcm()); 210 211 bb << CF_ALU_WORD0_EXT_EGCM() 212 .KCACHE_BANK2(bc.kc[2].bank) 213 .KCACHE_BANK3(bc.kc[3].bank) 214 .KCACHE_BANK_INDEX_MODE0(bc.kc[0].index_mode) 215 .KCACHE_BANK_INDEX_MODE1(bc.kc[1].index_mode) 216 .KCACHE_BANK_INDEX_MODE2(bc.kc[2].index_mode) 217 .KCACHE_BANK_INDEX_MODE3(bc.kc[3].index_mode) 218 .KCACHE_MODE2(bc.kc[2].mode); 219 220 bb << CF_ALU_WORD1_EXT_EGCM() 221 .BARRIER(bc.barrier) 222 .CF_INST(ctx.cf_opcode(CF_OP_ALU_EXT)) 223 .KCACHE_ADDR2(bc.kc[2].addr) 224 .KCACHE_ADDR3(bc.kc[3].addr) 225 .KCACHE_MODE3(bc.kc[3].mode); 226 } 227 228 bb << CF_ALU_WORD0_ALL() 229 .ADDR(bc.addr) 230 .KCACHE_BANK0(bc.kc[0].bank) 231 .KCACHE_BANK1(bc.kc[1].bank) 232 .KCACHE_MODE0(bc.kc[0].mode); 233 234 assert(bc.count < 128); 235 236 if (ctx.is_r600()) 237 bb << CF_ALU_WORD1_R6() 238 .BARRIER(bc.barrier) 239 .CF_INST(ctx.cf_opcode(bc.op)) 240 .COUNT(bc.count) 241 .KCACHE_ADDR0(bc.kc[0].addr) 242 .KCACHE_ADDR1(bc.kc[1].addr) 243 .KCACHE_MODE1(bc.kc[1].mode) 244 .USES_WATERFALL(bc.uses_waterfall) 245 .WHOLE_QUAD_MODE(bc.whole_quad_mode); 246 else 247 bb << CF_ALU_WORD1_R7EGCM() 248 .ALT_CONST(bc.alt_const) 249 .BARRIER(bc.barrier) 250 .CF_INST(ctx.cf_opcode(bc.op)) 251 .COUNT(bc.count) 252 .KCACHE_ADDR0(bc.kc[0].addr) 253 .KCACHE_ADDR1(bc.kc[1].addr) 254 .KCACHE_MODE1(bc.kc[1].mode) 255 .WHOLE_QUAD_MODE(bc.whole_quad_mode); 256 257 return 0; 258 } 259 260 int bc_builder::build_cf_exp(cf_node* n) { 261 const bc_cf &bc = n->bc; 262 const cf_op_info *cfop = bc.op_ptr; 263 264 if (cfop->flags & CF_RAT) { 265 assert(ctx.is_egcm()); 266 267 bb << CF_ALLOC_EXPORT_WORD0_RAT_EGCM() 268 .ELEM_SIZE(bc.elem_size) 269 .INDEX_GPR(bc.index_gpr) 270 .RAT_ID(bc.rat_id) 271 .RAT_INDEX_MODE(bc.rat_index_mode) 272 .RAT_INST(bc.rat_inst) 273 .RW_GPR(bc.rw_gpr) 274 .RW_REL(bc.rw_rel) 275 .TYPE(bc.type); 276 } else { 277 278 bb << CF_ALLOC_EXPORT_WORD0_ALL() 279 .ARRAY_BASE(bc.array_base) 280 .ELEM_SIZE(bc.elem_size) 281 .INDEX_GPR(bc.index_gpr) 282 .RW_GPR(bc.rw_gpr) 283 .RW_REL(bc.rw_rel) 284 .TYPE(bc.type); 285 } 286 287 if (cfop->flags & CF_EXP) { 288 289 if (!ctx.is_egcm()) 290 bb << CF_ALLOC_EXPORT_WORD1_SWIZ_R6R7() 291 .BARRIER(bc.barrier) 292 .BURST_COUNT(bc.burst_count) 293 .CF_INST(ctx.cf_opcode(bc.op)) 294 .END_OF_PROGRAM(bc.end_of_program) 295 .SEL_X(bc.sel[0]) 296 .SEL_Y(bc.sel[1]) 297 .SEL_Z(bc.sel[2]) 298 .SEL_W(bc.sel[3]) 299 .VALID_PIXEL_MODE(bc.valid_pixel_mode) 300 .WHOLE_QUAD_MODE(bc.whole_quad_mode); 301 302 else if (ctx.is_evergreen()) 303 bb << CF_ALLOC_EXPORT_WORD1_SWIZ_EG() 304 .BARRIER(bc.barrier) 305 .BURST_COUNT(bc.burst_count) 306 .CF_INST(ctx.cf_opcode(bc.op)) 307 .END_OF_PROGRAM(bc.end_of_program) 308 .MARK(bc.mark) 309 .SEL_X(bc.sel[0]) 310 .SEL_Y(bc.sel[1]) 311 .SEL_Z(bc.sel[2]) 312 .SEL_W(bc.sel[3]) 313 .VALID_PIXEL_MODE(bc.valid_pixel_mode); 314 315 else // cayman 316 bb << CF_ALLOC_EXPORT_WORD1_SWIZ_CM() 317 .BARRIER(bc.barrier) 318 .BURST_COUNT(bc.burst_count) 319 .CF_INST(ctx.cf_opcode(bc.op)) 320 .MARK(bc.mark) 321 .SEL_X(bc.sel[0]) 322 .SEL_Y(bc.sel[1]) 323 .SEL_Z(bc.sel[2]) 324 .SEL_W(bc.sel[3]) 325 .VALID_PIXEL_MODE(bc.valid_pixel_mode); 326 327 } else if (cfop->flags & CF_MEM) { 328 return build_cf_mem(n); 329 } 330 331 return 0; 332 } 333 334 int bc_builder::build_cf_mem(cf_node* n) { 335 const bc_cf &bc = n->bc; 336 337 if (!ctx.is_egcm()) 338 bb << CF_ALLOC_EXPORT_WORD1_BUF_R6R7() 339 .ARR_SIZE(bc.array_size) 340 .BARRIER(bc.barrier) 341 .BURST_COUNT(bc.burst_count) 342 .CF_INST(ctx.cf_opcode(bc.op)) 343 .COMP_MASK(bc.comp_mask) 344 .END_OF_PROGRAM(bc.end_of_program) 345 .VALID_PIXEL_MODE(bc.valid_pixel_mode) 346 .WHOLE_QUAD_MODE(bc.whole_quad_mode); 347 348 else if (ctx.is_evergreen()) 349 bb << CF_ALLOC_EXPORT_WORD1_BUF_EG() 350 .ARR_SIZE(bc.array_size) 351 .BARRIER(bc.barrier) 352 .BURST_COUNT(bc.burst_count) 353 .CF_INST(ctx.cf_opcode(bc.op)) 354 .COMP_MASK(bc.comp_mask) 355 .END_OF_PROGRAM(bc.end_of_program) 356 .MARK(bc.mark) 357 .VALID_PIXEL_MODE(bc.valid_pixel_mode); 358 359 else // cayman 360 bb << CF_ALLOC_EXPORT_WORD1_BUF_CM() 361 .ARR_SIZE(bc.array_size) 362 .BARRIER(bc.barrier) 363 .BURST_COUNT(bc.burst_count) 364 .CF_INST(ctx.cf_opcode(bc.op)) 365 .COMP_MASK(bc.comp_mask) 366 .MARK(bc.mark) 367 .VALID_PIXEL_MODE(bc.valid_pixel_mode); 368 369 return 0; 370 } 371 372 int bc_builder::build_alu(alu_node* n) { 373 const bc_alu &bc = n->bc; 374 const alu_op_info *aop = bc.op_ptr; 375 376 if (n->bc.op_ptr->flags & AF_LDS) { 377 assert(ctx.is_egcm()); 378 bb << ALU_WORD0_LDS_IDX_OP_EGCM() 379 .SRC0_SEL(bc.src[0].sel) 380 .SRC0_REL(bc.src[0].rel) 381 .SRC0_CHAN(bc.src[0].chan) 382 .IDX_OFFSET_4((bc.lds_idx_offset >> 4) & 1) 383 .SRC1_SEL(bc.src[1].sel) 384 .SRC1_REL(bc.src[1].rel) 385 .SRC1_CHAN(bc.src[1].chan) 386 .IDX_OFFSET_5((bc.lds_idx_offset >> 5) & 1) 387 .INDEX_MODE(bc.index_mode) 388 .PRED_SEL(bc.pred_sel) 389 .LAST(bc.last); 390 391 bb << ALU_WORD1_LDS_IDX_OP_EGCM() 392 .SRC2_SEL(bc.src[2].sel) 393 .SRC2_REL(bc.src[2].rel) 394 .SRC2_CHAN(bc.src[2].chan) 395 .IDX_OFFSET_1((bc.lds_idx_offset >> 1) & 1) 396 .ALU_INST(ctx.alu_opcode(ALU_OP3_LDS_IDX_OP)) 397 .BANK_SWIZZLE(bc.bank_swizzle) 398 .LDS_OP((bc.op_ptr->opcode[1] >> 8) & 0xff) 399 .IDX_OFFSET_0((bc.lds_idx_offset >> 0) & 1) 400 .IDX_OFFSET_2((bc.lds_idx_offset >> 2) & 1) 401 .DST_CHAN(bc.dst_chan) 402 .IDX_OFFSET_3((bc.lds_idx_offset >> 3) & 1); 403 404 return 0; 405 } 406 407 bb << ALU_WORD0_ALL() 408 .INDEX_MODE(bc.index_mode) 409 .LAST(bc.last) 410 .PRED_SEL(bc.pred_sel) 411 .SRC0_SEL(bc.src[0].sel) 412 .SRC0_CHAN(bc.src[0].chan) 413 .SRC0_NEG(bc.src[0].neg) 414 .SRC0_REL(bc.src[0].rel) 415 .SRC1_SEL(bc.src[1].sel) 416 .SRC1_CHAN(bc.src[1].chan) 417 .SRC1_NEG(bc.src[1].neg) 418 .SRC1_REL(bc.src[1].rel); 419 420 if (aop->src_count<3) { 421 if (ctx.is_r600()) 422 bb << ALU_WORD1_OP2_R6() 423 .ALU_INST(ctx.alu_opcode(bc.op)) 424 .BANK_SWIZZLE(bc.bank_swizzle) 425 .CLAMP(bc.clamp) 426 .DST_GPR(bc.dst_gpr) 427 .DST_CHAN(bc.dst_chan) 428 .DST_REL(bc.dst_rel) 429 .FOG_MERGE(bc.fog_merge) 430 .OMOD(bc.omod) 431 .SRC0_ABS(bc.src[0].abs) 432 .SRC1_ABS(bc.src[1].abs) 433 .UPDATE_EXEC_MASK(bc.update_exec_mask) 434 .UPDATE_PRED(bc.update_pred) 435 .WRITE_MASK(bc.write_mask); 436 else { 437 438 if (ctx.is_cayman() && (aop->flags & AF_MOVA)) { 439 440 bb << ALU_WORD1_OP2_MOVA_CM() 441 .ALU_INST(ctx.alu_opcode(bc.op)) 442 .BANK_SWIZZLE(bc.bank_swizzle) 443 .CLAMP(bc.clamp) 444 .MOVA_DST(bc.dst_gpr) 445 .DST_CHAN(bc.dst_chan) 446 .DST_REL(bc.dst_rel) 447 .OMOD(bc.omod) 448 .UPDATE_EXEC_MASK(bc.update_exec_mask) 449 .UPDATE_PRED(bc.update_pred) 450 .WRITE_MASK(bc.write_mask) 451 .SRC0_ABS(bc.src[0].abs) 452 .SRC1_ABS(bc.src[1].abs); 453 454 } else if (ctx.is_cayman() && (aop->flags & (AF_PRED|AF_KILL))) { 455 bb << ALU_WORD1_OP2_EXEC_MASK_CM() 456 .ALU_INST(ctx.alu_opcode(bc.op)) 457 .BANK_SWIZZLE(bc.bank_swizzle) 458 .CLAMP(bc.clamp) 459 .DST_CHAN(bc.dst_chan) 460 .DST_REL(bc.dst_rel) 461 .EXECUTE_MASK_OP(bc.omod) 462 .UPDATE_EXEC_MASK(bc.update_exec_mask) 463 .UPDATE_PRED(bc.update_pred) 464 .WRITE_MASK(bc.write_mask) 465 .SRC0_ABS(bc.src[0].abs) 466 .SRC1_ABS(bc.src[1].abs); 467 468 } else 469 bb << ALU_WORD1_OP2_R7EGCM() 470 .ALU_INST(ctx.alu_opcode(bc.op)) 471 .BANK_SWIZZLE(bc.bank_swizzle) 472 .CLAMP(bc.clamp) 473 .DST_GPR(bc.dst_gpr) 474 .DST_CHAN(bc.dst_chan) 475 .DST_REL(bc.dst_rel) 476 .OMOD(bc.omod) 477 .UPDATE_EXEC_MASK(bc.update_exec_mask) 478 .UPDATE_PRED(bc.update_pred) 479 .WRITE_MASK(bc.write_mask) 480 .SRC0_ABS(bc.src[0].abs) 481 .SRC1_ABS(bc.src[1].abs); 482 483 } 484 } else 485 bb << ALU_WORD1_OP3_ALL() 486 .ALU_INST(ctx.alu_opcode(bc.op)) 487 .BANK_SWIZZLE(bc.bank_swizzle) 488 .CLAMP(bc.clamp) 489 .DST_GPR(bc.dst_gpr) 490 .DST_CHAN(bc.dst_chan) 491 .DST_REL(bc.dst_rel) 492 .SRC2_SEL(bc.src[2].sel) 493 .SRC2_CHAN(bc.src[2].chan) 494 .SRC2_NEG(bc.src[2].neg) 495 .SRC2_REL(bc.src[2].rel); 496 return 0; 497 } 498 499 int bc_builder::build_fetch_tex(fetch_node* n) { 500 const bc_fetch &bc = n->bc; 501 const fetch_op_info *fop = bc.op_ptr; 502 503 assert(!(fop->flags & FF_VTX)); 504 505 if (ctx.is_r600()) 506 bb << TEX_WORD0_R6() 507 .BC_FRAC_MODE(bc.bc_frac_mode) 508 .FETCH_WHOLE_QUAD(bc.fetch_whole_quad) 509 .RESOURCE_ID(bc.resource_id) 510 .SRC_GPR(bc.src_gpr) 511 .SRC_REL(bc.src_rel) 512 .TEX_INST(ctx.fetch_opcode(bc.op)); 513 514 else if (ctx.is_r700()) 515 bb << TEX_WORD0_R7() 516 .ALT_CONST(bc.alt_const) 517 .BC_FRAC_MODE(bc.bc_frac_mode) 518 .FETCH_WHOLE_QUAD(bc.fetch_whole_quad) 519 .RESOURCE_ID(bc.resource_id) 520 .SRC_GPR(bc.src_gpr) 521 .SRC_REL(bc.src_rel) 522 .TEX_INST(ctx.fetch_opcode(bc.op)); 523 524 else 525 bb << TEX_WORD0_EGCM() 526 .ALT_CONST(bc.alt_const) 527 .FETCH_WHOLE_QUAD(bc.fetch_whole_quad) 528 .INST_MOD(bc.inst_mod) 529 .RESOURCE_ID(bc.resource_id) 530 .RESOURCE_INDEX_MODE(bc.resource_index_mode) 531 .SAMPLER_INDEX_MODE(bc.sampler_index_mode) 532 .SRC_GPR(bc.src_gpr) 533 .SRC_REL(bc.src_rel) 534 .TEX_INST(ctx.fetch_opcode(bc.op)); 535 536 bb << TEX_WORD1_ALL() 537 .COORD_TYPE_X(bc.coord_type[0]) 538 .COORD_TYPE_Y(bc.coord_type[1]) 539 .COORD_TYPE_Z(bc.coord_type[2]) 540 .COORD_TYPE_W(bc.coord_type[3]) 541 .DST_GPR(bc.dst_gpr) 542 .DST_REL(bc.dst_rel) 543 .DST_SEL_X(bc.dst_sel[0]) 544 .DST_SEL_Y(bc.dst_sel[1]) 545 .DST_SEL_Z(bc.dst_sel[2]) 546 .DST_SEL_W(bc.dst_sel[3]) 547 .LOD_BIAS(bc.lod_bias); 548 549 bb << TEX_WORD2_ALL() 550 .OFFSET_X(bc.offset[0]) 551 .OFFSET_Y(bc.offset[1]) 552 .OFFSET_Z(bc.offset[2]) 553 .SAMPLER_ID(bc.sampler_id) 554 .SRC_SEL_X(bc.src_sel[0]) 555 .SRC_SEL_Y(bc.src_sel[1]) 556 .SRC_SEL_Z(bc.src_sel[2]) 557 .SRC_SEL_W(bc.src_sel[3]); 558 559 bb << 0; 560 return 0; 561 } 562 563 int bc_builder::build_fetch_gds(fetch_node *n) { 564 const bc_fetch &bc = n->bc; 565 const fetch_op_info *fop = bc.op_ptr; 566 unsigned gds_op = (ctx.fetch_opcode(bc.op) >> 8) & 0x3f; 567 unsigned mem_op = 4; 568 assert(fop->flags && FF_GDS); 569 570 if (bc.op == FETCH_OP_TF_WRITE) { 571 mem_op = 5; 572 gds_op = 0; 573 } 574 575 bb << MEM_GDS_WORD0_EGCM() 576 .MEM_INST(2) 577 .MEM_OP(mem_op) 578 .SRC_GPR(bc.src_gpr) 579 .SRC_SEL_X(bc.src_sel[0]) 580 .SRC_SEL_Y(bc.src_sel[1]) 581 .SRC_SEL_Z(bc.src_sel[2]); 582 583 bb << MEM_GDS_WORD1_EGCM() 584 .DST_GPR(bc.dst_gpr) 585 .DST_REL_MODE(bc.dst_rel) 586 .GDS_OP(gds_op) 587 .SRC_GPR(bc.src2_gpr) 588 .UAV_INDEX_MODE(bc.uav_index_mode) 589 .UAV_ID(bc.uav_id) 590 .ALLOC_CONSUME(bc.alloc_consume) 591 .BCAST_FIRST_REQ(bc.bcast_first_req); 592 593 bb << MEM_GDS_WORD2_EGCM() 594 .DST_SEL_X(bc.dst_sel[0]) 595 .DST_SEL_Y(bc.dst_sel[1]) 596 .DST_SEL_Z(bc.dst_sel[2]) 597 .DST_SEL_W(bc.dst_sel[3]); 598 599 bb << 0; 600 return 0; 601 } 602 603 int bc_builder::build_fetch_vtx(fetch_node* n) { 604 const bc_fetch &bc = n->bc; 605 const fetch_op_info *fop = bc.op_ptr; 606 607 assert(fop->flags & FF_VTX); 608 609 if (!ctx.is_cayman()) 610 bb << VTX_WORD0_R6R7EG() 611 .BUFFER_ID(bc.resource_id) 612 .FETCH_TYPE(bc.fetch_type) 613 .FETCH_WHOLE_QUAD(bc.fetch_whole_quad) 614 .MEGA_FETCH_COUNT(bc.mega_fetch_count) 615 .SRC_GPR(bc.src_gpr) 616 .SRC_REL(bc.src_rel) 617 .SRC_SEL_X(bc.src_sel[0]) 618 .VC_INST(ctx.fetch_opcode(bc.op)); 619 620 else 621 bb << VTX_WORD0_CM() 622 .BUFFER_ID(bc.resource_id) 623 .COALESCED_READ(bc.coalesced_read) 624 .FETCH_TYPE(bc.fetch_type) 625 .FETCH_WHOLE_QUAD(bc.fetch_whole_quad) 626 .LDS_REQ(bc.lds_req) 627 .SRC_GPR(bc.src_gpr) 628 .SRC_REL(bc.src_rel) 629 .SRC_SEL_X(bc.src_sel[0]) 630 .SRC_SEL_Y(bc.src_sel[1]) 631 .STRUCTURED_READ(bc.structured_read) 632 .VC_INST(ctx.fetch_opcode(bc.op)); 633 634 if (bc.op == FETCH_OP_SEMFETCH) 635 bb << VTX_WORD1_SEM_ALL() 636 .DATA_FORMAT(bc.data_format) 637 .DST_SEL_X(bc.dst_sel[0]) 638 .DST_SEL_Y(bc.dst_sel[1]) 639 .DST_SEL_Z(bc.dst_sel[2]) 640 .DST_SEL_W(bc.dst_sel[3]) 641 .FORMAT_COMP_ALL(bc.format_comp_all) 642 .NUM_FORMAT_ALL(bc.num_format_all) 643 .SEMANTIC_ID(bc.semantic_id) 644 .SRF_MODE_ALL(bc.srf_mode_all) 645 .USE_CONST_FIELDS(bc.use_const_fields); 646 else 647 bb << VTX_WORD1_GPR_ALL() 648 .DATA_FORMAT(bc.data_format) 649 .DST_GPR(bc.dst_gpr) 650 .DST_REL(bc.dst_rel) 651 .DST_SEL_X(bc.dst_sel[0]) 652 .DST_SEL_Y(bc.dst_sel[1]) 653 .DST_SEL_Z(bc.dst_sel[2]) 654 .DST_SEL_W(bc.dst_sel[3]) 655 .FORMAT_COMP_ALL(bc.format_comp_all) 656 .NUM_FORMAT_ALL(bc.num_format_all) 657 .SRF_MODE_ALL(bc.srf_mode_all) 658 .USE_CONST_FIELDS(bc.use_const_fields); 659 660 switch (ctx.hw_class) { 661 case HW_CLASS_R600: 662 bb << VTX_WORD2_R6() 663 .CONST_BUF_NO_STRIDE(bc.const_buf_no_stride) 664 .ENDIAN_SWAP(bc.endian_swap) 665 .MEGA_FETCH(bc.mega_fetch) 666 .OFFSET(bc.offset[0]); 667 break; 668 case HW_CLASS_R700: 669 bb << VTX_WORD2_R7() 670 .ALT_CONST(bc.alt_const) 671 .CONST_BUF_NO_STRIDE(bc.const_buf_no_stride) 672 .ENDIAN_SWAP(bc.endian_swap) 673 .MEGA_FETCH(bc.mega_fetch) 674 .OFFSET(bc.offset[0]); 675 break; 676 case HW_CLASS_EVERGREEN: 677 bb << VTX_WORD2_EG() 678 .ALT_CONST(bc.alt_const) 679 .BUFFER_INDEX_MODE(bc.resource_index_mode) 680 .CONST_BUF_NO_STRIDE(bc.const_buf_no_stride) 681 .ENDIAN_SWAP(bc.endian_swap) 682 .MEGA_FETCH(bc.mega_fetch) 683 .OFFSET(bc.offset[0]); 684 break; 685 case HW_CLASS_CAYMAN: 686 bb << VTX_WORD2_CM() 687 .ALT_CONST(bc.alt_const) 688 .BUFFER_INDEX_MODE(bc.resource_index_mode) 689 .CONST_BUF_NO_STRIDE(bc.const_buf_no_stride) 690 .ENDIAN_SWAP(bc.endian_swap) 691 .OFFSET(bc.offset[0]); 692 break; 693 default: 694 assert(!"unknown hw class"); 695 return -1; 696 } 697 698 bb << 0; 699 return 0; 700 } 701 702 } 703