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 assert( (dstreg
.modifier
& (SVGA3DDSTMOD_SATURATE
| SVGA3DDSTMOD_PARTIALPRECISION
)) == dstreg
.modifier
);
367 if (dstreg
.modifier
& SVGA3DDSTMOD_SATURATE
)
368 _debug_printf( "_sat" );
369 if (dstreg
.modifier
& SVGA3DDSTMOD_PARTIALPRECISION
)
370 _debug_printf( "_pp" );
371 switch (dstreg
.shift_scale
) {
375 _debug_printf( "_x2" );
378 _debug_printf( "_x4" );
381 _debug_printf( "_x8" );
384 _debug_printf( "_d8" );
387 _debug_printf( "_d4" );
390 _debug_printf( "_d2" );
395 _debug_printf( " " );
398 dump_reg( u
.reg
, indreg
, di
);
399 if (dstreg
.write_mask
!= SVGA3DWRITEMASK_ALL
) {
400 _debug_printf( "." );
401 if (dstreg
.write_mask
& SVGA3DWRITEMASK_0
)
402 _debug_printf( "x" );
403 if (dstreg
.write_mask
& SVGA3DWRITEMASK_1
)
404 _debug_printf( "y" );
405 if (dstreg
.write_mask
& SVGA3DWRITEMASK_2
)
406 _debug_printf( "z" );
407 if (dstreg
.write_mask
& SVGA3DWRITEMASK_3
)
408 _debug_printf( "w" );
412 static void dump_srcreg( struct sh_srcreg srcreg
, struct sh_srcreg
*indreg
, const struct dump_info
*di
)
414 switch (srcreg
.modifier
) {
415 case SVGA3DSRCMOD_NEG
:
416 case SVGA3DSRCMOD_BIASNEG
:
417 case SVGA3DSRCMOD_SIGNNEG
:
418 case SVGA3DSRCMOD_X2NEG
:
419 case SVGA3DSRCMOD_ABSNEG
:
420 _debug_printf( "-" );
422 case SVGA3DSRCMOD_COMP
:
423 _debug_printf( "1-" );
425 case SVGA3DSRCMOD_NOT
:
426 _debug_printf( "!" );
428 dump_reg( *(struct sh_reg
*) &srcreg
, indreg
, di
);
429 switch (srcreg
.modifier
) {
430 case SVGA3DSRCMOD_NONE
:
431 case SVGA3DSRCMOD_NEG
:
432 case SVGA3DSRCMOD_COMP
:
433 case SVGA3DSRCMOD_NOT
:
435 case SVGA3DSRCMOD_BIAS
:
436 case SVGA3DSRCMOD_BIASNEG
:
437 _debug_printf( "_bias" );
439 case SVGA3DSRCMOD_SIGN
:
440 case SVGA3DSRCMOD_SIGNNEG
:
441 _debug_printf( "_bx2" );
443 case SVGA3DSRCMOD_X2
:
444 case SVGA3DSRCMOD_X2NEG
:
445 _debug_printf( "_x2" );
447 case SVGA3DSRCMOD_DZ
:
448 _debug_printf( "_dz" );
450 case SVGA3DSRCMOD_DW
:
451 _debug_printf( "_dw" );
453 case SVGA3DSRCMOD_ABS
:
454 case SVGA3DSRCMOD_ABSNEG
:
455 _debug_printf("_abs");
460 if (srcreg
.swizzle_x
!= 0 || srcreg
.swizzle_y
!= 1 || srcreg
.swizzle_z
!= 2 || srcreg
.swizzle_w
!= 3) {
461 _debug_printf( "." );
462 if (srcreg
.swizzle_x
== srcreg
.swizzle_y
&& srcreg
.swizzle_y
== srcreg
.swizzle_z
&& srcreg
.swizzle_z
== srcreg
.swizzle_w
) {
463 _debug_printf( "%c", "xyzw"[srcreg
.swizzle_x
] );
466 _debug_printf( "%c", "xyzw"[srcreg
.swizzle_x
] );
467 _debug_printf( "%c", "xyzw"[srcreg
.swizzle_y
] );
468 _debug_printf( "%c", "xyzw"[srcreg
.swizzle_z
] );
469 _debug_printf( "%c", "xyzw"[srcreg
.swizzle_w
] );
475 parse_op(struct dump_info
*di
,
483 assert(num_dst
<= 1);
484 assert(num_src
<= DUMP_MAX_OP_SRC
);
486 op
->op
= *(struct sh_op
*)*token
;
487 *token
+= sizeof(struct sh_op
) / sizeof(uint
);
490 op
->dst
= *(struct sh_dstreg
*)*token
;
491 *token
+= sizeof(struct sh_dstreg
) / sizeof(uint
);
492 if (op
->dst
.relative
&&
493 (!di
->is_ps
&& di
->version
>= SVGA3D_VS_30
)) {
494 op
->dstind
= *(struct sh_srcreg
*)*token
;
495 *token
+= sizeof(struct sh_srcreg
) / sizeof(uint
);
499 if (op
->op
.predicated
) {
500 op
->p0
= *(struct sh_srcreg
*)*token
;
501 *token
+= sizeof(struct sh_srcreg
) / sizeof(uint
);
504 for (i
= 0; i
< num_src
; ++i
) {
505 op
->src
[i
] = *(struct sh_srcreg
*)*token
;
506 *token
+= sizeof(struct sh_srcreg
) / sizeof(uint
);
507 if (op
->src
[i
].relative
&&
508 ((!di
->is_ps
&& di
->version
>= SVGA3D_VS_20
) ||
509 (di
->is_ps
&& di
->version
>= SVGA3D_PS_30
))) {
510 op
->srcind
[i
] = *(struct sh_srcreg
*)*token
;
511 *token
+= sizeof(struct sh_srcreg
) / sizeof(uint
);
517 dump_inst(struct dump_info
*di
,
518 const unsigned **assem
,
520 const struct sh_opcode_info
*info
)
523 boolean not_first_arg
= FALSE
;
526 assert(info
->num_dst
<= 1);
528 di
->indent
-= info
->pre_dedent
;
529 dump_indent(di
->indent
);
530 di
->indent
+= info
->post_indent
;
532 dump_op(op
, info
->mnemonic
);
534 parse_op(di
, assem
, &dop
, info
->num_dst
, info
->num_src
);
535 if (info
->num_dst
> 0) {
536 dump_dstreg(dop
.dst
, &dop
.dstind
, di
);
537 not_first_arg
= TRUE
;
540 for (i
= 0; i
< info
->num_src
; i
++) {
546 dump_srcreg(dop
.src
[i
], &dop
.srcind
[i
], di
);
547 not_first_arg
= TRUE
;
555 const unsigned *assem
,
559 boolean finished
= FALSE
;
562 di
.version
= *assem
++;
563 di
.is_ps
= (di
.version
& 0xFFFF0000) == 0xFFFF0000;
568 di
.is_ps
? "ps" : "vs",
569 (di
.version
>> 8) & 0xff,
573 struct sh_op op
= *(struct sh_op
*) assem
;
578 struct sh_dcl dcl
= *(struct sh_dcl
*) assem
;
580 _debug_printf( "dcl" );
581 switch (sh_dstreg_type(dcl
.reg
)) {
582 case SVGA3DREG_INPUT
:
583 if ((di
.is_ps
&& di
.version
>= SVGA3D_PS_30
) ||
584 (!di
.is_ps
&& di
.version
>= SVGA3D_VS_30
)) {
585 dump_semantic(dcl
.u
.semantic
.usage
,
586 dcl
.u
.semantic
.usage_index
);
589 case SVGA3DREG_TEXCRDOUT
:
590 if (!di
.is_ps
&& di
.version
>= SVGA3D_VS_30
) {
591 dump_semantic(dcl
.u
.semantic
.usage
,
592 dcl
.u
.semantic
.usage_index
);
595 case SVGA3DREG_SAMPLER
:
596 dump_sampleinfo( dcl
.u
.sampleinfo
);
599 dump_dstreg(dcl
.reg
, NULL
, &di
);
600 _debug_printf( "\n" );
601 assem
+= sizeof( struct sh_dcl
) / sizeof( unsigned );
607 struct sh_defb defb
= *(struct sh_defb
*) assem
;
609 _debug_printf( "defb " );
610 dump_reg( defb
.reg
, NULL
, &di
);
611 _debug_printf( ", " );
612 dump_bdata( defb
.data
);
613 _debug_printf( "\n" );
614 assem
+= sizeof( struct sh_defb
) / sizeof( unsigned );
620 struct sh_defi defi
= *(struct sh_defi
*) assem
;
622 _debug_printf( "defi " );
623 dump_reg( defi
.reg
, NULL
, &di
);
624 _debug_printf( ", " );
625 dump_idata( defi
.idata
);
626 _debug_printf( "\n" );
627 assem
+= sizeof( struct sh_defi
) / sizeof( unsigned );
631 case SVGA3DOP_TEXCOORD
:
633 struct sh_opcode_info info
= *svga_opcode_info(op
.opcode
);
636 if (di
.version
> SVGA3D_PS_13
) {
637 assert(info
.num_src
== 0);
642 dump_inst(&di
, &assem
, op
, &info
);
648 struct sh_opcode_info info
= *svga_opcode_info(op
.opcode
);
651 if (di
.version
> SVGA3D_PS_13
) {
652 assert(info
.num_src
== 0);
654 if (di
.version
> SVGA3D_PS_14
) {
656 info
.mnemonic
= "texld";
662 dump_inst(&di
, &assem
, op
, &info
);
668 struct sh_def def
= *(struct sh_def
*) assem
;
670 _debug_printf( "def " );
671 dump_reg( def
.reg
, NULL
, &di
);
672 _debug_printf( ", " );
673 dump_cdata( def
.cdata
);
674 _debug_printf( "\n" );
675 assem
+= sizeof( struct sh_def
) / sizeof( unsigned );
679 case SVGA3DOP_SINCOS
:
681 struct sh_opcode_info info
= *svga_opcode_info(op
.opcode
);
683 if ((di
.is_ps
&& di
.version
>= SVGA3D_PS_30
) ||
684 (!di
.is_ps
&& di
.version
>= SVGA3D_VS_30
)) {
685 assert(info
.num_src
== 3);
690 dump_inst(&di
, &assem
, op
, &info
);
695 _debug_printf( "phase\n" );
696 assem
+= sizeof( struct sh_op
) / sizeof( unsigned );
699 case SVGA3DOP_COMMENT
:
701 struct sh_comment comment
= *(struct sh_comment
*)assem
;
703 /* Ignore comment contents. */
704 assem
+= sizeof(struct sh_comment
) / sizeof(unsigned) + comment
.size
;
714 const struct sh_opcode_info
*info
= svga_opcode_info(op
.opcode
);
716 dump_inst(&di
, &assem
, op
, info
);