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