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
static const char* chans = "xyzw01?_";
34
 
35
static const char* vec_bs[] = {
36
		"VEC_012", "VEC_021", "VEC_120", "VEC_102", "VEC_201", "VEC_210"
37
};
38
 
39
static const char* scl_bs[] = {
40
		"SCL_210", "SCL_122", "SCL_212", "SCL_221"
41
};
42
 
43
 
44
bool bc_dump::visit(cf_node& n, bool enter) {
45
	if (enter) {
46
 
47
		id = n.bc.id << 1;
48
 
49
		if ((n.bc.op_ptr->flags & CF_ALU) && n.bc.is_alu_extended()) {
50
			dump_dw(id, 2);
51
			id += 2;
52
			sblog << "\n";
53
		}
54
 
55
		dump_dw(id, 2);
56
		dump(n);
57
 
58
		if (n.bc.op_ptr->flags & CF_CLAUSE) {
59
			id = n.bc.addr << 1;
60
			new_group = 1;
61
		}
62
	}
63
	return true;
64
}
65
 
66
bool bc_dump::visit(alu_node& n, bool enter) {
67
	if (enter) {
68
		sblog << " ";
69
		dump_dw(id, 2);
70
 
71
		if (new_group) {
72
			sblog.print_w(++group_index, 5);
73
			sblog << " ";
74
		} else
75
			sblog << "      ";
76
 
77
		dump(n);
78
		id += 2;
79
 
80
		new_group = n.bc.last;
81
	} else {
82
		if (n.bc.last) {
83
			alu_group_node *g =
84
					static_cast(n.get_alu_group_node());
85
			assert(g);
86
			for (unsigned k = 0; k < g->literals.size(); ++k) {
87
				sblog << " ";
88
				dump_dw(id, 1);
89
				id += 1;
90
				sblog << "\n";
91
			}
92
 
93
			id = (id + 1) & ~1u;
94
		}
95
	}
96
 
97
	return false;
98
}
99
 
100
bool bc_dump::visit(fetch_node& n, bool enter) {
101
	if (enter) {
102
		sblog << " ";
103
		dump_dw(id, 3);
104
		dump(n);
105
		id += 4;
106
	}
107
	return false;
108
}
109
 
110
static void fill_to(sb_ostringstream &s, int pos) {
111
	int l = s.str().length();
112
	if (l < pos)
113
		s << std::string(pos-l, ' ');
114
}
115
 
116
void bc_dump::dump(cf_node& n) {
117
	sb_ostringstream s;
118
	s << n.bc.op_ptr->name;
119
 
120
	if (n.bc.op_ptr->flags & CF_EXP) {
121
		static const char *exp_type[] = {"PIXEL", "POS  ", "PARAM"};
122
 
123
		fill_to(s, 18);
124
		s << " " << exp_type[n.bc.type] << " ";
125
 
126
		if (n.bc.burst_count) {
127
			sb_ostringstream s2;
128
			s2 << n.bc.array_base << "-" << n.bc.array_base + n.bc.burst_count;
129
			s.print_wl(s2.str(), 5);
130
			s << " R" << n.bc.rw_gpr << "-" <<
131
					n.bc.rw_gpr + n.bc.burst_count << ".";
132
		} else {
133
			s.print_wl(n.bc.array_base, 5);
134
			s << " R" << n.bc.rw_gpr << ".";
135
		}
136
 
137
		for (int k = 0; k < 4; ++k)
138
			s << chans[n.bc.sel[k]];
139
 
140
	} else if (n.bc.op_ptr->flags & (CF_STRM | CF_RAT)) {
141
		static const char *exp_type[] = {"WRITE", "WRITE_IND", "WRITE_ACK",
142
				"WRITE_IND_ACK"};
143
		fill_to(s, 18);
144
		s << " " << exp_type[n.bc.type] << " ";
145
		s.print_wl(n.bc.array_base, 5);
146
		s << " R" << n.bc.rw_gpr << ".";
147
		for (int k = 0; k < 4; ++k)
148
			s << ((n.bc.comp_mask & (1 << k)) ? chans[k] : '_');
149
 
150
		if ((n.bc.op_ptr->flags & CF_RAT) && (n.bc.type & 1)) {
151
			s << ", @R" << n.bc.index_gpr << ".xyz";
152
		}
153
 
154
		s << "  ES:" << n.bc.elem_size;
155
 
156
	} else {
157
 
158
		if (n.bc.op_ptr->flags & CF_CLAUSE) {
159
			s << " " << n.bc.count+1;
160
		}
161
 
162
		s << " @" << (n.bc.addr << 1);
163
 
164
		if (n.bc.op_ptr->flags & CF_ALU) {
165
 
166
			for (int k = 0; k < 4; ++k) {
167
				bc_kcache &kc = n.bc.kc[k];
168
				if (kc.mode) {
169
					s << " KC" << k << "[CB" << kc.bank << ":" <<
170
							(kc.addr << 4) << "-" <<
171
							(((kc.addr + kc.mode) << 4) - 1) << "]";
172
				}
173
			}
174
		}
175
 
176
		if (n.bc.cond)
177
			s << " CND:" << n.bc.pop_count;
178
 
179
		if (n.bc.pop_count)
180
			s << " POP:" << n.bc.pop_count;
181
	}
182
 
183
	if (!n.bc.barrier)
184
		s << "  NO_BARRIER";
185
 
186
	if (n.bc.valid_pixel_mode)
187
		s << "  VPM";
188
 
189
	if (n.bc.whole_quad_mode)
190
		s << "  WQM";
191
 
192
	if (n.bc.end_of_program)
193
		s << "  EOP";
194
 
195
	sblog << s.str() << "\n";
196
}
197
 
