Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4304 Serge 1
/*
2
 * Copyright © 2007-2011 Intel Corporation
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
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 * SOFTWARE.
22
 *
23
 * Authors:
24
 *    Eric Anholt 
25
 *    Chris Wilson 
26
 *
27
 */
28
 
29
#ifdef HAVE_CONFIG_H
30
#include "config.h"
31
#endif
32
 
33
#include 
34
 
35
#include "sna.h"
36
#include "sna_reg.h"
37
 
38
#include "gen3_render.h"
39
 
40
#include "kgem_debug.h"
41
 
42
enum type {
43
	T_FLOAT32,
44
	T_FLOAT16,
45
};
46
 
47
static struct state {
48
	struct vertex_buffer {
49
		int handle;
50
		void *base;
51
		const char *ptr;
52
		int pitch;
53
 
54
		struct kgem_bo *current;
55
	} vb;
56
	struct vertex_elements {
57
		int offset;
58
		bool valid;
59
		enum type type;
60
		int size;
61
		uint8_t swizzle[4];
62
	} ve[33];
63
	int num_ve;
64
} state;
65
 
66
static float int_as_float(int i)
67
{
68
	union {
69
		float f;
70
		int i;
71
	} x;
72
	x.i = i;
73
	return x.f;
74
}
75
 
76
static void gen3_update_vertex_buffer_addr(struct kgem *kgem,
77
					   uint32_t offset)
78
{
79
	uint32_t handle;
80
	struct kgem_bo *bo = NULL;
81
	void *base, *ptr;
82
	int i;
83
 
84
	offset *= sizeof(uint32_t);
85
 
86
	for (i = 0; i < kgem->nreloc; i++)
87
		if (kgem->reloc[i].offset == offset)
88
			break;
89
	assert(i < kgem->nreloc);
90
	handle = kgem->reloc[i].target_handle;
91
 
92
	if (handle == 0) {
93
		base = kgem->batch;
94
	} else {
95
		list_for_each_entry(bo, &kgem->next_request->buffers, request)
96
			if (bo->handle == handle)
97
				break;
98
		assert(&bo->request != &kgem->next_request->buffers);
99
		base = kgem_bo_map__debug(kgem, bo);
100
	}
101
	ptr = (char *)base + kgem->reloc[i].delta;
102
 
103
	state.vb.current = bo;
104
	state.vb.base = base;
105
	state.vb.ptr = ptr;
106
}
107
 
108
static void gen3_update_vertex_buffer_pitch(struct kgem *kgem,
109
					   uint32_t offset)
110
{
111
	state.vb.pitch = kgem->batch[offset] >> 16 & 0x3f;
112
	state.vb.pitch *= sizeof(uint32_t);
113
}
114
 
115
static void gen3_update_vertex_elements(struct kgem *kgem, uint32_t data)
116
{
117
	state.ve[1].valid = 1;
118
 
119
	switch ((data >> 6) & 7) {
120
	case 1:
121
		state.ve[1].type = T_FLOAT32;
122
		state.ve[1].size = 3;
123
		state.ve[1].swizzle[0] = 1;
124
		state.ve[1].swizzle[1] = 1;
125
		state.ve[1].swizzle[2] = 1;
126
		state.ve[1].swizzle[3] = 3;
127
		break;
128
	case 2:
129
		state.ve[1].type = T_FLOAT32;
130
		state.ve[1].size = 4;
131
		state.ve[1].swizzle[0] = 1;
132
		state.ve[1].swizzle[1] = 1;
133
		state.ve[1].swizzle[2] = 1;
134
		state.ve[1].swizzle[3] = 1;
135
		break;
136
	case 3:
137
		state.ve[1].type = T_FLOAT32;
138
		state.ve[1].size = 2;
139
		state.ve[1].swizzle[0] = 1;
140
		state.ve[1].swizzle[1] = 1;
141
		state.ve[1].swizzle[2] = 2;
142
		state.ve[1].swizzle[3] = 3;
143
		break;
144
	case 4:
145
		state.ve[1].type = T_FLOAT32;
146
		state.ve[1].size = 3;
147
		state.ve[1].swizzle[0] = 1;
148
		state.ve[1].swizzle[1] = 1;
149
		state.ve[1].swizzle[2] = 3;
150
		state.ve[1].swizzle[3] = 1;
151
		break;
152
	}
153
 
154
	state.ve[2].valid = 0;
155
	state.ve[3].valid = 0;
156
}
157
 
158
static void gen3_update_vertex_texcoords(struct kgem *kgem, uint32_t data)
159
{
160
	int id;
161
	for (id = 0; id < 8; id++) {
162
		uint32_t fmt = (data >> (id*4)) & 0xf;
163
		int width;
164
 
165
		state.ve[id+4].valid = fmt != 0xf;
166
 
167
		width = 0;
168
		switch (fmt) {
169
		case 0:
170
			state.ve[id+4].type = T_FLOAT32;
171
			width = state.ve[id+4].size = 2;
172
			break;
173
		case 1:
174
			state.ve[id+4].type = T_FLOAT32;
175
			width = state.ve[id+4].size = 3;
176
			break;
177
		case 2:
178
			state.ve[id+4].type = T_FLOAT32;
179
			width = state.ve[id+4].size = 4;
180
			break;
181
		case 3:
182
			state.ve[id+4].type = T_FLOAT32;
183
			width = state.ve[id+4].size = 1;
184
			break;
185
		case 4:
186
			state.ve[id+4].type = T_FLOAT16;
187
			width = state.ve[id+4].size = 2;
188
			break;
189
		case 5:
190
			state.ve[id+4].type = T_FLOAT16;
191
			width = state.ve[id+4].size = 4;
192
			break;
193
		}
194
 
195
		state.ve[id+4].swizzle[0] = width > 0 ? 1 : 2;
196
		state.ve[id+4].swizzle[1] = width > 1 ? 1 : 2;
197
		state.ve[id+4].swizzle[2] = width > 2 ? 1 : 2;
198
		state.ve[id+4].swizzle[3] = width > 3 ? 1 : 2;
199
	}
200
}
201
 
202
static void gen3_update_vertex_elements_offsets(struct kgem *kgem)
203
{
204
	int i, offset;
205
 
206
	for (i = offset = 0; i < ARRAY_SIZE(state.ve); i++) {
207
		if (!state.ve[i].valid)
208
			continue;
209
 
210
		state.ve[i].offset = offset;
211
		offset += 4 * state.ve[i].size;
212
		state.num_ve = i;
213
	}
214
}
215
 
216
static void vertices_float32_out(const struct vertex_elements *ve, const float *f, int max)
217
{
218
	int c;
219
 
220
	ErrorF("(");
221
	for (c = 0; c < max; c++) {
222
		switch (ve->swizzle[c]) {
223
		case 0: ErrorF("#"); break;
224
		case 1: ErrorF("%f", f[c]); break;
225
		case 2: ErrorF("0.0"); break;
226
		case 3: ErrorF("1.0"); break;
227
		case 4: ErrorF("0x1"); break;
228
		case 5: break;
229
		default: ErrorF("?");
230
		}
231
		if (c < max-1)
232
			ErrorF(", ");
233
	}
234
	ErrorF(")");
235
}
236
 
237
static void ve_out(const struct vertex_elements *ve, const void *ptr)
238
{
239
	switch (ve->type) {
240
	case T_FLOAT32:
241
		vertices_float32_out(ve, ptr, ve->size);
242
		break;
243
	case T_FLOAT16:
244
		//vertices_float16_out(ve, ptr, ve->size);
245
		break;
246
	}
247
}
248
 
249
static void indirect_vertex_out(struct kgem *kgem, uint32_t v)
250
{
251
	const struct vertex_buffer *vb = &state.vb;
252
	int i = 1;
253
 
254
	do {
255
		const struct vertex_elements *ve = &state.ve[i];
256
		const void *ptr = vb->ptr + v * vb->pitch + ve->offset;
257
 
258
		if (!ve->valid)
259
			continue;
260
 
261
		ve_out(ve, ptr);
262
 
263
		while (++i <= state.num_ve && !state.ve[i].valid)
264
			;
265
 
266
		if (i <= state.num_ve)
267
			ErrorF(", ");
268
	} while (i <= state.num_ve);
269
}
270
 
