Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Copyright 2013 Vadim Girlin 
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(*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(*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(*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(*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(*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
 
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
 
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
 
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
 
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
				.ARRAY_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
				.ARRAY_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
		.ARRAY_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
 
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
	bb << ALU_WORD0_ALL()
375
			.INDEX_MODE(bc.index_mode)
376
			.LAST(bc.last)
377
			.PRED_SEL(bc.pred_sel)
378
			.SRC0_SEL(bc.src[0].sel)
379
			.SRC0_CHAN(bc.src[0].chan)
380
			.SRC0_NEG(bc.src[0].neg)
381
			.SRC0_REL(bc.src[0].rel)
382
			.SRC1_SEL(bc.src[1].sel)
383
			.SRC1_CHAN(bc.src[1].chan)
384
			.SRC1_NEG(bc.src[1].neg)
385
			.SRC1_REL(bc.src[1].rel);
386
 
387
	if (aop->src_count<3) {
388
		if (ctx.is_r600())
389
			bb << ALU_WORD1_OP2_R6()
390
					.ALU_INST(ctx.alu_opcode(bc.op))
391
					.BANK_SWIZZLE(bc.bank_swizzle)
392
					.CLAMP(bc.clamp)
393
					.DST_GPR(bc.dst_gpr)
394
					.DST_CHAN(bc.dst_chan)
395
					.DST_REL(bc.dst_rel)
396
					.FOG_MERGE(bc.fog_merge)
397
					.OMOD(bc.omod)
398
					.SRC0_ABS(bc.src[0].abs)
399
					.SRC1_ABS(bc.src[1].abs)
400
					.UPDATE_EXEC_MASK(bc.update_exec_mask)
401
					.UPDATE_PRED(bc.update_pred)
402
					.WRITE_MASK(bc.write_mask);
403
		else {
404
 
405
			if (ctx.is_cayman() && (aop->flags & AF_MOVA)) {
406
 
407
				bb << ALU_WORD1_OP2_MOVA_CM()
408
						.ALU_INST(ctx.alu_opcode(bc.op))
409
						.BANK_SWIZZLE(bc.bank_swizzle)
410
						.CLAMP(bc.clamp)
411
						.MOVA_DST(bc.dst_gpr)
412
						.DST_CHAN(bc.dst_chan)
413
						.DST_REL(bc.dst_rel)
414
						.OMOD(bc.omod)
415
						.UPDATE_EXEC_MASK(bc.update_exec_mask)
416
						.UPDATE_PRED(bc.update_pred)
417
						.WRITE_MASK(bc.write_mask)
418
						.SRC0_ABS(bc.src[0].abs)
419
						.SRC1_ABS(bc.src[1].abs);
420
 
421
			} else if (ctx.is_cayman() && (aop->flags & (AF_PRED|AF_KILL))) {
422
				bb << ALU_WORD1_OP2_EXEC_MASK_CM()
423
						.ALU_INST(ctx.alu_opcode(bc.op))
424
						.BANK_SWIZZLE(bc.bank_swizzle)
425
						.CLAMP(bc.clamp)
426
						.DST_CHAN(bc.dst_chan)
427
						.DST_REL(bc.dst_rel)
428
						.EXECUTE_MASK_OP(bc.omod)
429
						.UPDATE_EXEC_MASK(bc.update_exec_mask)
430
						.UPDATE_PRED(bc.update_pred)
431
						.WRITE_MASK(bc.write_mask)
432
						.SRC0_ABS(bc.src[0].abs)
433
						.SRC1_ABS(bc.src[1].abs);
434
 
435
			} else
436
				bb << ALU_WORD1_OP2_R7EGCM()
437
						.ALU_INST(ctx.alu_opcode(bc.op))
438
						.BANK_SWIZZLE(bc.bank_swizzle)
439
						.CLAMP(bc.clamp)
440
						.DST_GPR(bc.dst_gpr)
441
						.DST_CHAN(bc.dst_chan)
442
						.DST_REL(bc.dst_rel)
443
						.OMOD(bc.omod)
444
						.UPDATE_EXEC_MASK(bc.update_exec_mask)
445
						.UPDATE_PRED(bc.update_pred)
446
						.WRITE_MASK(bc.write_mask)
447
						.SRC0_ABS(bc.src[0].abs)
448
						.SRC1_ABS(bc.src[1].abs);
449
 
450
		}
451
	} else
452
		bb << ALU_WORD1_OP3_ALL()
453
				.ALU_INST(ctx.alu_opcode(bc.op))
454
				.BANK_SWIZZLE(bc.bank_swizzle)
455
				.CLAMP(bc.clamp)
456
				.DST_GPR(bc.dst_gpr)
457
				.DST_CHAN(bc.dst_chan)
458
				.DST_REL(bc.dst_rel)
459
				.SRC2_SEL(bc.src[2].sel)
460
				.SRC2_CHAN(bc.src[2].chan)
461
				.SRC2_NEG(bc.src[2].neg)
462
				.SRC2_REL(bc.src[2].rel);
463
	return 0;
464
}
465
 
466
int bc_builder::build_fetch_tex(fetch_node* n) {
467
	const bc_fetch &bc = n->bc;
468
	const fetch_op_info *fop = bc.op_ptr;
469
 
470
	assert(!(fop->flags & FF_VTX));
471
 
472
	if (ctx.is_r600())
473
		bb << TEX_WORD0_R6()
474
				.BC_FRAC_MODE(bc.bc_frac_mode)
475
				.FETCH_WHOLE_QUAD(bc.fetch_whole_quad)
476
				.RESOURCE_ID(bc.resource_id)
477
				.SRC_GPR(bc.src_gpr)
478
				.SRC_REL(bc.src_rel)
479
				.TEX_INST(ctx.fetch_opcode(bc.op));
480
 
481
	else if (ctx.is_r700())
482
		bb << TEX_WORD0_R7()
483
				.ALT_CONST(bc.alt_const)
484
				.BC_FRAC_MODE(bc.bc_frac_mode)
485
				.FETCH_WHOLE_QUAD(bc.fetch_whole_quad)
486
				.RESOURCE_ID(bc.resource_id)
487
				.SRC_GPR(bc.src_gpr)
488
				.SRC_REL(bc.src_rel)
489
				.TEX_INST(ctx.fetch_opcode(bc.op));
490
 
491
	else
492
		bb << TEX_WORD0_EGCM()
493
				.ALT_CONST(bc.alt_const)
494
				.FETCH_WHOLE_QUAD(bc.fetch_whole_quad)
495
				.INST_MOD(bc.inst_mod)
496
				.RESOURCE_ID(bc.resource_id)
497
				.RESOURCE_INDEX_MODE(bc.resource_index_mode)
498
				.SAMPLER_INDEX_MODE(bc.sampler_index_mode)
499
				.SRC_GPR(bc.src_gpr)
500
				.SRC_REL(bc.src_rel)
501
				.TEX_INST(ctx.fetch_opcode(bc.op));
502
 
503
	bb << TEX_WORD1_ALL()
504
			.COORD_TYPE_X(bc.coord_type[0])
505
			.COORD_TYPE_Y(bc.coord_type[1])
506
			.COORD_TYPE_Z(bc.coord_type[2])
507
			.COORD_TYPE_W(bc.coord_type[3])
508
			.DST_GPR(bc.dst_gpr)
509
			.DST_REL(bc.dst_rel)
510
			.DST_SEL_X(bc.dst_sel[0])
511
			.DST_SEL_Y(bc.dst_sel[1])
512
			.DST_SEL_Z(bc.dst_sel[2])
513
			.DST_SEL_W(bc.dst_sel[3])
514
			.LOD_BIAS(bc.lod_bias);
515
 
516
	bb << TEX_WORD2_ALL()
517
			.OFFSET_X(bc.offset[0])
518
			.OFFSET_Y(bc.offset[1])
519
			.OFFSET_Z(bc.offset[2])
520
			.SAMPLER_ID(bc.sampler_id)
521
			.SRC_SEL_X(bc.src_sel[0])
522
			.SRC_SEL_Y(bc.src_sel[1])
523
			.SRC_SEL_Z(bc.src_sel[2])
524
			.SRC_SEL_W(bc.src_sel[3]);
525
 
526
	bb << 0;
527
	return 0;
528
}
529
 
530
int bc_builder::build_fetch_vtx(fetch_node* n) {
531
	const bc_fetch &bc = n->bc;
532
	const fetch_op_info *fop = bc.op_ptr;
533
 
534
	assert(fop->flags & FF_VTX);
535
 
536
	if (!ctx.is_cayman())
537
		bb << VTX_WORD0_R6R7EG()
538
				.BUFFER_ID(bc.resource_id)
539
				.FETCH_TYPE(bc.fetch_type)
540
				.FETCH_WHOLE_QUAD(bc.fetch_whole_quad)
541
				.MEGA_FETCH_COUNT(bc.mega_fetch_count)
542
				.SRC_GPR(bc.src_gpr)
543
				.SRC_REL(bc.src_rel)
544
				.SRC_SEL_X(bc.src_sel[0])
545
				.VC_INST(ctx.fetch_opcode(bc.op));
546
 
547
	else
548
		bb << VTX_WORD0_CM()
549
				.BUFFER_ID(bc.resource_id)
550
				.COALESCED_READ(bc.coalesced_read)
551
				.FETCH_TYPE(bc.fetch_type)
552
				.FETCH_WHOLE_QUAD(bc.fetch_whole_quad)
553
				.LDS_REQ(bc.lds_req)
554
				.SRC_GPR(bc.src_gpr)
555
				.SRC_REL(bc.src_rel)
556
				.SRC_SEL_X(bc.src_sel[0])
557
				.SRC_SEL_Y(bc.src_sel[1])
558
				.STRUCTURED_READ(bc.structured_read)
559
				.VC_INST(ctx.fetch_opcode(bc.op));
560
 
561
	if (bc.op == FETCH_OP_SEMFETCH)
562
		bb << VTX_WORD1_SEM_ALL()
563
				.DATA_FORMAT(bc.data_format)
564
				.DST_SEL_X(bc.dst_sel[0])
565
				.DST_SEL_Y(bc.dst_sel[1])
566
				.DST_SEL_Z(bc.dst_sel[2])
567
				.DST_SEL_W(bc.dst_sel[3])
568
				.FORMAT_COMP_ALL(bc.format_comp_all)
569
				.NUM_FORMAT_ALL(bc.num_format_all)
570
				.SEMANTIC_ID(bc.semantic_id)
571
				.SRF_MODE_ALL(bc.srf_mode_all)
572
				.USE_CONST_FIELDS(bc.use_const_fields);
573
	else
574
		bb << VTX_WORD1_GPR_ALL()
575
				.DATA_FORMAT(bc.data_format)
576
				.DST_GPR(bc.dst_gpr)
577
				.DST_REL(bc.dst_rel)
578
				.DST_SEL_X(bc.dst_sel[0])
579
				.DST_SEL_Y(bc.dst_sel[1])
580
				.DST_SEL_Z(bc.dst_sel[2])
581
				.DST_SEL_W(bc.dst_sel[3])
582
				.FORMAT_COMP_ALL(bc.format_comp_all)
583
				.NUM_FORMAT_ALL(bc.num_format_all)
584
				.SRF_MODE_ALL(bc.srf_mode_all)
585
				.USE_CONST_FIELDS(bc.use_const_fields);
586
 
587
	switch (ctx.hw_class) {
588
	case HW_CLASS_R600:
589
		bb << VTX_WORD2_R6()
590
				.CONST_BUF_NO_STRIDE(bc.const_buf_no_stride)
591
				.ENDIAN_SWAP(bc.endian_swap)
592
				.MEGA_FETCH(bc.mega_fetch)
593
				.OFFSET(bc.offset[0]);
594
		break;
595
	case HW_CLASS_R700:
596
		bb << VTX_WORD2_R7()
597
				.ALT_CONST(bc.alt_const)
598
				.CONST_BUF_NO_STRIDE(bc.const_buf_no_stride)
599
				.ENDIAN_SWAP(bc.endian_swap)
600
				.MEGA_FETCH(bc.mega_fetch)
601
				.OFFSET(bc.offset[0]);
602
		break;
603
	case HW_CLASS_EVERGREEN:
604
		bb << VTX_WORD2_EG()
605
				.ALT_CONST(bc.alt_const)
606
				.BUFFER_INDEX_MODE(bc.resource_index_mode)
607
				.CONST_BUF_NO_STRIDE(bc.const_buf_no_stride)
608
				.ENDIAN_SWAP(bc.endian_swap)
609
				.MEGA_FETCH(bc.mega_fetch)
610
				.OFFSET(bc.offset[0]);
611
		break;
612
	case HW_CLASS_CAYMAN:
613
		bb << VTX_WORD2_CM()
614
				.ALT_CONST(bc.alt_const)
615
				.BUFFER_INDEX_MODE(bc.resource_index_mode)
616
				.CONST_BUF_NO_STRIDE(bc.const_buf_no_stride)
617
				.ENDIAN_SWAP(bc.endian_swap)
618
				.OFFSET(bc.offset[0]);
619
		break;
620
	default:
621
		assert(!"unknown hw class");
622
		return -1;
623
	}
624
 
625
	bb << 0;
626
	return 0;
627
}
628
 
629
}