198
 
199
static void print_sel(sb_ostream &s, int sel, int rel, int index_mode,
200
                      int need_brackets) {
201
	if (rel && index_mode >= 5 && sel < 128)
202
		s << "G";
203
	if (rel || need_brackets) {
204
		s << "[";
205
	}
206
	s << sel;
207
	if (rel) {
208
		if (index_mode == 0 || index_mode == 6)
209
			s << "+AR";
210
		else if (index_mode == 4)
211
			s << "+AL";
212
	}
213
	if (rel || need_brackets) {
214
		s << "]";
215
	}
216
}
217
 
218
static void print_dst(sb_ostream &s, bc_alu &alu)
219
{
220
	unsigned sel = alu.dst_gpr;
221
	char reg_char = 'R';
222
	if (sel >= 128 - 4) { // clause temporary gpr
223
		sel -= 128 - 4;
224
		reg_char = 'T';
225
	}
226
 
227
	if (alu.write_mask || alu.op_ptr->src_count == 3) {
228
		s << reg_char;
229
		print_sel(s, sel, alu.dst_rel, alu.index_mode, 0);
230
	} else {
231
		s << "__";
232
	}
233
	s << ".";
234
	s << chans[alu.dst_chan];
235
}
236
 
237
static void print_src(sb_ostream &s, bc_alu &alu, unsigned idx)
238
{
239
	bc_alu_src *src = &alu.src[idx];
240
	unsigned sel = src->sel, need_sel = 1, need_chan = 1, need_brackets = 0;
241
 
242
	if (src->neg)
243
		s <<"-";
244
	if (src->abs)
245
		s <<"|";
246
 
247
	if (sel < 128 - 4) {
248
		s << "R";
249
	} else if (sel < 128) {
250
		s << "T";
251
		sel -= 128 - 4;
252
	} else if (sel < 160) {
253
		s << "KC0";
254
		need_brackets = 1;
255
		sel -= 128;
256
	} else if (sel < 192) {
257
		s << "KC1";
258
		need_brackets = 1;
259
		sel -= 160;
260
	} else if (sel >= 448) {
261
		s << "Param";
262
		sel -= 448;
263
	} else if (sel >= 288) {
264
		s << "KC3";
265
		need_brackets = 1;
266
		sel -= 288;
267
	} else if (sel >= 256) {
268
		s << "KC2";
269
		need_brackets = 1;
270
		sel -= 256;
271
	} else {
272
		need_sel = 0;
273
		need_chan = 0;
274
		switch (sel) {
275
		case ALU_SRC_PS:
276
			s << "PS";
277
			break;
278
		case ALU_SRC_PV:
279
			s << "PV";
280
			need_chan = 1;
281
			break;
282
		case ALU_SRC_LITERAL:
283
			s << "[0x";
284
			s.print_zw_hex(src->value.u, 8);
285
			s << " " << src->value.f << "]";
286
			need_chan = 1;
287
			break;
288
		case ALU_SRC_0_5:
289
			s << "0.5";
290
			break;
291
		case ALU_SRC_M_1_INT:
292
			s << "-1";
293
			break;
294
		case ALU_SRC_1_INT:
295
			s << "1";
296
			break;
297
		case ALU_SRC_1:
298
			s << "1.0";
299
			break;
300
		case ALU_SRC_0:
301
			s << "0";
302
			break;
303
		default:
304
			s << "??IMM_" <<  sel;
305
			break;
306
		}
307
	}
308
 
309
	if (need_sel)
310
		print_sel(s, sel, src->rel, alu.index_mode, need_brackets);
311
 
312
	if (need_chan) {
313
		s << "." << chans[src->chan];
314
	}
315
 
316
	if (src->abs)
317
		s << "|";
318
}
319
void bc_dump::dump(alu_node& n) {
320
	sb_ostringstream s;
321
	static const char *omod_str[] = {"","*2","*4","/2"};
322
	static const char *slots = "xyzwt";
323
 
324
	s << (n.bc.update_exec_mask ? "M" : " ");
325
	s << (n.bc.update_pred ? "P" : " ");
326
	s << " ";
327
	s << (n.bc.pred_sel>=2 ? (n.bc.pred_sel == 2 ? "0" : "1") : " ");
328
	s << " ";
329
 
330
	s << slots[n.bc.slot] << ": ";
331
 
332
	s << n.bc.op_ptr->name << omod_str[n.bc.omod] << (n.bc.clamp ? "_sat" : "");
333
	fill_to(s, 26);
334
	s << " ";
335
 
336
	print_dst(s, n.bc);
337
	for (int k = 0; k < n.bc.op_ptr->src_count; ++k) {
338
		s << (k ? ", " : ",  ");
339
		print_src(s, n.bc, k);
340
	}
341
 
342
	if (n.bc.bank_swizzle) {
343
		fill_to(s, 55);
344
		if (n.bc.slot == SLOT_TRANS)
345
			s << "  " << scl_bs[n.bc.bank_swizzle];
346
		else
347
			s << "  " << vec_bs[n.bc.bank_swizzle];
348
	}
349
 
350
	sblog << s.str() << "\n";
351
}
352
 