271
static int inline_vertex_out(struct kgem *kgem, void *base)
272
{
273
	const struct vertex_buffer *vb = &state.vb;
274
	int i = 1;
275
 
276
	do {
277
		const struct vertex_elements *ve = &state.ve[i];
278
		const void *ptr = (char *)base + ve->offset;
279
 
280
		if (!ve->valid)
281
			continue;
282
 
283
		ve_out(ve, ptr);
284
 
285
		while (++i <= state.num_ve && !state.ve[i].valid)
286
			;
287
 
288
		if (i <= state.num_ve)
289
			ErrorF(", ");
290
	} while (i <= state.num_ve);
291
 
292
	return vb->pitch;
293
}
294
 
295
static int
296
gen3_decode_3d_1c(struct kgem *kgem, uint32_t offset)
297
{
298
	uint32_t *data = kgem->batch + offset;
299
	uint32_t opcode;
300
 
301
	opcode = (data[0] & 0x00f80000) >> 19;
302
 
303
	switch (opcode) {
304
	case 0x11:
305
		kgem_debug_print(data, offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE\n");
306
		return 1;
307
	case 0x10:
308
		kgem_debug_print(data, offset, 0, "3DSTATE_SCISSOR_ENABLE %s\n",
309
			  data[0]&1?"enabled":"disabled");
310
		return 1;
311
	case 0x01:
312
		kgem_debug_print(data, offset, 0, "3DSTATE_MAP_COORD_SET_I830\n");
313
		return 1;
314
	case 0x0a:
315
		kgem_debug_print(data, offset, 0, "3DSTATE_MAP_CUBE_I830\n");
316
		return 1;
317
	case 0x05:
318
		kgem_debug_print(data, offset, 0, "3DSTATE_MAP_TEX_STREAM_I830\n");
319
		return 1;
320
	}
321
 
322
	kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1c opcode = 0x%x\n",
323
		  opcode);
324
	assert(0);
325
	return 1;
326
}
327
 
328
/** Sets the string dstname to describe the destination of the PS instruction */
329
static void
330
gen3_get_instruction_dst(uint32_t *data, int i, char *dstname, int do_mask)
331
{
332
    uint32_t a0 = data[i];
333
    int dst_nr = (a0 >> 14) & 0xf;
334
    char dstmask[8];
335
    const char *sat;
336
 
337
    if (do_mask) {
338
	if (((a0 >> 10) & 0xf) == 0xf) {
339
	    dstmask[0] = 0;
340
	} else {
341
	    int dstmask_index = 0;
342
 
343
	    dstmask[dstmask_index++] = '.';
344
	    if (a0 & (1 << 10))
345
		dstmask[dstmask_index++] = 'x';
346
	    if (a0 & (1 << 11))
347
		dstmask[dstmask_index++] = 'y';
348
	    if (a0 & (1 << 12))
349
		dstmask[dstmask_index++] = 'z';
350
	    if (a0 & (1 << 13))
351
		dstmask[dstmask_index++] = 'w';
352
	    dstmask[dstmask_index++] = 0;
353
	}
354
 
355
	if (a0 & (1 << 22))
356
	    sat = ".sat";
357
	else
358
	    sat = "";
359
    } else {
360
	dstmask[0] = 0;
361
	sat = "";
362
    }
363
 
364
    switch ((a0 >> 19) & 0x7) {
365
    case 0:
366
	    assert(dst_nr <= 15);
367
	sprintf(dstname, "R%d%s%s", dst_nr, dstmask, sat);
368
	break;
369
    case 4:
370
	assert(dst_nr == 0);
371
	sprintf(dstname, "oC%s%s", dstmask, sat);
372
	break;
373
    case 5:
374
	assert(dst_nr == 0);
375
	sprintf(dstname, "oD%s%s",  dstmask, sat);
376
	break;
377
    case 6:
378
	assert(dst_nr <= 3);
379
	sprintf(dstname, "U%d%s%s", dst_nr, dstmask, sat);
380
	break;
381
    default:
382
	sprintf(dstname, "RESERVED");
383
	break;
384
    }
385
}
386
 
387
static const char *
388
gen3_get_channel_swizzle(uint32_t select)
389
{
390
    switch (select & 0x7) {
391
    case 0:
392
	return (select & 8) ? "-x" : "x";
393
    case 1:
394
	return (select & 8) ? "-y" : "y";
395
    case 2:
396
	return (select & 8) ? "-z" : "z";
397
    case 3:
398
	return (select & 8) ? "-w" : "w";
399
    case 4:
400
	return (select & 8) ? "-0" : "0";
401
    case 5:
402
	return (select & 8) ? "-1" : "1";
403
    default:
404
	return (select & 8) ? "-bad" : "bad";
405
    }
406
}
407
 
408
static void
409
gen3_get_instruction_src_name(uint32_t src_type, uint32_t src_nr, char *name)
410
{
411
	switch (src_type) {
412
	case 0:
413
		sprintf(name, "R%d", src_nr);
414
		assert(src_nr <= 15);
415
		break;
416
	case 1:
417
		if (src_nr < 8)
418
			sprintf(name, "T%d", src_nr);
419
		else if (src_nr == 8)
420
			sprintf(name, "DIFFUSE");
421
		else if (src_nr == 9)
422
			sprintf(name, "SPECULAR");
423
		else if (src_nr == 10)
424
			sprintf(name, "FOG");
425
		else {
426
			assert(0);
427
			sprintf(name, "RESERVED");
428
		}
429
		break;
430
	case 2:
431
		sprintf(name, "C%d", src_nr);
432
		assert(src_nr <= 31);
433
		break;
434
	case 4:
435
		sprintf(name, "oC");
436
		assert(src_nr == 0);
437
		break;
438
	case 5:
439
		sprintf(name, "oD");
440
		assert(src_nr == 0);
441
		break;
442
	case 6:
443
		sprintf(name, "U%d", src_nr);
444
		assert(src_nr <= 3);
445
		break;
446
	default:
447
		sprintf(name, "RESERVED");
448
		assert(0);
449
		break;
450
	}
451
}
452
 
453
static void
454
gen3_get_instruction_src0(uint32_t *data, int i, char *srcname)
455
{
456
    uint32_t a0 = data[i];
457
    uint32_t a1 = data[i + 1];
458
    int src_nr = (a0 >> 2) & 0x1f;
459
    const char *swizzle_x = gen3_get_channel_swizzle((a1 >> 28) & 0xf);
460
    const char *swizzle_y = gen3_get_channel_swizzle((a1 >> 24) & 0xf);
461
    const char *swizzle_z = gen3_get_channel_swizzle((a1 >> 20) & 0xf);
462
    const char *swizzle_w = gen3_get_channel_swizzle((a1 >> 16) & 0xf);
463
    char swizzle[100];
464
 
465
    gen3_get_instruction_src_name((a0 >> 7) & 0x7, src_nr, srcname);
466
    sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
467
    if (strcmp(swizzle, ".xyzw") != 0)
468
	strcat(srcname, swizzle);
469
}
470
 
471
static void
472
gen3_get_instruction_src1(uint32_t *data, int i, char *srcname)
473
{
474
    uint32_t a1 = data[i + 1];
475
    uint32_t a2 = data[i + 2];
476
    int src_nr = (a1 >> 8) & 0x1f;
477
    const char *swizzle_x = gen3_get_channel_swizzle((a1 >> 4) & 0xf);
478
    const char *swizzle_y = gen3_get_channel_swizzle((a1 >> 0) & 0xf);
479
    const char *swizzle_z = gen3_get_channel_swizzle((a2 >> 28) & 0xf);
480
    const char *swizzle_w = gen3_get_channel_swizzle((a2 >> 24) & 0xf);
481
    char swizzle[100];
482
 
483
    gen3_get_instruction_src_name((a1 >> 13) & 0x7, src_nr, srcname);
484
    sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
485
    if (strcmp(swizzle, ".xyzw") != 0)
486
	strcat(srcname, swizzle);
487
}
488
 
