Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / drivers / svga / svgadump / svga_shader_dump.c
1 /**********************************************************
2 * Copyright 2008-2009 VMware, Inc. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 **********************************************************/
25
26 /**
27 * @file
28 * SVGA Shader Dump Facilities
29 *
30 * @author Michal Krol <michal@vmware.com>
31 */
32
33 #include "svga_shader.h"
34 #include "svga_shader_dump.h"
35 #include "svga_shader_op.h"
36 #include "util/u_debug.h"
37
38 #include "../svga_hw_reg.h"
39 #include "svga3d_shaderdefs.h"
40
41 struct dump_info
42 {
43 SVGA3dShaderVersion version;
44 boolean is_ps;
45 };
46
47 static void dump_op( struct sh_op op, const char *mnemonic )
48 {
49 assert( op.predicated == 0 );
50 assert( op.is_reg == 0 );
51
52 if (op.coissue)
53 _debug_printf( "+" );
54 _debug_printf( "%s", mnemonic );
55 switch (op.control) {
56 case 0:
57 break;
58 case SVGA3DOPCONT_PROJECT:
59 _debug_printf( "p" );
60 break;
61 case SVGA3DOPCONT_BIAS:
62 _debug_printf( "b" );
63 break;
64 default:
65 assert( 0 );
66 }
67 }
68
69
70 static void dump_comp_op( struct sh_op op, const char *mnemonic )
71 {
72 assert( op.is_reg == 0 );
73
74 if (op.coissue)
75 _debug_printf( "+" );
76 _debug_printf( "%s", mnemonic );
77 switch (op.control) {
78 case SVGA3DOPCOMP_RESERVED0:
79 break;
80 case SVGA3DOPCOMP_GT:
81 _debug_printf("_gt");
82 break;
83 case SVGA3DOPCOMP_EQ:
84 _debug_printf("_eq");
85 break;
86 case SVGA3DOPCOMP_GE:
87 _debug_printf("_ge");
88 break;
89 case SVGA3DOPCOMP_LT:
90 _debug_printf("_lt");
91 break;
92 case SVGA3DOPCOMPC_NE:
93 _debug_printf("_ne");
94 break;
95 case SVGA3DOPCOMP_LE:
96 _debug_printf("_le");
97 break;
98 case SVGA3DOPCOMP_RESERVED1:
99 default:
100 assert( 0 );
101 }
102 }
103
104
105 static void dump_reg( struct sh_reg reg, struct sh_srcreg *indreg, const struct dump_info *di )
106 {
107 assert( sh_reg_type( reg ) == SVGA3DREG_CONST || reg.relative == 0 );
108 assert( reg.is_reg == 1 );
109
110 switch (sh_reg_type( reg )) {
111 case SVGA3DREG_TEMP:
112 _debug_printf( "r%u", reg.number );
113 break;
114
115 case SVGA3DREG_INPUT:
116 _debug_printf( "v%u", reg.number );
117 break;
118
119 case SVGA3DREG_CONST:
120 if (reg.relative) {
121 if (sh_srcreg_type( *indreg ) == SVGA3DREG_LOOP)
122 _debug_printf( "c[aL+%u]", reg.number );
123 else
124 _debug_printf( "c[a%u.x+%u]", indreg->number, reg.number );
125 }
126 else
127 _debug_printf( "c%u", reg.number );
128 break;
129
130 case SVGA3DREG_ADDR: /* VS */
131 /* SVGA3DREG_TEXTURE */ /* PS */
132 if (di->is_ps)
133 _debug_printf( "t%u", reg.number );
134 else
135 _debug_printf( "a%u", reg.number );
136 break;
137
138 case SVGA3DREG_RASTOUT:
139 switch (reg.number) {
140 case 0 /*POSITION*/:
141 _debug_printf( "oPos" );
142 break;
143 case 1 /*FOG*/:
144 _debug_printf( "oFog" );
145 break;
146 case 2 /*POINT_SIZE*/:
147 _debug_printf( "oPts" );
148 break;
149 default:
150 assert( 0 );
151 _debug_printf( "???" );
152 }
153 break;
154
155 case SVGA3DREG_ATTROUT:
156 assert( reg.number < 2 );
157 _debug_printf( "oD%u", reg.number );
158 break;
159
160 case SVGA3DREG_TEXCRDOUT:
161 /* SVGA3DREG_OUTPUT */
162 _debug_printf( "oT%u", reg.number );
163 break;
164
165 case SVGA3DREG_COLOROUT:
166 _debug_printf( "oC%u", reg.number );
167 break;
168
169 case SVGA3DREG_DEPTHOUT:
170 _debug_printf( "oD%u", reg.number );
171 break;
172
173 case SVGA3DREG_SAMPLER:
174 _debug_printf( "s%u", reg.number );
175 break;
176
177 case SVGA3DREG_CONSTBOOL:
178 assert( !reg.relative );
179 _debug_printf( "b%u", reg.number );
180 break;
181
182 case SVGA3DREG_CONSTINT:
183 assert( !reg.relative );
184 _debug_printf( "i%u", reg.number );
185 break;
186
187 case SVGA3DREG_LOOP:
188 assert( reg.number == 0 );
189 _debug_printf( "aL" );
190 break;
191
192 case SVGA3DREG_MISCTYPE:
193 switch (reg.number) {
194 case SVGA3DMISCREG_POSITION:
195 _debug_printf( "vPos" );
196 break;
197 case SVGA3DMISCREG_FACE:
198 _debug_printf( "vFace" );
199 break;
200 default:
201 assert(0);
202 break;
203 }
204 break;
205
206 case SVGA3DREG_LABEL:
207 _debug_printf( "l%u", reg.number );
208 break;
209
210 case SVGA3DREG_PREDICATE:
211 _debug_printf( "p%u", reg.number );
212 break;
213
214
215 default:
216 assert( 0 );
217 _debug_printf( "???" );
218 }
219 }
220
221 static void dump_cdata( struct sh_cdata cdata )
222 {
223 _debug_printf( "%f, %f, %f, %f", cdata.xyzw[0], cdata.xyzw[1], cdata.xyzw[2], cdata.xyzw[3] );
224 }
225
226 static void dump_idata( struct sh_idata idata )
227 {
228 _debug_printf( "%d, %d, %d, %d", idata.xyzw[0], idata.xyzw[1], idata.xyzw[2], idata.xyzw[3] );
229 }
230
231 static void dump_bdata( boolean bdata )
232 {
233 _debug_printf( bdata ? "TRUE" : "FALSE" );
234 }
235
236 static void dump_sampleinfo( struct ps_sampleinfo sampleinfo )
237 {
238 switch (sampleinfo.texture_type) {
239 case SVGA3DSAMP_2D:
240 _debug_printf( "_2d" );
241 break;
242 case SVGA3DSAMP_CUBE:
243 _debug_printf( "_cube" );
244 break;
245 case SVGA3DSAMP_VOLUME:
246 _debug_printf( "_volume" );
247 break;
248 default:
249 assert( 0 );
250 }
251 }
252
253
254 static void dump_usageinfo( struct vs_semantic semantic )
255 {
256 switch (semantic.usage) {
257 case SVGA3D_DECLUSAGE_POSITION:
258 _debug_printf("_position" );
259 break;
260 case SVGA3D_DECLUSAGE_BLENDWEIGHT:
261 _debug_printf("_blendweight" );
262 break;
263 case SVGA3D_DECLUSAGE_BLENDINDICES:
264 _debug_printf("_blendindices" );
265 break;
266 case SVGA3D_DECLUSAGE_NORMAL:
267 _debug_printf("_normal" );
268 break;
269 case SVGA3D_DECLUSAGE_PSIZE:
270 _debug_printf("_psize" );
271 break;
272 case SVGA3D_DECLUSAGE_TEXCOORD:
273 _debug_printf("_texcoord");
274 break;
275 case SVGA3D_DECLUSAGE_TANGENT:
276 _debug_printf("_tangent" );
277 break;
278 case SVGA3D_DECLUSAGE_BINORMAL:
279 _debug_printf("_binormal" );
280 break;
281 case SVGA3D_DECLUSAGE_TESSFACTOR:
282 _debug_printf("_tessfactor" );
283 break;
284 case SVGA3D_DECLUSAGE_POSITIONT:
285 _debug_printf("_positiont" );
286 break;
287 case SVGA3D_DECLUSAGE_COLOR:
288 _debug_printf("_color" );
289 break;
290 case SVGA3D_DECLUSAGE_FOG:
291 _debug_printf("_fog" );
292 break;
293 case SVGA3D_DECLUSAGE_DEPTH:
294 _debug_printf("_depth" );
295 break;
296 case SVGA3D_DECLUSAGE_SAMPLE:
297 _debug_printf("_sample");
298 break;
299 default:
300 assert( 0 );
301 return;
302 }
303
304 if (semantic.usage_index != 0) {
305 _debug_printf("%d", semantic.usage_index );
306 }
307 }
308
309 static void dump_dstreg( struct sh_dstreg dstreg, const struct dump_info *di )
310 {
311 union {
312 struct sh_reg reg;
313 struct sh_dstreg dstreg;
314 } u;
315
316 assert( (dstreg.modifier & (SVGA3DDSTMOD_SATURATE | SVGA3DDSTMOD_PARTIALPRECISION)) == dstreg.modifier );
317
318 if (dstreg.modifier & SVGA3DDSTMOD_SATURATE)
319 _debug_printf( "_sat" );
320 if (dstreg.modifier & SVGA3DDSTMOD_PARTIALPRECISION)
321 _debug_printf( "_pp" );
322 switch (dstreg.shift_scale) {
323 case 0:
324 break;
325 case 1:
326 _debug_printf( "_x2" );
327 break;
328 case 2:
329 _debug_printf( "_x4" );
330 break;
331 case 3:
332 _debug_printf( "_x8" );
333 break;
334 case 13:
335 _debug_printf( "_d8" );
336 break;
337 case 14:
338 _debug_printf( "_d4" );
339 break;
340 case 15:
341 _debug_printf( "_d2" );
342 break;
343 default:
344 assert( 0 );
345 }
346 _debug_printf( " " );
347
348 u.dstreg = dstreg;
349 dump_reg( u.reg, NULL, di );
350 if (dstreg.write_mask != SVGA3DWRITEMASK_ALL) {
351 _debug_printf( "." );
352 if (dstreg.write_mask & SVGA3DWRITEMASK_0)
353 _debug_printf( "x" );
354 if (dstreg.write_mask & SVGA3DWRITEMASK_1)
355 _debug_printf( "y" );
356 if (dstreg.write_mask & SVGA3DWRITEMASK_2)
357 _debug_printf( "z" );
358 if (dstreg.write_mask & SVGA3DWRITEMASK_3)
359 _debug_printf( "w" );
360 }
361 }
362
363 static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, const struct dump_info *di )
364 {
365 union {
366 struct sh_reg reg;
367 struct sh_srcreg srcreg;
368 } u;
369
370 switch (srcreg.modifier) {
371 case SVGA3DSRCMOD_NEG:
372 case SVGA3DSRCMOD_BIASNEG:
373 case SVGA3DSRCMOD_SIGNNEG:
374 case SVGA3DSRCMOD_X2NEG:
375 _debug_printf( "-" );
376 break;
377 case SVGA3DSRCMOD_ABS:
378 _debug_printf( "|" );
379 break;
380 case SVGA3DSRCMOD_ABSNEG:
381 _debug_printf( "-|" );
382 break;
383 case SVGA3DSRCMOD_COMP:
384 _debug_printf( "1-" );
385 break;
386 case SVGA3DSRCMOD_NOT:
387 _debug_printf( "!" );
388 }
389
390 u.srcreg = srcreg;
391 dump_reg( u.reg, indreg, di );
392 switch (srcreg.modifier) {
393 case SVGA3DSRCMOD_NONE:
394 case SVGA3DSRCMOD_NEG:
395 case SVGA3DSRCMOD_COMP:
396 case SVGA3DSRCMOD_NOT:
397 break;
398 case SVGA3DSRCMOD_ABS:
399 case SVGA3DSRCMOD_ABSNEG:
400 _debug_printf( "|" );
401 break;
402 case SVGA3DSRCMOD_BIAS:
403 case SVGA3DSRCMOD_BIASNEG:
404 _debug_printf( "_bias" );
405 break;
406 case SVGA3DSRCMOD_SIGN:
407 case SVGA3DSRCMOD_SIGNNEG:
408 _debug_printf( "_bx2" );
409 break;
410 case SVGA3DSRCMOD_X2:
411 case SVGA3DSRCMOD_X2NEG:
412 _debug_printf( "_x2" );
413 break;
414 case SVGA3DSRCMOD_DZ:
415 _debug_printf( "_dz" );
416 break;
417 case SVGA3DSRCMOD_DW:
418 _debug_printf( "_dw" );
419 break;
420 default:
421 assert( 0 );
422 }
423 if (srcreg.swizzle_x != 0 || srcreg.swizzle_y != 1 || srcreg.swizzle_z != 2 || srcreg.swizzle_w != 3) {
424 _debug_printf( "." );
425 if (srcreg.swizzle_x == srcreg.swizzle_y && srcreg.swizzle_y == srcreg.swizzle_z && srcreg.swizzle_z == srcreg.swizzle_w) {
426 _debug_printf( "%c", "xyzw"[srcreg.swizzle_x] );
427 }
428 else {
429 _debug_printf( "%c", "xyzw"[srcreg.swizzle_x] );
430 _debug_printf( "%c", "xyzw"[srcreg.swizzle_y] );
431 _debug_printf( "%c", "xyzw"[srcreg.swizzle_z] );
432 _debug_printf( "%c", "xyzw"[srcreg.swizzle_w] );
433 }
434 }
435 }
436
437 void
438 svga_shader_dump(
439 const unsigned *assem,
440 unsigned dwords,
441 unsigned do_binary )
442 {
443 const unsigned *start = assem;
444 boolean finished = FALSE;
445 struct dump_info di;
446 unsigned i;
447
448 if (do_binary) {
449 for (i = 0; i < dwords; i++)
450 _debug_printf(" 0x%08x,\n", assem[i]);
451
452 _debug_printf("\n\n");
453 }
454
455 di.version.value = *assem++;
456 di.is_ps = (di.version.type == SVGA3D_PS_TYPE);
457
458 _debug_printf(
459 "%s_%u_%u\n",
460 di.is_ps ? "ps" : "vs",
461 di.version.major,
462 di.version.minor );
463
464 while (!finished) {
465 struct sh_op op = *(struct sh_op *) assem;
466
467 if (assem - start >= dwords) {
468 _debug_printf("... ran off end of buffer\n");
469 assert(0);
470 return;
471 }
472
473 switch (op.opcode) {
474 case SVGA3DOP_DCL:
475 {
476 struct sh_dcl dcl = *(struct sh_dcl *) assem;
477
478 _debug_printf( "dcl" );
479 if (sh_dstreg_type( dcl.reg ) == SVGA3DREG_SAMPLER)
480 dump_sampleinfo( dcl.u.ps.sampleinfo );
481 else if (di.is_ps) {
482 if (di.version.major == 3 &&
483 sh_dstreg_type( dcl.reg ) != SVGA3DREG_MISCTYPE)
484 dump_usageinfo( dcl.u.vs.semantic );
485 }
486 else
487 dump_usageinfo( dcl.u.vs.semantic );
488 dump_dstreg( dcl.reg, &di );
489 _debug_printf( "\n" );
490 assem += sizeof( struct sh_dcl ) / sizeof( unsigned );
491 }
492 break;
493
494 case SVGA3DOP_DEFB:
495 {
496 struct sh_defb defb = *(struct sh_defb *) assem;
497
498 _debug_printf( "defb " );
499 dump_reg( defb.reg, NULL, &di );
500 _debug_printf( ", " );
501 dump_bdata( defb.data );
502 _debug_printf( "\n" );
503 assem += sizeof( struct sh_defb ) / sizeof( unsigned );
504 }
505 break;
506
507 case SVGA3DOP_DEFI:
508 {
509 struct sh_defi defi = *(struct sh_defi *) assem;
510
511 _debug_printf( "defi " );
512 dump_reg( defi.reg, NULL, &di );
513 _debug_printf( ", " );
514 dump_idata( defi.idata );
515 _debug_printf( "\n" );
516 assem += sizeof( struct sh_defi ) / sizeof( unsigned );
517 }
518 break;
519
520 case SVGA3DOP_TEXCOORD:
521 assert( di.is_ps );
522 dump_op( op, "texcoord" );
523 if (0) {
524 struct sh_dstop dstop = *(struct sh_dstop *) assem;
525 dump_dstreg( dstop.dst, &di );
526 assem += sizeof( struct sh_dstop ) / sizeof( unsigned );
527 }
528 else {
529 struct sh_unaryop unaryop = *(struct sh_unaryop *) assem;
530 dump_dstreg( unaryop.dst, &di );
531 _debug_printf( ", " );
532 dump_srcreg( unaryop.src, NULL, &di );
533 assem += sizeof( struct sh_unaryop ) / sizeof( unsigned );
534 }
535 _debug_printf( "\n" );
536 break;
537
538 case SVGA3DOP_TEX:
539 assert( di.is_ps );
540 if (0) {
541 dump_op( op, "tex" );
542 if (0) {
543 struct sh_dstop dstop = *(struct sh_dstop *) assem;
544
545 dump_dstreg( dstop.dst, &di );
546 assem += sizeof( struct sh_dstop ) / sizeof( unsigned );
547 }
548 else {
549 struct sh_unaryop unaryop = *(struct sh_unaryop *) assem;
550
551 dump_dstreg( unaryop.dst, &di );
552 _debug_printf( ", " );
553 dump_srcreg( unaryop.src, NULL, &di );
554 assem += sizeof( struct sh_unaryop ) / sizeof( unsigned );
555 }
556 }
557 else {
558 struct sh_binaryop binaryop = *(struct sh_binaryop *) assem;
559
560 dump_op( op, "texld" );
561 dump_dstreg( binaryop.dst, &di );
562 _debug_printf( ", " );
563 dump_srcreg( binaryop.src0, NULL, &di );
564 _debug_printf( ", " );
565 dump_srcreg( binaryop.src1, NULL, &di );
566 assem += sizeof( struct sh_binaryop ) / sizeof( unsigned );
567 }
568 _debug_printf( "\n" );
569 break;
570
571 case SVGA3DOP_DEF:
572 {
573 struct sh_def def = *(struct sh_def *) assem;
574
575 _debug_printf( "def " );
576 dump_reg( def.reg, NULL, &di );
577 _debug_printf( ", " );
578 dump_cdata( def.cdata );
579 _debug_printf( "\n" );
580 assem += sizeof( struct sh_def ) / sizeof( unsigned );
581 }
582 break;
583
584 case SVGA3DOP_PHASE:
585 _debug_printf( "phase\n" );
586 assem += sizeof( struct sh_op ) / sizeof( unsigned );
587 break;
588
589 case SVGA3DOP_COMMENT:
590 {
591 struct sh_comment comment = *(struct sh_comment *)assem;
592
593 /* Ignore comment contents. */
594 assem += sizeof(struct sh_comment) / sizeof(unsigned) + comment.size;
595 }
596 break;
597
598 case SVGA3DOP_RET:
599 _debug_printf( "ret\n" );
600 assem += sizeof( struct sh_op ) / sizeof( unsigned );
601 break;
602
603 case SVGA3DOP_END:
604 _debug_printf( "end\n" );
605 finished = TRUE;
606 break;
607
608 default:
609 {
610 const struct sh_opcode_info *info = svga_opcode_info( op.opcode );
611 uint i;
612 uint num_src = info->num_src + op.predicated;
613 boolean not_first_arg = FALSE;
614
615 assert( info->num_dst <= 1 );
616
617 if (op.opcode == SVGA3DOP_SINCOS && di.version.major < 3)
618 num_src += 2;
619
620 dump_comp_op( op, info->mnemonic );
621 assem += sizeof( struct sh_op ) / sizeof( unsigned );
622
623 if (info->num_dst > 0) {
624 struct sh_dstreg dstreg = *(struct sh_dstreg *) assem;
625
626 dump_dstreg( dstreg, &di );
627 assem += sizeof( struct sh_dstreg ) / sizeof( unsigned );
628 not_first_arg = TRUE;
629 }
630
631 for (i = 0; i < num_src; i++) {
632 struct sh_srcreg srcreg;
633 struct sh_srcreg indreg;
634
635 srcreg = *(struct sh_srcreg *) assem;
636 assem += sizeof( struct sh_srcreg ) / sizeof( unsigned );
637 if (srcreg.relative && !di.is_ps && di.version.major >= 2) {
638 indreg = *(struct sh_srcreg *) assem;
639 assem += sizeof( struct sh_srcreg ) / sizeof( unsigned );
640 }
641
642 if (not_first_arg)
643 _debug_printf( ", " );
644 else
645 _debug_printf( " " );
646 dump_srcreg( srcreg, &indreg, &di );
647 not_first_arg = TRUE;
648 }
649
650 _debug_printf( "\n" );
651 }
652 }
653 }
654 }