353
int bc_dump::init() {
354
	sb_ostringstream s;
355
	s << "===== SHADER #" << sh.id;
356
 
357
	if (sh.optimized)
358
		s << " OPT";
359
 
360
	s << " ";
361
 
362
	std::string target = std::string(" ") +
363
			sh.get_full_target_name() + " =====";
364
 
365
	while (s.str().length() + target.length() < 80)
366
		s << "=";
367
 
368
	s << target;
369
 
370
	sblog << "\n" << s.str() << "\n";
371
 
372
	s.clear();
373
 
374
	if (bc_data) {
375
		s << "===== " << ndw << " dw ===== " << sh.ngpr
376
				<< " gprs ===== " << sh.nstack << " stack ";
377
	}
378
 
379
	while (s.str().length() < 80)
380
		s << "=";
381
 
382
	sblog << s.str() << "\n";
383
 
384
	return 0;
385
}
386
 
387
int bc_dump::done() {
388
	sb_ostringstream s;
389
	s << "===== SHADER_END ";
390
 
391
	while (s.str().length() < 80)
392
		s << "=";
393
 
394
	sblog << s.str() << "\n\n";
395
 
396
	return 0;
397
}
398
 
399
bc_dump::bc_dump(shader& s, bytecode* bc)  :
400
	vpass(s), bc_data(), ndw(), id(),
401
	new_group(), group_index() {
402
 
403
	if (bc) {
404
		bc_data = bc->data();
405
		ndw = bc->ndw();
406
	}
407
}
408
 
409
void bc_dump::dump(fetch_node& n) {
410
	sb_ostringstream s;
411
	static const char * fetch_type[] = {"VERTEX", "INSTANCE", ""};
412
 
413
	s << n.bc.op_ptr->name;
414
	fill_to(s, 20);
415
 
416
	s << "R";
417
	print_sel(s, n.bc.dst_gpr, n.bc.dst_rel, INDEX_LOOP, 0);
418
	s << ".";
419
	for (int k = 0; k < 4; ++k)
420
		s << chans[n.bc.dst_sel[k]];
421
	s << ", ";
422
 
423
	s << "R";
424
	print_sel(s, n.bc.src_gpr, n.bc.src_rel, INDEX_LOOP, 0);
425
	s << ".";
426
 
427
	unsigned vtx = n.bc.op_ptr->flags & FF_VTX;
428
	unsigned num_src_comp = vtx ? ctx.is_cayman() ? 2 : 1 : 4;
429
 
430
	for (unsigned k = 0; k < num_src_comp; ++k)
431
		s << chans[n.bc.src_sel[k]];
432
 
433
	if (vtx && n.bc.offset[0]) {
434
		s << " + " << n.bc.offset[0] << "b ";
435
	}
436
 
437
	s << ",   RID:" << n.bc.resource_id;
438
 
439
	if (vtx) {
440
		s << "  " << fetch_type[n.bc.fetch_type];
441
		if (!ctx.is_cayman() && n.bc.mega_fetch_count)
442
			s << " MFC:" << n.bc.mega_fetch_count;
443
		if (n.bc.fetch_whole_quad)
444
			s << " FWQ";
445
		s << " UCF:" << n.bc.use_const_fields
446
				<< " FMT(DTA:" << n.bc.data_format
447
				<< " NUM:" << n.bc.num_format_all
448
				<< " COMP:" << n.bc.format_comp_all
449
				<< " MODE:" << n.bc.srf_mode_all << ")";
450
	} else {
451
		s << ", SID:" << n.bc.sampler_id;
452
		if (n.bc.lod_bias)
453
			s << " LB:" << n.bc.lod_bias;
454
		s << " CT:";
455
		for (unsigned k = 0; k < 4; ++k)
456
			s << (n.bc.coord_type[k] ? "N" : "U");
457
		for (unsigned k = 0; k < 3; ++k)
458
			if (n.bc.offset[k])
459
				s << " O" << chans[k] << ":" << n.bc.offset[k];
460
	}
461
 
462
	sblog << s.str() << "\n";
463
}
464
 
465
void bc_dump::dump_dw(unsigned dw_id, unsigned count) {
466
	if (!bc_data)
467
		return;
468
 
469
	assert(dw_id + count <= ndw);
470
 
471
	sblog.print_zw(dw_id, 4);
472
	sblog << "  ";
473
	while (count--) {
474
		sblog.print_zw_hex(bc_data[dw_id++], 8);
475
		sblog << " ";
476
	}
477
}
478
 
479
} // namespace r600_sb