489
static void
490
gen3_get_instruction_src2(uint32_t *data, int i, char *srcname)
491
{
492
    uint32_t a2 = data[i + 2];
493
    int src_nr = (a2 >> 16) & 0x1f;
494
    const char *swizzle_x = gen3_get_channel_swizzle((a2 >> 12) & 0xf);
495
    const char *swizzle_y = gen3_get_channel_swizzle((a2 >> 8) & 0xf);
496
    const char *swizzle_z = gen3_get_channel_swizzle((a2 >> 4) & 0xf);
497
    const char *swizzle_w = gen3_get_channel_swizzle((a2 >> 0) & 0xf);
498
    char swizzle[100];
499
 
500
    gen3_get_instruction_src_name((a2 >> 21) & 0x7, src_nr, srcname);
501
    sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
502
    if (strcmp(swizzle, ".xyzw") != 0)
503
	strcat(srcname, swizzle);
504
}
505
 
506
static void
507
gen3_get_instruction_addr(uint32_t src_type, uint32_t src_nr, char *name)
508
{
509
	switch (src_type) {
510
	case 0:
511
		sprintf(name, "R%d", src_nr);
512
		assert(src_nr <= 15);
513
		break;
514
	case 1:
515
		if (src_nr < 8)
516
			sprintf(name, "T%d", src_nr);
517
		else if (src_nr == 8)
518
			sprintf(name, "DIFFUSE");
519
		else if (src_nr == 9)
520
			sprintf(name, "SPECULAR");
521
		else if (src_nr == 10)
522
			sprintf(name, "FOG");
523
		else {
524
			assert(0);
525
			sprintf(name, "RESERVED");
526
		}
527
		break;
528
	case 4:
529
		sprintf(name, "oC");
530
		assert(src_nr == 0);
531
		break;
532
	case 5:
533
		sprintf(name, "oD");
534
		assert(src_nr == 0);
535
		break;
536
	default:
537
		assert(0);
538
		sprintf(name, "RESERVED");
539
		break;
540
	}
541
}
542
 
543
static void
544
gen3_decode_alu1(uint32_t *data, uint32_t offset,
545
		 int i, char *instr_prefix, const char *op_name)
546
{
547
    char dst[100], src0[100];
548
 
549
    gen3_get_instruction_dst(data, i, dst, 1);
550
    gen3_get_instruction_src0(data, i, src0);
551
 
552
    kgem_debug_print(data, offset, i++, "%s: %s %s, %s\n", instr_prefix,
553
	      op_name, dst, src0);
554
    kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
555
    kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
556
}
557
 
558
static void
559
gen3_decode_alu2(uint32_t *data, uint32_t offset,
560
		 int i, char *instr_prefix, const char *op_name)
561
{
562
    char dst[100], src0[100], src1[100];
563
 
564
    gen3_get_instruction_dst(data, i, dst, 1);
565
    gen3_get_instruction_src0(data, i, src0);
566
    gen3_get_instruction_src1(data, i, src1);
567
 
568
    kgem_debug_print(data, offset, i++, "%s: %s %s, %s, %s\n", instr_prefix,
569
	      op_name, dst, src0, src1);
570
    kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
571
    kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
572
}
573
 
574
static void
575
gen3_decode_alu3(uint32_t *data, uint32_t offset,
576
		 int i, char *instr_prefix, const char *op_name)
577
{
578
    char dst[100], src0[100], src1[100], src2[100];
579
 
580
    gen3_get_instruction_dst(data, i, dst, 1);
581
    gen3_get_instruction_src0(data, i, src0);
582
    gen3_get_instruction_src1(data, i, src1);
583
    gen3_get_instruction_src2(data, i, src2);
584
 
585
    kgem_debug_print(data, offset, i++, "%s: %s %s, %s, %s, %s\n", instr_prefix,
586
	      op_name, dst, src0, src1, src2);
587
    kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
588
    kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
589
}
590
 
591
static void
592
gen3_decode_tex(uint32_t *data, uint32_t offset, int i, char *instr_prefix,
593
		const char *tex_name)
594
{
595
    uint32_t t0 = data[i];
596
    uint32_t t1 = data[i + 1];
597
    char dst_name[100];
598
    char addr_name[100];
599
    int sampler_nr;
600
 
601
    gen3_get_instruction_dst(data, i, dst_name, 0);
602
    gen3_get_instruction_addr((t1 >> 24) & 0x7,
603
			      (t1 >> 17) & 0xf,
604
			      addr_name);
605
    sampler_nr = t0 & 0xf;
606
 
607
    kgem_debug_print(data, offset, i++, "%s: %s %s, S%d, %s\n", instr_prefix,
608
	      tex_name, dst_name, sampler_nr, addr_name);
609
    kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
610
    kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
611
}
612
 
613
static void
614
gen3_decode_dcl(uint32_t *data, uint32_t offset, int i, char *instr_prefix)
615
{
616
	uint32_t d0 = data[i];
617
	const char *sampletype;
618
	int dcl_nr = (d0 >> 14) & 0xf;
619
	const char *dcl_x = d0 & (1 << 10) ? "x" : "";
620
	const char *dcl_y = d0 & (1 << 11) ? "y" : "";
621
	const char *dcl_z = d0 & (1 << 12) ? "z" : "";
622
	const char *dcl_w = d0 & (1 << 13) ? "w" : "";
623
	char dcl_mask[10];
624
 
625
	switch ((d0 >> 19) & 0x3) {
626
	case 1:
627
		sprintf(dcl_mask, ".%s%s%s%s", dcl_x, dcl_y, dcl_z, dcl_w);
628
		assert (strcmp(dcl_mask, "."));
629
 
630
		assert(dcl_nr <= 10);
631
		if (dcl_nr < 8) {
632
			if (strcmp(dcl_mask, ".x") != 0 &&
633
			    strcmp(dcl_mask, ".xy") != 0 &&
634
			    strcmp(dcl_mask, ".xz") != 0 &&
635
			    strcmp(dcl_mask, ".w") != 0 &&
636
			    strcmp(dcl_mask, ".xyzw") != 0) {
637
				assert(0);
638
			}
639
			kgem_debug_print(data, offset, i++, "%s: DCL T%d%s\n", instr_prefix,
640
				  dcl_nr, dcl_mask);
641
		} else {
642
			if (strcmp(dcl_mask, ".xz") == 0)
643
				assert(0);
644
			else if (strcmp(dcl_mask, ".xw") == 0)
645
				assert(0);
646
			else if (strcmp(dcl_mask, ".xzw") == 0)
647
				assert(0);
648
 
649
			if (dcl_nr == 8) {
650
				kgem_debug_print(data, offset, i++, "%s: DCL DIFFUSE%s\n", instr_prefix,
651
					  dcl_mask);
652
			} else if (dcl_nr == 9) {
653
				kgem_debug_print(data, offset, i++, "%s: DCL SPECULAR%s\n", instr_prefix,
654
					  dcl_mask);
655
			} else if (dcl_nr == 10) {
656
				kgem_debug_print(data, offset, i++, "%s: DCL FOG%s\n", instr_prefix,
657
					  dcl_mask);
658
			}
659
		}
660
		kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
661
		kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
662
		break;
663
	case 3:
664
		switch ((d0 >> 22) & 0x3) {
665
		case 0:
666
			sampletype = "2D";
667
			break;
668
		case 1:
669
			sampletype = "CUBE";
670
			break;
671
		case 2:
672
			sampletype = "3D";
673
			break;
674
		default:
675
			sampletype = "RESERVED";
676
			break;
677
		}
678
		assert(dcl_nr <= 15);
679
		kgem_debug_print(data, offset, i++, "%s: DCL S%d %s\n", instr_prefix,
680
			  dcl_nr, sampletype);
681
		kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
682
		kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
683
		break;
684
	default:
685
		kgem_debug_print(data, offset, i++, "%s: DCL RESERVED%d\n", instr_prefix, dcl_nr);
686
		kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
687
		kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
688
	}
689
}
690
 
691
static void
692
gen3_decode_instruction(uint32_t *data, uint32_t offset,
693
			int i, char *instr_prefix)
