1 /**********************************************************
2 * Copyright 2008-2009 VMware, Inc. All rights reserved.
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:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
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
24 **********************************************************/
28 * SVGA Shader Dump Facilities
30 * @author Michal Krol <michal@vmware.com>
33 #include "svga_shader.h"
34 #include "svga_shader_dump.h"
35 #include "svga_shader_op.h"
36 #include "util/u_debug.h"
38 #include "../svga_hw_reg.h"
39 #include "svga3d_shaderdefs.h"
48 #define DUMP_MAX_OP_SRC 4
54 struct sh_srcreg dstind;
55 struct sh_srcreg src[DUMP_MAX_OP_SRC];
56 struct sh_srcreg srcind[DUMP_MAX_OP_SRC];
61 dump_indent(int indent)
65 for (i = 0; i < indent; ++i) {
70 static void dump_op( struct sh_op op, const char *mnemonic )
72 assert( op.is_reg == 0 );
75 _debug_printf("(p0) ");
79 _debug_printf( "%s", mnemonic );
100 switch (op.control) {
101 case SVGA3DOPCOMP_GT:
102 _debug_printf("_gt");
104 case SVGA3DOPCOMP_EQ:
105 _debug_printf("_eq");
107 case SVGA3DOPCOMP_GE:
108 _debug_printf("_ge");
110 case SVGA3DOPCOMP_LT:
111 _debug_printf("_lt");
113 case SVGA3DOPCOMPC_NE:
114 _debug_printf("_ne");
116 case SVGA3DOPCOMP_LE:
117 _debug_printf("_le");
125 assert(op.control == 0);
130 format_reg(const char *name,
131 const struct sh_reg reg,
132 const struct sh_srcreg *indreg)
137 if (sh_srcreg_type(*indreg) == SVGA3DREG_LOOP) {
138 _debug_printf("%s[aL+%u]", name, reg.number);
140 _debug_printf("%s[a%u.x+%u]", name, indreg->number, reg.number);
143 _debug_printf("%s%u", name, reg.number);
147 static void dump_reg( struct sh_reg reg, struct sh_srcreg *indreg, const struct dump_info *di )
149 assert( reg.is_reg == 1 );
151 switch (sh_reg_type( reg )) {
153 format_reg("r", reg, NULL);
156 case SVGA3DREG_INPUT:
157 format_reg("v", reg, indreg);
160 case SVGA3DREG_CONST:
161 format_reg("c", reg, indreg);
164 case SVGA3DREG_ADDR: /* VS */
165 /* SVGA3DREG_TEXTURE */ /* PS */
166 assert(!reg.relative);
168 format_reg("t", reg, NULL);
170 format_reg("a", reg, NULL);
174 case SVGA3DREG_RASTOUT:
175 assert(!reg.relative);
176 switch (reg.number) {
178 _debug_printf( "oPos" );
181 _debug_printf( "oFog" );
183 case 2 /*POINT_SIZE*/:
184 _debug_printf( "oPts" );
188 _debug_printf( "???" );
192 case SVGA3DREG_ATTROUT:
193 assert( reg.number < 2 );
194 format_reg("oD", reg, NULL);
197 case SVGA3DREG_TEXCRDOUT: /* VS */
198 /* SVGA3DREG_OUTPUT */ /* VS3.0+ */
199 if (!di->is_ps && di->version >= SVGA3D_VS_30) {
200 format_reg("o", reg, indreg);
202 format_reg("oT", reg, NULL);
206 case SVGA3DREG_COLOROUT:
207 format_reg("oC", reg, NULL);
210 case SVGA3DREG_DEPTHOUT:
211 assert(!reg.relative);
212 assert(reg.number == 0);
213 _debug_printf("oDepth");
216 case SVGA3DREG_SAMPLER:
217 format_reg("s", reg, NULL);
220 case SVGA3DREG_CONSTBOOL:
221 format_reg("b", reg, NULL);
224 case SVGA3DREG_CONSTINT:
225 format_reg("i", reg, NULL);
229 assert(!reg.relative);
230 assert( reg.number == 0 );
231 _debug_printf( "aL" );
234 case SVGA3DREG_MISCTYPE:
235 assert(!reg.relative);
236 switch (reg.number) {
237 case SVGA3DMISCREG_POSITION:
238 _debug_printf("vPos");
240 case SVGA3DMISCREG_FACE:
241 _debug_printf("vFace");
245 _debug_printf("???");
249 case SVGA3DREG_LABEL:
250 format_reg("l", reg, NULL);
253 case SVGA3DREG_PREDICATE:
254 format_reg("p", reg, NULL);
259 _debug_printf( "???" );
263 static void dump_cdata( struct sh_cdata cdata )
265 _debug_printf( "%f, %f, %f, %f", cdata.xyzw[0], cdata.xyzw[1], cdata.xyzw[2], cdata.xyzw[3] );
268 static void dump_idata( struct sh_idata idata )
270 _debug_printf( "%d, %d, %d, %d", idata.xyzw[0], idata.xyzw[1], idata.xyzw[2], idata.xyzw[3] );
273 static void dump_bdata( boolean bdata )
275 _debug_printf( bdata ? "TRUE" : "FALSE" );
279 dump_sampleinfo(struct sh_sampleinfo sampleinfo)
281 assert( sampleinfo.is_reg == 1 );
283 switch (sampleinfo.texture_type) {
285 _debug_printf( "_2d" );
287 case SVGA3DSAMP_CUBE:
288 _debug_printf( "_cube" );
290 case SVGA3DSAMP_VOLUME:
291 _debug_printf( "_volume" );
299 dump_semantic(uint usage,
303 case SVGA3D_DECLUSAGE_POSITION:
304 _debug_printf("_position");
306 case SVGA3D_DECLUSAGE_BLENDWEIGHT:
307 _debug_printf("_blendweight");
309 case SVGA3D_DECLUSAGE_BLENDINDICES:
310 _debug_printf("_blendindices");
312 case SVGA3D_DECLUSAGE_NORMAL:
313 _debug_printf("_normal");
315 case SVGA3D_DECLUSAGE_PSIZE:
316 _debug_printf("_psize");
318 case SVGA3D_DECLUSAGE_TEXCOORD:
319 _debug_printf("_texcoord");
321 case SVGA3D_DECLUSAGE_TANGENT:
322 _debug_printf("_tangent");
324 case SVGA3D_DECLUSAGE_BINORMAL:
325 _debug_printf("_binormal");
327 case SVGA3D_DECLUSAGE_TESSFACTOR:
328 _debug_printf("_tessfactor");
330 case SVGA3D_DECLUSAGE_POSITIONT:
331 _debug_printf("_positiont");
333 case SVGA3D_DECLUSAGE_COLOR:
334 _debug_printf("_color");
336 case SVGA3D_DECLUSAGE_FOG:
337 _debug_printf("_fog");
339 case SVGA3D_DECLUSAGE_DEPTH:
340 _debug_printf("_depth");
342 case SVGA3D_DECLUSAGE_SAMPLE:
343 _debug_printf("_sample");
346 assert(!"Unknown usage");
347 _debug_printf("_???");
351 _debug_printf("%u", usage_index);
356 dump_dstreg(struct sh_dstreg dstreg,
357 struct sh_srcreg *indreg,
358 const struct dump_info *di)
362 struct sh_dstreg dstreg;
365 memset(&u, 0, sizeof(u));
367 assert( (dstreg.modifier & (SVGA3DDSTMOD_SATURATE | SVGA3DDSTMOD_PARTIALPRECISION)) == dstreg.modifier );
369 if (dstreg.modifier & SVGA3DDSTMOD_SATURATE)
370 _debug_printf( "_sat" );
371 if (dstreg.modifier & SVGA3DDSTMOD_PARTIALPRECISION)
372 _debug_printf( "_pp" );
373 switch (dstreg.shift_scale) {
377 _debug_printf( "_x2" );
380 _debug_printf( "_x4" );
383 _debug_printf( "_x8" );
386 _debug_printf( "_d8" );
389 _debug_printf( "_d4" );
392 _debug_printf( "_d2" );
397 _debug_printf( " " );
400 dump_reg( u.reg, indreg, di);
401 if (dstreg.write_mask != SVGA3DWRITEMASK_ALL) {
402 _debug_printf( "." );
403 if (dstreg.write_mask & SVGA3DWRITEMASK_0)
404 _debug_printf( "x" );
405 if (dstreg.write_mask & SVGA3DWRITEMASK_1)
406 _debug_printf( "y" );
407 if (dstreg.write_mask & SVGA3DWRITEMASK_2)
408 _debug_printf( "z" );
409 if (dstreg.write_mask & SVGA3DWRITEMASK_3)
410 _debug_printf( "w" );
414 static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, const struct dump_info *di )
416 switch (srcreg.modifier) {
417 case SVGA3DSRCMOD_NEG:
418 case SVGA3DSRCMOD_BIASNEG:
419 case SVGA3DSRCMOD_SIGNNEG:
420 case SVGA3DSRCMOD_X2NEG:
421 case SVGA3DSRCMOD_ABSNEG:
422 _debug_printf( "-" );
424 case SVGA3DSRCMOD_COMP:
425 _debug_printf( "1-" );
427 case SVGA3DSRCMOD_NOT:
428 _debug_printf( "!" );
430 dump_reg( *(struct sh_reg *) &srcreg, indreg, di );
431 switch (srcreg.modifier) {
432 case SVGA3DSRCMOD_NONE:
433 case SVGA3DSRCMOD_NEG:
434 case SVGA3DSRCMOD_COMP:
435 case SVGA3DSRCMOD_NOT:
437 case SVGA3DSRCMOD_BIAS:
438 case SVGA3DSRCMOD_BIASNEG:
439 _debug_printf( "_bias" );
441 case SVGA3DSRCMOD_SIGN:
442 case SVGA3DSRCMOD_SIGNNEG:
443 _debug_printf( "_bx2" );
445 case SVGA3DSRCMOD_X2:
446 case SVGA3DSRCMOD_X2NEG:
447 _debug_printf( "_x2" );
449 case SVGA3DSRCMOD_DZ:
450 _debug_printf( "_dz" );
452 case SVGA3DSRCMOD_DW:
453 _debug_printf( "_dw" );
455 case SVGA3DSRCMOD_ABS:
456 case SVGA3DSRCMOD_ABSNEG:
457 _debug_printf("_abs");
462 if (srcreg.swizzle_x != 0 || srcreg.swizzle_y != 1 || srcreg.swizzle_z != 2 || srcreg.swizzle_w != 3) {
463 _debug_printf( "." );
464 if (srcreg.swizzle_x == srcreg.swizzle_y && srcreg.swizzle_y == srcreg.swizzle_z && srcreg.swizzle_z == srcreg.swizzle_w) {
465 _debug_printf( "%c", "xyzw"[srcreg.swizzle_x] );
468 _debug_printf( "%c", "xyzw"[srcreg.swizzle_x] );
469 _debug_printf( "%c", "xyzw"[srcreg.swizzle_y] );
470 _debug_printf( "%c", "xyzw"[srcreg.swizzle_z] );
471 _debug_printf( "%c", "xyzw"[srcreg.swizzle_w] );
477 parse_op(struct dump_info *di,
485 assert(num_dst <= 1);
486 assert(num_src <= DUMP_MAX_OP_SRC);
488 op->op = *(struct sh_op *)*token;
489 *token += sizeof(struct sh_op) / sizeof(uint);
492 op->dst = *(struct sh_dstreg *)*token;
493 *token += sizeof(struct sh_dstreg) / sizeof(uint);
494 if (op->dst.relative &&
495 (!di->is_ps && di->version >= SVGA3D_VS_30)) {
496 op->dstind = *(struct sh_srcreg *)*token;
497 *token += sizeof(struct sh_srcreg) / sizeof(uint);
501 if (op->op.predicated) {
502 op->p0 = *(struct sh_srcreg *)*token;
503 *token += sizeof(struct sh_srcreg) / sizeof(uint);
506 for (i = 0; i < num_src; ++i) {
507 op->src[i] = *(struct sh_srcreg *)*token;
508 *token += sizeof(struct sh_srcreg) / sizeof(uint);
509 if (op->src[i].relative &&
510 ((!di->is_ps && di->version >= SVGA3D_VS_20) ||
511 (di->is_ps && di->version >= SVGA3D_PS_30))) {
512 op->srcind[i] = *(struct sh_srcreg *)*token;
513 *token += sizeof(struct sh_srcreg) / sizeof(uint);
519 dump_inst(struct dump_info *di,
520 const unsigned **assem,
522 const struct sh_opcode_info *info)
525 boolean not_first_arg = FALSE;
528 assert(info->num_dst <= 1);
530 di->indent -= info->pre_dedent;
531 dump_indent(di->indent);
532 di->indent += info->post_indent;
534 dump_op(op, info->mnemonic);
536 parse_op(di, assem, &dop, info->num_dst, info->num_src);
537 if (info->num_dst > 0) {
538 dump_dstreg(dop.dst, &dop.dstind, di);
539 not_first_arg = TRUE;
542 for (i = 0; i < info->num_src; i++) {
548 dump_srcreg(dop.src[i], &dop.srcind[i], di);
549 not_first_arg = TRUE;
557 const unsigned *assem,
561 boolean finished = FALSE;
564 di.version = *assem++;
565 di.is_ps = (di.version & 0xFFFF0000) == 0xFFFF0000;
570 di.is_ps ? "ps" : "vs",
571 (di.version >> 8) & 0xff,
575 struct sh_op op = *(struct sh_op *) assem;
580 struct sh_dcl dcl = *(struct sh_dcl *) assem;
582 _debug_printf( "dcl" );
583 switch (sh_dstreg_type(dcl.reg)) {
584 case SVGA3DREG_INPUT:
585 if ((di.is_ps && di.version >= SVGA3D_PS_30) ||
586 (!di.is_ps && di.version >= SVGA3D_VS_30)) {
587 dump_semantic(dcl.u.semantic.usage,
588 dcl.u.semantic.usage_index);
591 case SVGA3DREG_TEXCRDOUT:
592 if (!di.is_ps && di.version >= SVGA3D_VS_30) {
593 dump_semantic(dcl.u.semantic.usage,
594 dcl.u.semantic.usage_index);
597 case SVGA3DREG_SAMPLER:
598 dump_sampleinfo( dcl.u.sampleinfo );
601 dump_dstreg(dcl.reg, NULL, &di);
602 _debug_printf( "\n" );
603 assem += sizeof( struct sh_dcl ) / sizeof( unsigned );
609 struct sh_defb defb = *(struct sh_defb *) assem;
611 _debug_printf( "defb " );
612 dump_reg( defb.reg, NULL, &di );
613 _debug_printf( ", " );
614 dump_bdata( defb.data );
615 _debug_printf( "\n" );
616 assem += sizeof( struct sh_defb ) / sizeof( unsigned );
622 struct sh_defi defi = *(struct sh_defi *) assem;
624 _debug_printf( "defi " );
625 dump_reg( defi.reg, NULL, &di );
626 _debug_printf( ", " );
627 dump_idata( defi.idata );
628 _debug_printf( "\n" );
629 assem += sizeof( struct sh_defi ) / sizeof( unsigned );
633 case SVGA3DOP_TEXCOORD:
635 struct sh_opcode_info info = *svga_opcode_info(op.opcode);
638 if (di.version > SVGA3D_PS_13) {
639 assert(info.num_src == 0);
644 dump_inst(&di, &assem, op, &info);
650 struct sh_opcode_info info = *svga_opcode_info(op.opcode);
653 if (di.version > SVGA3D_PS_13) {
654 assert(info.num_src == 0);
656 if (di.version > SVGA3D_PS_14) {
658 info.mnemonic = "texld";
664 dump_inst(&di, &assem, op, &info);
670 struct sh_def def = *(struct sh_def *) assem;
672 _debug_printf( "def " );
673 dump_reg( def.reg, NULL, &di );
674 _debug_printf( ", " );
675 dump_cdata( def.cdata );
676 _debug_printf( "\n" );
677 assem += sizeof( struct sh_def ) / sizeof( unsigned );
681 case SVGA3DOP_SINCOS:
683 struct sh_opcode_info info = *svga_opcode_info(op.opcode);
685 if ((di.is_ps && di.version >= SVGA3D_PS_30) ||
686 (!di.is_ps && di.version >= SVGA3D_VS_30)) {
687 assert(info.num_src == 3);
692 dump_inst(&di, &assem, op, &info);
697 _debug_printf( "phase\n" );
698 assem += sizeof( struct sh_op ) / sizeof( unsigned );
701 case SVGA3DOP_COMMENT:
703 struct sh_comment comment = *(struct sh_comment *)assem;
705 /* Ignore comment contents. */
706 assem += sizeof(struct sh_comment) / sizeof(unsigned) + comment.size;
716 const struct sh_opcode_info *info = svga_opcode_info(op.opcode);
718 dump_inst(&di, &assem, op, info);