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
);