694
{
695
    switch ((data[i] >> 24) & 0x1f) {
696
    case 0x0:
697
	kgem_debug_print(data, offset, i++, "%s: NOP\n", instr_prefix);
698
	kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
699
	kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
700
	break;
701
    case 0x01:
702
	gen3_decode_alu2(data, offset, i, instr_prefix, "ADD");
703
	break;
704
    case 0x02:
705
	gen3_decode_alu1(data, offset, i, instr_prefix, "MOV");
706
	break;
707
    case 0x03:
708
	gen3_decode_alu2(data, offset, i, instr_prefix, "MUL");
709
	break;
710
    case 0x04:
711
	gen3_decode_alu3(data, offset, i, instr_prefix, "MAD");
712
	break;
713
    case 0x05:
714
	gen3_decode_alu3(data, offset, i, instr_prefix, "DP2ADD");
715
	break;
716
    case 0x06:
717
	gen3_decode_alu2(data, offset, i, instr_prefix, "DP3");
718
	break;
719
    case 0x07:
720
	gen3_decode_alu2(data, offset, i, instr_prefix, "DP4");
721
	break;
722
    case 0x08:
723
	gen3_decode_alu1(data, offset, i, instr_prefix, "FRC");
724
	break;
725
    case 0x09:
726
	gen3_decode_alu1(data, offset, i, instr_prefix, "RCP");
727
	break;
728
    case 0x0a:
729
	gen3_decode_alu1(data, offset, i, instr_prefix, "RSQ");
730
	break;
731
    case 0x0b:
732
	gen3_decode_alu1(data, offset, i, instr_prefix, "EXP");
733
	break;
734
    case 0x0c:
735
	gen3_decode_alu1(data, offset, i, instr_prefix, "LOG");
736
	break;
737
    case 0x0d:
738
	gen3_decode_alu2(data, offset, i, instr_prefix, "CMP");
739
	break;
740
    case 0x0e:
741
	gen3_decode_alu2(data, offset, i, instr_prefix, "MIN");
742
	break;
743
    case 0x0f:
744
	gen3_decode_alu2(data, offset, i, instr_prefix, "MAX");
745
	break;
746
    case 0x10:
747
	gen3_decode_alu1(data, offset, i, instr_prefix, "FLR");
748
	break;
749
    case 0x11:
750
	gen3_decode_alu1(data, offset, i, instr_prefix, "MOD");
751
	break;
752
    case 0x12:
753
	gen3_decode_alu1(data, offset, i, instr_prefix, "TRC");
754
	break;
755
    case 0x13:
756
	gen3_decode_alu2(data, offset, i, instr_prefix, "SGE");
757
	break;
758
    case 0x14:
759
	gen3_decode_alu2(data, offset, i, instr_prefix, "SLT");
760
	break;
761
    case 0x15:
762
	gen3_decode_tex(data, offset, i, instr_prefix, "TEXLD");
763
	break;
764
    case 0x16:
765
	gen3_decode_tex(data, offset, i, instr_prefix, "TEXLDP");
766
	break;
767
    case 0x17:
768
	gen3_decode_tex(data, offset, i, instr_prefix, "TEXLDB");
769
	break;
770
    case 0x19:
771
	gen3_decode_dcl(data, offset, i, instr_prefix);
772
	break;
773
    default:
774
	kgem_debug_print(data, offset, i++, "%s: unknown\n", instr_prefix);
775
	kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
776
	kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
777
	break;
778
    }
779
}
780
 
781
static const char *
782
gen3_decode_compare_func(uint32_t op)
783
{
784
	switch (op&0x7) {
785
	case 0: return "always";
786
	case 1: return "never";
787
	case 2: return "less";
788
	case 3: return "equal";
789
	case 4: return "lequal";
790
	case 5: return "greater";
791
	case 6: return "notequal";
792
	case 7: return "gequal";
793
	}
794
	return "";
795
}
796
 
797
static const char *
798
gen3_decode_stencil_op(uint32_t op)
799
{
800
	switch (op&0x7) {
801
	case 0: return "keep";
802
	case 1: return "zero";
803
	case 2: return "replace";
804
	case 3: return "incr_sat";
805
	case 4: return "decr_sat";
806
	case 5: return "greater";
807
	case 6: return "incr";
808
	case 7: return "decr";
809
	}
810
	return "";
811
}
812
 
813
#if 0
814
/* part of MODES_4 */
815
static const char *
816
gen3_decode_logic_op(uint32_t op)
817
{
818
	switch (op&0xf) {
819
	case 0: return "clear";
820
	case 1: return "nor";
821
	case 2: return "and_inv";
822
	case 3: return "copy_inv";
823
	case 4: return "and_rvrse";
824
	case 5: return "inv";
825
	case 6: return "xor";
826
	case 7: return "nand";
827
	case 8: return "and";
828
	case 9: return "equiv";
829
	case 10: return "noop";
830
	case 11: return "or_inv";
831
	case 12: return "copy";
832
	case 13: return "or_rvrse";
833
	case 14: return "or";
834
	case 15: return "set";
835
	}
836
	return "";
837
}
838
#endif
839
 
840
static const char *
841
gen3_decode_blend_fact(uint32_t op)
842
{
843
	switch (op&0xf) {
844
	case 1: return "zero";
845
	case 2: return "one";
846
	case 3: return "src_colr";
847
	case 4: return "inv_src_colr";
848
	case 5: return "src_alpha";
849
	case 6: return "inv_src_alpha";
850
	case 7: return "dst_alpha";
851
	case 8: return "inv_dst_alpha";
852
	case 9: return "dst_colr";
853
	case 10: return "inv_dst_colr";
854
	case 11: return "src_alpha_sat";
855
	case 12: return "cnst_colr";
856
	case 13: return "inv_cnst_colr";
857
	case 14: return "cnst_alpha";
858
	case 15: return "inv_const_alpha";
859
	}
860
	return "";
861
}
862
 
863
static const char *
864
decode_tex_coord_mode(uint32_t mode)
865
{
866
    switch (mode&0x7) {
867
    case 0: return "wrap";
868
    case 1: return "mirror";
869
    case 2: return "clamp_edge";
870
    case 3: return "cube";
871
    case 4: return "clamp_border";
872
    case 5: return "mirror_once";
873
    }
874
    return "";
875
}
876
 
877
static const char *
878
gen3_decode_sample_filter(uint32_t mode)
879
{
880
	switch (mode&0x7) {
881
	case 0: return "nearest";
882
	case 1: return "linear";
883
	case 2: return "anisotropic";
884
	case 3: return "4x4_1";
885
	case 4: return "4x4_2";
886
	case 5: return "4x4_flat";
887
	case 6: return "6x5_mono";
888
	}
889
	return "";
890
}
891
 
