• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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