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