892
static int
893
gen3_decode_load_state_immediate_1(struct kgem *kgem, uint32_t offset)
894
{
895
	const uint32_t *data = kgem->batch + offset;
896
	int len, i, word;
897
 
898
	kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n");
899
	len = (data[0] & 0x0000000f) + 2;
900
	i = 1;
901
	for (word = 0; word <= 8; word++) {
902
		if (data[0] & (1 << (4 + word))) {
903
			switch (word) {
904
			case 0:
905
				kgem_debug_print(data, offset, i, "S0: vbo offset: 0x%08x%s\n",
906
					  data[i]&(~1),data[i]&1?", auto cache invalidate disabled":"");
907
				gen3_update_vertex_buffer_addr(kgem, offset + i);
908
				break;
909
			case 1:
910
				kgem_debug_print(data, offset, i, "S1: vertex width: %i, vertex pitch: %i\n",
911
					  (data[i]>>24)&0x3f,(data[i]>>16)&0x3f);
912
				gen3_update_vertex_buffer_pitch(kgem, offset + i);
913
				break;
914
			case 2:
915
				{
916
					char buf[200];
917
					int len = 0;
918
					int tex_num;
919
					for (tex_num = 0; tex_num < 8; tex_num++) {
920
						switch((data[i]>>tex_num*4)&0xf) {
921
						case 0: len += sprintf(buf + len, "%i=2D ", tex_num); break;
922
						case 1: len += sprintf(buf + len, "%i=3D ", tex_num); break;
923
						case 2: len += sprintf(buf + len, "%i=4D ", tex_num); break;
924
						case 3: len += sprintf(buf + len, "%i=1D ", tex_num); break;
925
						case 4: len += sprintf(buf + len, "%i=2D_16 ", tex_num); break;
926
						case 5: len += sprintf(buf + len, "%i=4D_16 ", tex_num); break;
927
						case 0xf: len += sprintf(buf + len, "%i=NP ", tex_num); break;
928
						}
929
					}
930
					kgem_debug_print(data, offset, i, "S2: texcoord formats: %s\n", buf);
931
					gen3_update_vertex_texcoords(kgem, data[i]);
932
				}
933
 
934
				break;
935
			case 3:
936
				kgem_debug_print(data, offset, i, "S3: not documented\n");
937
				break;
938
			case 4:
939
				{
940
					const char *cullmode = "";
941
					const char *vfmt_xyzw = "";
942
					switch((data[i]>>13)&0x3) {
943
					case 0: cullmode = "both"; break;
944
					case 1: cullmode = "none"; break;
945
					case 2: cullmode = "cw"; break;
946
					case 3: cullmode = "ccw"; break;
947
					}
948
					switch(data[i] & (7<<6 | 1<<2)) {
949
					case 1<<6: vfmt_xyzw = "XYZ,"; break;
950
					case 2<<6: vfmt_xyzw = "XYZW,"; break;
951
					case 3<<6: vfmt_xyzw = "XY,"; break;
952
					case 4<<6: vfmt_xyzw = "XYW,"; break;
953
					case 1<<6 | 1<<2: vfmt_xyzw = "XYZF,"; break;
954
					case 2<<6 | 1<<2: vfmt_xyzw = "XYZWF,"; break;
955
					case 3<<6 | 1<<2: vfmt_xyzw = "XYF,"; break;
956
					case 4<<6 | 1<<2: vfmt_xyzw = "XYWF,"; break;
957
					}
958
					kgem_debug_print(data, offset, i, "S4: point_width=%i, line_width=%.1f,"
959
						  "%s%s%s%s%s cullmode=%s, vfmt=%s%s%s%s%s%s%s%s "
960
						  "%s%s%s\n",
961
						  (data[i]>>23)&0x1ff,
962
						  ((data[i]>>19)&0xf) / 2.0,
963
						  data[i]&(0xf<<15)?" flatshade=":"",
964
						  data[i]&(1<<18)?"Alpha,":"",
965
						  data[i]&(1<<17)?"Fog,":"",
966
						  data[i]&(1<<16)?"Specular,":"",
967
						  data[i]&(1<<15)?"Color,":"",
968
						  cullmode,
969
						  data[i]&(1<<12)?"PointWidth,":"",
970
						  data[i]&(1<<11)?"SpecFog,":"",
971
						  data[i]&(1<<10)?"Color,":"",
972
						  data[i]&(1<<9)?"DepthOfs,":"",
973
						  vfmt_xyzw,
974
						  data[i]&(1<<9)?"FogParam,":"",
975
						  data[i]&(1<<5)?"force default diffuse, ":"",
976
						  data[i]&(1<<4)?"force default specular, ":"",
977
						  data[i]&(1<<3)?"local depth ofs enable, ":"",
978
						  data[i]&(1<<1)?"point sprite enable, ":"",
979
						  data[i]&(1<<0)?"line AA enable, ":"");
980
					gen3_update_vertex_elements(kgem, data[i]);
981
					break;
982
				}
983
			case 5:
984
				{
985
					kgem_debug_print(data, offset, i, "S5:%s%s%s%s%s"
986
						  "%s%s%s%s stencil_ref=0x%x, stencil_test=%s, "
987
						  "stencil_fail=%s, stencil_pass_z_fail=%s, "
988
						  "stencil_pass_z_pass=%s, %s%s%s%s\n",
989
						  data[i]&(0xf<<28)?" write_disable=":"",
990
						  data[i]&(1<<31)?"Alpha,":"",
991
						  data[i]&(1<<30)?"Red,":"",
992
						  data[i]&(1<<29)?"Green,":"",
993
						  data[i]&(1<<28)?"Blue,":"",
994
						  data[i]&(1<<27)?" force default point size,":"",
995
						  data[i]&(1<<26)?" last pixel enable,":"",
996
						  data[i]&(1<<25)?" global depth ofs enable,":"",
997
						  data[i]&(1<<24)?" fog enable,":"",
998
						  (data[i]>>16)&0xff,
999
						  gen3_decode_compare_func(data[i]>>13),
1000
						  gen3_decode_stencil_op(data[i]>>10),
1001
						  gen3_decode_stencil_op(data[i]>>7),
1002
						  gen3_decode_stencil_op(data[i]>>4),
1003
						  data[i]&(1<<3)?"stencil write enable, ":"",
1004
						  data[i]&(1<<2)?"stencil test enable, ":"",
1005
						  data[i]&(1<<1)?"color dither enable, ":"",
1006
						  data[i]&(1<<0)?"logicop enable, ":"");
1007
				}
1008
				break;
1009
			case 6:
1010
				kgem_debug_print(data, offset, i, "S6: %salpha_test=%s, alpha_ref=0x%x, "
1011
					  "depth_test=%s, %ssrc_blnd_fct=%s, dst_blnd_fct=%s, "
1012
					  "%s%stristrip_provoking_vertex=%i\n",
1013
					  data[i]&(1<<31)?"alpha test enable, ":"",
1014
					  gen3_decode_compare_func(data[i]>>28),
1015
					  data[i]&(0xff<<20),
1016
					  gen3_decode_compare_func(data[i]>>16),
1017
					  data[i]&(1<<15)?"cbuf blend enable, ":"",
1018
					  gen3_decode_blend_fact(data[i]>>8),
1019
					  gen3_decode_blend_fact(data[i]>>4),
1020
					  data[i]&(1<<3)?"depth write enable, ":"",
1021
					  data[i]&(1<<2)?"cbuf write enable, ":"",
1022
					  data[i]&(0x3));
1023
				break;
1024
			case 7:
1025
				kgem_debug_print(data, offset, i, "S7: depth offset constant: 0x%08x\n", data[i]);
1026
				break;
1027
			}
1028
			i++;
1029
		}
1030
	}
1031
 
1032
	assert(len == i);
1033
	return len;
1034
}
1035
 
1036
static int
1037
gen3_decode_3d_1d(struct kgem *kgem, uint32_t offset)
1038
{
1039
	uint32_t *data = kgem->batch + offset;
1040
	unsigned int len, i, c, idx, word, map, sampler, instr;
1041
	const char *format, *zformat, *type;
1042
	uint32_t opcode;
1043
	static const struct {
1044
		uint32_t opcode;
1045
		int min_len;
1046
		int max_len;
1047
		const char *name;
1048
	} opcodes_3d_1d[] = {
1049
		{ 0x86, 4, 4, "3DSTATE_CHROMA_KEY" },
1050
		{ 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" },
1051
		{ 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" },
1052
		{ 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" },
1053
		{ 0x98, 2, 2, "3DSTATE_DEFAULT_Z" },
1054
		{ 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" },
1055
		{ 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" },
1056
		{ 0x9e, 4, 4, "3DSTATE_MONO_FILTER" },
1057
		{ 0x89, 4, 4, "3DSTATE_FOG_MODE" },
1058
		{ 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" },
1059
		{ 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" },
1060
	}, *opcode_3d_1d;
1061
 
1062
	opcode = (data[0] & 0x00ff0000) >> 16;
1063
 
1064
	switch (opcode) {
1065
	case 0x07:
1066
		/* This instruction is unusual.  A 0 length means just 1 DWORD instead of
1067
		 * 2.  The 0 length is specified in one place to be unsupported, but
1068
		 * stated to be required in another, and 0 length LOAD_INDIRECTs appear
1069
		 * to cause no harm at least.
1070
		 */
1071
		kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_INDIRECT\n");
1072
		len = (data[0] & 0x000000ff) + 1;
1073
		i = 1;
1074
		if (data[0] & (0x01 << 8)) {
1075
			kgem_debug_print(data, offset, i++, "SIS.0\n");
1076
			kgem_debug_print(data, offset, i++, "SIS.1\n");
1077
		}
1078
		if (data[0] & (0x02 << 8)) {
1079
			kgem_debug_print(data, offset, i++, "DIS.0\n");
1080
		}
1081
		if (data[0] & (0x04 << 8)) {
1082
			kgem_debug_print(data, offset, i++, "SSB.0\n");
1083
			kgem_debug_print(data, offset, i++, "SSB.1\n");
1084
		}
1085
		if (data[0] & (0x08 << 8)) {
1086
			kgem_debug_print(data, offset, i++, "MSB.0\n");
1087
			kgem_debug_print(data, offset, i++, "MSB.1\n");
1088
		}
1089
		if (data[0] & (0x10 << 8)) {
1090
			kgem_debug_print(data, offset, i++, "PSP.0\n");
1091
			kgem_debug_print(data, offset, i++, "PSP.1\n");
1092
		}
1093
		if (data[0] & (0x20 << 8)) {
1094
			kgem_debug_print(data, offset, i++, "PSC.0\n");
1095
			kgem_debug_print(data, offset, i++, "PSC.1\n");
1096
		}
1097
		assert(len == i);
1098
		return len;
1099
	case 0x04:
1100
		return gen3_decode_load_state_immediate_1(kgem, offset);
1101
	case 0x03:
1102
		kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_2\n");
1103
		len = (data[0] & 0x0000000f) + 2;
1104
		i = 1;
1105
		for (word = 6; word <= 14; word++) {
1106
			if (data[0] & (1 << word)) {
1107
				if (word == 6)
1108
					kgem_debug_print(data, offset, i++, "TBCF\n");
1109
				else if (word >= 7 && word <= 10) {
1110
					kgem_debug_print(data, offset, i++, "TB%dC\n", word - 7);
1111
					kgem_debug_print(data, offset, i++, "TB%dA\n", word - 7);
1112
				} else if (word >= 11 && word <= 14) {
1113
					kgem_debug_print(data, offset, i, "TM%dS0: offset=0x%08x, %s\n",
1114
						  word - 11,
1115
						  data[i]&0xfffffffe,
1116
						  data[i]&1?"use fence":"");
1117
					i++;
1118
					kgem_debug_print(data, offset, i, "TM%dS1: height=%i, width=%i, %s\n",
1119
						  word - 11,
1120
						  data[i]>>21, (data[i]>>10)&0x3ff,
1121
						  data[i]&2?(data[i]&1?"y-tiled":"x-tiled"):"");
1122
					i++;
1123
					kgem_debug_print(data, offset, i, "TM%dS2: pitch=%i, \n",
1124
						  word - 11,
1125
						  ((data[i]>>21) + 1)*4);
1126
					i++;
1127
					kgem_debug_print(data, offset, i++, "TM%dS3\n", word - 11);
1128
					kgem_debug_print(data, offset, i++, "TM%dS4: dflt color\n", word - 11);
1129
				}
1130
			}
1131
		}
1132
		assert(len == i);
1133
		return len;
1134
	case 0x00:
1135
		kgem_debug_print(data, offset, 0, "3DSTATE_MAP_STATE\n");
1136
		len = (data[0] & 0x0000003f) + 2;
1137
		kgem_debug_print(data, offset, 1, "mask\n");
1138
 
1139
		i = 2;
1140
		for (map = 0; map <= 15; map++) {
1141
			if (data[1] & (1 << map)) {
1142
				int width, height, pitch, dword;
1143
				struct drm_i915_gem_relocation_entry *reloc;
1144
				const char *tiling;
1145
 
1146
				reloc = kgem_debug_get_reloc_entry(kgem, &data[i] - kgem->batch);
1147
				assert(reloc->target_handle);
1148
 
1149
				dword = data[i];
1150
				kgem_debug_print(data, offset, i++, "map %d MS2 %s%s%s, handle=%d\n", map,
1151
					  dword&(1<<31)?"untrusted surface, ":"",
1152
					  dword&(1<<1)?"vertical line stride enable, ":"",
1153
					  dword&(1<<0)?"vertical ofs enable, ":"",
1154
					  reloc->target_handle);
1155
 
1156
				dword = data[i];
1157
				width = ((dword >> 10) & ((1 << 11) - 1))+1;
1158
				height = ((dword >> 21) & ((1 << 11) - 1))+1;
1159
 
1160
				tiling = "none";
1161
				if (dword & (1 << 2))
1162
					tiling = "fenced";
1163
				else if (dword & (1 << 1))
1164
					tiling = dword & (1 << 0) ? "Y" : "X";
1165
				type = " BAD";
1166
				format = " (invalid)";
1167
				switch ((dword>>7) & 0x7) {
1168
				case 1:
1169
					type = "8";
1170
					switch ((dword>>3) & 0xf) {
1171
					case 0: format = "I"; break;
1172
					case 1: format = "L"; break;
1173
					case 4: format = "A"; break;
1174
					case 5: format = " mono"; break;
1175
					}
1176
					break;
1177
				case 2:
1178
					type = "16";
1179
					switch ((dword>>3) & 0xf) {
1180
					case 0: format = " rgb565"; break;
1181
					case 1: format = " argb1555"; break;
1182
					case 2: format = " argb4444"; break;
1183
					case 3: format = " ay88"; break;
1184
					case 5: format = " 88dvdu"; break;
1185
					case 6: format = " bump655"; break;
1186
					case 7: format = "I"; break;
1187
					case 8: format = "L"; break;
1188
					case 9: format = "A"; break;
1189
					}
1190
					break;
1191
				case 3:
1192
					type = "32";
1193
					switch ((dword>>3) & 0xf) {
1194
					case 0: format = " argb8888"; break;
1195
					case 1: format = " abgr8888"; break;
1196
					case 2: format = " xrgb8888"; break;
1197
					case 3: format = " xbgr8888"; break;
1198
					case 4: format = " qwvu8888"; break;
1199
					case 5: format = " axvu8888"; break;
1200
					case 6: format = " lxvu8888"; break;
1201
					case 7: format = " xlvu8888"; break;
1202
					case 8: format = " argb2101010"; break;
1203
					case 9: format = " abgr2101010"; break;
1204
					case 10: format = " awvu2101010"; break;
1205
					case 11: format = " gr1616"; break;
1206
					case 12: format = " vu1616"; break;
1207
					case 13: format = " xI824"; break;
1208
					case 14: format = " xA824"; break;
1209
					case 15: format = " xL824"; break;
1210
					}
1211
					break;
1212
				case 5:
1213
					type = "422";
1214
					switch ((dword>>3) & 0xf) {
1215
					case 0: format = " yuv_swapy"; break;
1216
					case 1: format = " yuv"; break;
1217
					case 2: format = " yuv_swapuv"; break;
1218
					case 3: format = " yuv_swapuvy"; break;
1219
					}
1220
					break;
1221
				case 6:
1222
					type = "compressed";
1223
					switch ((dword>>3) & 0x7) {
1224
					case 0: format = " dxt1"; break;
1225
					case 1: format = " dxt2_3"; break;
1226
					case 2: format = " dxt4_5"; break;
1227
					case 3: format = " fxt1"; break;
1228
					case 4: format = " dxt1_rb"; break;
1229
					}
1230
					break;
1231
				case 7:
1232
					type = "4b indexed";
1233
					switch ((dword>>3) & 0xf) {
1234
					case 7: format = " argb8888"; break;
1235
					}
1236
					break;
1237
				default:
1238
					format = "BAD";
1239
					break;
1240
				}
1241
				dword = data[i];
1242
				kgem_debug_print(data, offset, i++, "map %d MS3 [width=%d, height=%d, format=%s%s, tiling=%s%s]\n",
1243
					  map, width, height, type, format, tiling,
1244
					  dword&(1<<9)?" palette select":"");
1245
 
1246
				dword = data[i];
1247
				pitch = 4*(((dword >> 21) & ((1 << 11) - 1))+1);
1248
				kgem_debug_print(data, offset, i++, "map %d MS4 [pitch=%d, max_lod=%i, vol_depth=%i, cube_face_ena=%x, %s]\n",
1249
					  map, pitch,
1250
					  (dword>>9)&0x3f, dword&0xff, (dword>>15)&0x3f,
1251
					  dword&(1<<8)?"miplayout legacy":"miplayout right");
1252
			}
1253
		}
1254
		assert(len == i);
1255
		return len;
1256
	case 0x06:
1257
		kgem_debug_print(data, offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n");
1258
		len = (data[0] & 0x000000ff) + 2;
1259
 
1260
		i = 2;
1261
		for (c = 0; c <= 31; c++) {
1262
			if (data[1] & (1 << c)) {
1263
				kgem_debug_print(data, offset, i, "C%d.X = %f\n",
1264
					  c, int_as_float(data[i]));
1265
				i++;
1266
				kgem_debug_print(data, offset, i, "C%d.Y = %f\n",
1267
					  c, int_as_float(data[i]));
1268
				i++;
1269
				kgem_debug_print(data, offset, i, "C%d.Z = %f\n",
1270
					  c, int_as_float(data[i]));
1271
				i++;
1272
				kgem_debug_print(data, offset, i, "C%d.W = %f\n",
1273
					  c, int_as_float(data[i]));
1274
				i++;
1275
			}
1276
		}
1277
		assert(len == i);
1278
		return len;
1279
	case 0x05:
1280
		kgem_debug_print(data, offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n");
1281
		len = (data[0] & 0x000000ff) + 2;
1282
		assert(((len-1) % 3) == 0);
1283
		assert(len <= 370);
1284
		i = 1;
1285
		for (instr = 0; instr < (len - 1) / 3; instr++) {
1286
			char instr_prefix[10];
1287
 
1288
			sprintf(instr_prefix, "PS%03d", instr);
1289
			gen3_decode_instruction(data, offset, i, instr_prefix);
1290
			i += 3;
1291
		}
1292
		return len;
1293
	case 0x01:
1294
		kgem_debug_print(data, offset, 0, "3DSTATE_SAMPLER_STATE\n");
1295
		kgem_debug_print(data, offset, 1, "mask\n");
1296
		len = (data[0] & 0x0000003f) + 2;
1297
		i = 2;
1298
		for (sampler = 0; sampler <= 15; sampler++) {
1299
			if (data[1] & (1 << sampler)) {
1300
				uint32_t dword;
1301
				const char *mip_filter = "";
1302
				dword = data[i];
1303
				switch ((dword>>20)&0x3) {
1304
				case 0: mip_filter = "none"; break;
1305
				case 1: mip_filter = "nearest"; break;
1306
				case 3: mip_filter = "linear"; break;
1307
				}
1308
				kgem_debug_print(data, offset, i++, "sampler %d SS2:%s%s%s "
1309
					  "base_mip_level=%i, mip_filter=%s, mag_filter=%s, min_filter=%s "
1310
					  "lod_bias=%.2f,%s max_aniso=%i, shadow_func=%s\n", sampler,
1311
					  dword&(1<<31)?" reverse gamma,":"",
1312
					  dword&(1<<30)?" packed2planar,":"",
1313
					  dword&(1<<29)?" colorspace conversion,":"",
1314
					  (dword>>22)&0x1f,
1315
					  mip_filter,
1316
					  gen3_decode_sample_filter(dword>>17),
1317
					  gen3_decode_sample_filter(dword>>14),
1318
					  ((dword>>5)&0x1ff)/(0x10*1.0),
1319
					  dword&(1<<4)?" shadow,":"",
1320
					  dword&(1<<3)?4:2,
1321
					  gen3_decode_compare_func(dword));
1322
				dword = data[i];
1323
				kgem_debug_print(data, offset, i++, "sampler %d SS3: min_lod=%.2f,%s "
1324
					  "tcmode_x=%s, tcmode_y=%s, tcmode_z=%s,%s texmap_idx=%i,%s\n",
1325
					  sampler, ((dword>>24)&0xff)/(0x10*1.0),
1326
					  dword&(1<<17)?" kill pixel enable,":"",
1327
					  decode_tex_coord_mode(dword>>12),
1328
					  decode_tex_coord_mode(dword>>9),
1329
					  decode_tex_coord_mode(dword>>6),
1330
					  dword&(1<<5)?" normalized coords,":"",
1331
					  (dword>>1)&0xf,
1332
					  dword&(1<<0)?" deinterlacer,":"");
1333
				kgem_debug_print(data, offset, i++, "sampler %d SS4: border color\n",
1334
					  sampler);
1335
			}
1336
		}
1337
		assert(len == i);
1338
		return len;
1339
	case 0x85:
1340
		len = (data[0] & 0x0000000f) + 2;
1341
		assert(len == 2);
1342
 
1343
		kgem_debug_print(data, offset, 0,
1344
			  "3DSTATE_DEST_BUFFER_VARIABLES\n");
1345
 
1346
		switch ((data[1] >> 8) & 0xf) {
1347
		case 0x0: format = "g8"; break;
1348
		case 0x1: format = "x1r5g5b5"; break;
1349
		case 0x2: format = "r5g6b5"; break;
1350
		case 0x3: format = "a8r8g8b8"; break;
1351
		case 0x4: format = "ycrcb_swapy"; break;
1352
		case 0x5: format = "ycrcb_normal"; break;
1353
		case 0x6: format = "ycrcb_swapuv"; break;
1354
		case 0x7: format = "ycrcb_swapuvy"; break;
1355
		case 0x8: format = "a4r4g4b4"; break;
1356
		case 0x9: format = "a1r5g5b5"; break;
1357
		case 0xa: format = "a2r10g10b10"; break;
1358
		default: format = "BAD"; break;
1359
		}
1360
		switch ((data[1] >> 2) & 0x3) {
1361
		case 0x0: zformat = "u16"; break;
1362
		case 0x1: zformat = "f16"; break;
1363
		case 0x2: zformat = "u24x8"; break;
1364
		default: zformat = "BAD"; break;
1365
		}
1366
		kgem_debug_print(data, offset, 1, "%s format, %s depth format, early Z %sabled\n",
1367
			  format, zformat,
1368
			  (data[1] & (1 << 31)) ? "en" : "dis");
1369
		return len;
1370
 
1371
	case 0x8e:
1372
		{
1373
			const char *name, *tiling;
1374
 
1375
			len = (data[0] & 0x0000000f) + 2;
1376
			assert(len == 3);
1377
 
1378
			switch((data[1] >> 24) & 0x7) {
1379
			case 0x3: name = "color"; break;
1380
			case 0x7: name = "depth"; break;
1381
			default: name = "unknown"; break;
1382
			}
1383
 
1384
			tiling = "none";
1385
			if (data[1] & (1 << 23))
1386
				tiling = "fenced";
1387
			else if (data[1] & (1 << 22))
1388
				tiling = data[1] & (1 << 21) ? "Y" : "X";
1389
 
1390
			kgem_debug_print(data, offset, 0, "3DSTATE_BUFFER_INFO\n");
1391
			kgem_debug_print(data, offset, 1, "%s, tiling = %s, pitch=%d\n", name, tiling, data[1]&0xffff);
1392
 
1393
			kgem_debug_print(data, offset, 2, "address\n");
1394
			return len;
1395
		}
1396
	case 0x81:
1397
		len = (data[0] & 0x0000000f) + 2;
1398
		assert(len == 3);
1399
 
1400
		kgem_debug_print(data, offset, 0,
1401
			  "3DSTATE_SCISSOR_RECTANGLE\n");
1402
		kgem_debug_print(data, offset, 1, "(%d,%d)\n",
1403
			  data[1] & 0xffff, data[1] >> 16);
1404
		kgem_debug_print(data, offset, 2, "(%d,%d)\n",
1405
			  data[2] & 0xffff, data[2] >> 16);
1406
 
1407
		return len;
1408
	case 0x80:
1409
		len = (data[0] & 0x0000000f) + 2;
1410
		assert(len == 5);
1411
 
1412
		kgem_debug_print(data, offset, 0,
1413
			  "3DSTATE_DRAWING_RECTANGLE\n");
1414
		kgem_debug_print(data, offset, 1, "%s\n",
1415
			  data[1]&(1<<30)?"depth ofs disabled ":"");
1416
		kgem_debug_print(data, offset, 2, "(%d,%d)\n",
1417
			  data[2] & 0xffff, data[2] >> 16);
1418
		kgem_debug_print(data, offset, 3, "(%d,%d)\n",
1419
			  data[3] & 0xffff, data[3] >> 16);
1420
		kgem_debug_print(data, offset, 4, "(%d,%d)\n",
1421
			  (int16_t)(data[4] & 0xffff),
1422
			  (int16_t)(data[4] >> 16));
1423
 
1424
		return len;
1425
	case 0x9c:
1426
		len = (data[0] & 0x0000000f) + 2;
1427
		assert(len == 7);
1428
 
1429
		kgem_debug_print(data, offset, 0,
1430
			  "3DSTATE_CLEAR_PARAMETERS\n");
1431
		kgem_debug_print(data, offset, 1, "prim_type=%s, clear=%s%s%s\n",
1432
			  data[1]&(1<<16)?"CLEAR_RECT":"ZONE_INIT",
1433
			  data[1]&(1<<2)?"color,":"",
1434
			  data[1]&(1<<1)?"depth,":"",
1435
			  data[1]&(1<<0)?"stencil,":"");
1436
		kgem_debug_print(data, offset, 2, "clear color\n");
1437
		kgem_debug_print(data, offset, 3, "clear depth/stencil\n");
1438
		kgem_debug_print(data, offset, 4, "color value (rgba8888)\n");
1439
		kgem_debug_print(data, offset, 5, "depth value %f\n",
1440
			  int_as_float(data[5]));
1441
		kgem_debug_print(data, offset, 6, "clear stencil\n");
1442
		return len;
1443
	}
1444
 
1445
	for (idx = 0; idx < ARRAY_SIZE(opcodes_3d_1d); idx++) {
1446
		opcode_3d_1d = &opcodes_3d_1d[idx];
1447
		if (((data[0] & 0x00ff0000) >> 16) == opcode_3d_1d->opcode) {
1448
			len = (data[0] & 0xf) + 2;
1449
			kgem_debug_print(data, offset, 0, "%s\n", opcode_3d_1d->name);
1450
			for (i = 1; i < len; i++)
1451
				kgem_debug_print(data, offset, i, "dword %d\n", i);
1452
 
1453
			return len;
1454
		}
1455
	}
1456
 
1457
	kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1d opcode = 0x%x\n", opcode);
1458
	assert(0);
1459
	return 1;
1460
}
1461
 
1462
#define VERTEX_OUT(fmt, ...) do {					\
1463
	kgem_debug_print(data, offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \
1464
	i++;								\
1465
} while (0)
1466
 
1467
static int
1468
gen3_decode_3d_primitive(struct kgem *kgem, uint32_t offset)
1469
{
1470
	uint32_t *data = kgem->batch + offset;
1471
	char immediate = (data[0] & (1 << 23)) == 0;
1472
	unsigned int len, i, ret;
1473
	const char *primtype;
1474
	unsigned int vertex = 0;
1475
 
1476
	switch ((data[0] >> 18) & 0xf) {
1477
	case 0x0: primtype = "TRILIST"; break;
1478
	case 0x1: primtype = "TRISTRIP"; break;
1479
	case 0x2: primtype = "TRISTRIP_REVERSE"; break;
1480
	case 0x3: primtype = "TRIFAN"; break;
1481
	case 0x4: primtype = "POLYGON"; break;
1482
	case 0x5: primtype = "LINELIST"; break;
1483
	case 0x6: primtype = "LINESTRIP"; break;
1484
	case 0x7: primtype = "RECTLIST"; break;
1485
	case 0x8: primtype = "POINTLIST"; break;
1486
	case 0x9: primtype = "DIB"; break;
1487
	case 0xa: primtype = "CLEAR_RECT"; assert(0); break;
1488
	default: primtype = "unknown"; break;
1489
	}
1490
 
1491
	gen3_update_vertex_elements_offsets(kgem);
1492
 
1493
	/* XXX: 3DPRIM_DIB not supported */
1494
	if (immediate) {
1495
		len = (data[0] & 0x0003ffff) + 2;
1496
		kgem_debug_print(data, offset, 0, "3DPRIMITIVE inline %s\n", primtype);
1497
		for (i = 1; i < len; ) {
1498
			ErrorF("    [%d]: ", vertex);
1499
			i += inline_vertex_out(kgem, data + i) / sizeof(uint32_t);
1500
			ErrorF("\n");
1501
			vertex++;
1502
		}
1503
 
1504
		ret = len;
1505
	} else {
1506
		/* indirect vertices */
1507
		len = data[0] & 0x0000ffff; /* index count */
1508
		if (data[0] & (1 << 17)) {
1509
			/* random vertex access */
1510
			kgem_debug_print(data, offset, 0,
1511
				  "3DPRIMITIVE random indirect %s (%d)\n", primtype, len);
1512
			assert(0);
1513
			if (len == 0) {
1514
				/* vertex indices continue until 0xffff is found */
1515
			} else {
1516
				/* fixed size vertex index buffer */
1517
			}
1518
			ret = (len + 1) / 2 + 1;
1519
			goto out;
1520
		} else {
1521
			/* sequential vertex access */
1522
			vertex = data[1] & 0xffff;
1523
			kgem_debug_print(data, offset, 0,
1524
				  "3DPRIMITIVE sequential indirect %s, %d starting from "
1525
				  "%d\n", primtype, len, vertex);
1526
			kgem_debug_print(data, offset, 1, "  start\n");
1527
			for (i = 0; i < len; i++) {
1528
				ErrorF("    [%d]: ", vertex);
1529
				indirect_vertex_out(kgem, vertex++);
1530
				ErrorF("\n");
1531
			}
1532
			ret = 2;
1533
			goto out;
1534
		}
1535
	}
1536
 
1537
out:
1538
	return ret;
1539
}
1540
 
1541
int kgem_gen3_decode_3d(struct kgem *kgem, uint32_t offset)
1542
{
1543
    static const struct {
1544
	uint32_t opcode;
1545
	int min_len;
1546
	int max_len;
1547
	const char *name;
1548
    } opcodes[] = {
1549
	{ 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" },
1550
	{ 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" },
1551
	{ 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" },
1552
	{ 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" },
1553
	{ 0x15, 1, 1, "3DSTATE_FOG_COLOR" },
1554
	{ 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" },
1555
	{ 0x0d, 1, 1, "3DSTATE_MODES_4" },
1556
	{ 0x0c, 1, 1, "3DSTATE_MODES_5" },
1557
	{ 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" },
1558
    };
1559
    uint32_t *data = kgem->batch + offset;
1560
    uint32_t opcode;
1561
    unsigned int idx;
1562
 
1563
    opcode = (data[0] & 0x1f000000) >> 24;
1564
 
1565
    switch (opcode) {
1566
    case 0x1f:
1567
	return gen3_decode_3d_primitive(kgem, offset);
1568
    case 0x1d:
1569
	return gen3_decode_3d_1d(kgem, offset);
1570
    case 0x1c:
1571
	return gen3_decode_3d_1c(kgem, offset);
1572
    }
1573
 
1574
    for (idx = 0; idx < ARRAY_SIZE(opcodes); idx++) {
1575
	if (opcode == opcodes[idx].opcode) {
1576
	    unsigned int len = 1, i;
1577
 
1578
	    kgem_debug_print(data, offset, 0, "%s\n", opcodes[idx].name);
1579
	    if (opcodes[idx].max_len > 1) {
1580
		len = (data[0] & 0xff) + 2;
1581
		assert(len >= opcodes[idx].min_len ||
1582
		       len <= opcodes[idx].max_len);
1583
	    }
1584
 
1585
	    for (i = 1; i < len; i++)
1586
		kgem_debug_print(data, offset, i, "dword %d\n", i);
1587
	    return len;
1588
	}
1589
    }
1590
 
1591
    kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d opcode = 0x%x\n", opcode);
1592
    return 1;
1593
}
1594
 
1595
 
1596
void kgem_gen3_finish_state(struct kgem *kgem)
1597
{
1598
	memset(&state, 0, sizeof(state));
1599
}