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>
36 #include "svga_shader.h"
37 #include "svga_shader_dump.h"
38 #include "svga_shader_op.h"
39 #include "util/u_debug.h"
41 #include "../svga_hw_reg.h"
42 #include "svga3d_shaderdefs.h"
51 #define DUMP_MAX_OP_SRC 4
57 struct sh_srcreg dstind
;
58 struct sh_srcreg src
[DUMP_MAX_OP_SRC
];
59 struct sh_srcreg srcind
[DUMP_MAX_OP_SRC
];
64 dump_indent(int indent
)
68 for (i
= 0; i
< indent
; ++i
) {
73 static void dump_op( struct sh_op op
, const char *mnemonic
)
75 assert( op
.is_reg
== 0 );
78 _debug_printf("(p0) ");
82 _debug_printf( "%s", mnemonic
);
101 case SVGA3DOP_BREAKC
:
103 switch (op
.control
) {
104 case SVGA3DOPCOMP_GT
:
105 _debug_printf("_gt");
107 case SVGA3DOPCOMP_EQ
:
108 _debug_printf("_eq");
110 case SVGA3DOPCOMP_GE
:
111 _debug_printf("_ge");
113 case SVGA3DOPCOMP_LT
:
114 _debug_printf("_lt");
116 case SVGA3DOPCOMPC_NE
:
117 _debug_printf("_ne");
119 case SVGA3DOPCOMP_LE
:
120 _debug_printf("_le");
128 assert(op
.control
== 0);
133 format_reg(const char *name
,
134 const struct sh_reg reg
,
135 const struct sh_srcreg
*indreg
)
140 if (sh_srcreg_type(*indreg
) == SVGA3DREG_LOOP
) {
141 _debug_printf("%s[aL+%u]", name
, reg
.number
);
143 _debug_printf("%s[a%u.x+%u]", name
, indreg
->number
, reg
.number
);
146 _debug_printf("%s%u", name
, reg
.number
);
150 static void dump_reg( struct sh_reg reg
, struct sh_srcreg
*indreg
, const struct dump_info
*di
)
152 assert( reg
.is_reg
== 1 );
154 switch (sh_reg_type( reg
)) {
156 format_reg("r", reg
, NULL
);
159 case SVGA3DREG_INPUT
:
160 format_reg("v", reg
, indreg
);
163 case SVGA3DREG_CONST
:
164 format_reg("c", reg
, indreg
);
167 case SVGA3DREG_ADDR
: /* VS */
168 /* SVGA3DREG_TEXTURE */ /* PS */
169 assert(!reg
.relative
);
171 format_reg("t", reg
, NULL
);
173 format_reg("a", reg
, NULL
);
177 case SVGA3DREG_RASTOUT
:
178 assert(!reg
.relative
);
179 switch (reg
.number
) {
181 _debug_printf( "oPos" );
184 _debug_printf( "oFog" );
186 case 2 /*POINT_SIZE*/:
187 _debug_printf( "oPts" );
191 _debug_printf( "???" );
195 case SVGA3DREG_ATTROUT
:
196 assert( reg
.number
< 2 );
197 format_reg("oD", reg
, NULL
);
200 case SVGA3DREG_TEXCRDOUT
: /* VS */
201 /* SVGA3DREG_OUTPUT */ /* VS3.0+ */
202 if (!di
->is_ps
&& di
->version
>= SVGA3D_VS_30
) {
203 format_reg("o", reg
, indreg
);
205 format_reg("oT", reg
, NULL
);
209 case SVGA3DREG_COLOROUT
:
210 format_reg("oC", reg
, NULL
);
213 case SVGA3DREG_DEPTHOUT
:
214 assert(!reg
.relative
);
215 assert(reg
.number
== 0);
216 _debug_printf("oDepth");
219 case SVGA3DREG_SAMPLER
:
220 format_reg("s", reg
, NULL
);
223 case SVGA3DREG_CONSTBOOL
:
224 format_reg("b", reg
, NULL
);
227 case SVGA3DREG_CONSTINT
:
228 format_reg("i", reg
, NULL
);
232 assert(!reg
.relative
);
233 assert( reg
.number
== 0 );
234 _debug_printf( "aL" );
237 case SVGA3DREG_MISCTYPE
:
238 assert(!reg
.relative
);
239 switch (reg
.number
) {
240 case SVGA3DMISCREG_POSITION
:
241 _debug_printf("vPos");
243 case SVGA3DMISCREG_FACE
:
244 _debug_printf("vFace");
248 _debug_printf("???");
252 case SVGA3DREG_LABEL
:
253 format_reg("l", reg
, NULL
);
256 case SVGA3DREG_PREDICATE
:
257 format_reg("p", reg
, NULL
);
262 _debug_printf( "???" );
266 static void dump_cdata( struct sh_cdata cdata
)
268 _debug_printf( "%f, %f, %f, %f", cdata
.xyzw
[0], cdata
.xyzw
[1], cdata
.xyzw
[2], cdata
.xyzw
[3] );
271 static void dump_idata( struct sh_idata idata
)
273 _debug_printf( "%d, %d, %d, %d", idata
.xyzw
[0], idata
.xyzw
[1], idata
.xyzw
[2], idata
.xyzw
[3] );
276 static void dump_bdata( boolean bdata
)
278 _debug_printf( bdata
? "TRUE" : "FALSE" );
282 dump_sampleinfo(struct sh_sampleinfo sampleinfo
)
284 assert( sampleinfo
.is_reg
== 1 );
286 switch (sampleinfo
.texture_type
) {
288 _debug_printf( "_2d" );
290 case SVGA3DSAMP_2D_SHADOW
:
291 _debug_printf( "_2dshadow" );
293 case SVGA3DSAMP_CUBE
:
294 _debug_printf( "_cube" );
296 case SVGA3DSAMP_VOLUME
:
297 _debug_printf( "_volume" );
305 dump_semantic(uint usage
,
309 case SVGA3D_DECLUSAGE_POSITION
:
310 _debug_printf("_position");
312 case SVGA3D_DECLUSAGE_BLENDWEIGHT
:
313 _debug_printf("_blendweight");
315 case SVGA3D_DECLUSAGE_BLENDINDICES
:
316 _debug_printf("_blendindices");
318 case SVGA3D_DECLUSAGE_NORMAL
:
319 _debug_printf("_normal");
321 case SVGA3D_DECLUSAGE_PSIZE
:
322 _debug_printf("_psize");
324 case SVGA3D_DECLUSAGE_TEXCOORD
:
325 _debug_printf("_texcoord");
327 case SVGA3D_DECLUSAGE_TANGENT
:
328 _debug_printf("_tangent");
330 case SVGA3D_DECLUSAGE_BINORMAL
:
331 _debug_printf("_binormal");
333 case SVGA3D_DECLUSAGE_TESSFACTOR
:
334 _debug_printf("_tessfactor");
336 case SVGA3D_DECLUSAGE_POSITIONT
:
337 _debug_printf("_positiont");
339 case SVGA3D_DECLUSAGE_COLOR
:
340 _debug_printf("_color");
342 case SVGA3D_DECLUSAGE_FOG
:
343 _debug_printf("_fog");
345 case SVGA3D_DECLUSAGE_DEPTH
:
346 _debug_printf("_depth");
348 case SVGA3D_DECLUSAGE_SAMPLE
:
349 _debug_printf("_sample");
352 assert(!"Unknown usage");
353 _debug_printf("_???");
357 _debug_printf("%u", usage_index
);
362 dump_dstreg(struct sh_dstreg dstreg
,
363 struct sh_srcreg
*indreg
,
364 const struct dump_info
*di
)
368 struct sh_dstreg dstreg
;
371 memset(&u
, 0, sizeof(u
));
373 assert( (dstreg
.modifier
& (SVGA3DDSTMOD_SATURATE
| SVGA3DDSTMOD_PARTIALPRECISION
)) == dstreg
.modifier
);
375 if (dstreg
.modifier
& SVGA3DDSTMOD_SATURATE
)
376 _debug_printf( "_sat" );
377 if (dstreg
.modifier
& SVGA3DDSTMOD_PARTIALPRECISION
)
378 _debug_printf( "_pp" );
379 switch (dstreg
.shift_scale
) {
383 _debug_printf( "_x2" );
386 _debug_printf( "_x4" );
389 _debug_printf( "_x8" );
392 _debug_printf( "_d8" );
395 _debug_printf( "_d4" );
398 _debug_printf( "_d2" );
403 _debug_printf( " " );
406 dump_reg( u
.reg
, indreg
, di
);
407 if (dstreg
.write_mask
!= SVGA3DWRITEMASK_ALL
) {
408 _debug_printf( "." );
409 if (dstreg
.write_mask
& SVGA3DWRITEMASK_0
)
410 _debug_printf( "x" );
411 if (dstreg
.write_mask
& SVGA3DWRITEMASK_1
)
412 _debug_printf( "y" );
413 if (dstreg
.write_mask
& SVGA3DWRITEMASK_2
)
414 _debug_printf( "z" );
415 if (dstreg
.write_mask
& SVGA3DWRITEMASK_3
)
416 _debug_printf( "w" );
420 static void dump_srcreg( struct sh_srcreg srcreg
, struct sh_srcreg
*indreg
, const struct dump_info
*di
)
422 struct sh_reg srcreg_sh
= {0};
423 /* bit-fields carefully aligned, ensure they stay that way. */
424 STATIC_ASSERT(sizeof(struct sh_reg
) == sizeof(struct sh_srcreg
));
425 memcpy(&srcreg_sh
, &srcreg
, sizeof(srcreg_sh
));
427 switch (srcreg
.modifier
) {
428 case SVGA3DSRCMOD_NEG
:
429 case SVGA3DSRCMOD_BIASNEG
:
430 case SVGA3DSRCMOD_SIGNNEG
:
431 case SVGA3DSRCMOD_X2NEG
:
432 case SVGA3DSRCMOD_ABSNEG
:
433 _debug_printf( "-" );
435 case SVGA3DSRCMOD_COMP
:
436 _debug_printf( "1-" );
438 case SVGA3DSRCMOD_NOT
:
439 _debug_printf( "!" );
441 dump_reg(srcreg_sh
, indreg
, di
);
442 switch (srcreg
.modifier
) {
443 case SVGA3DSRCMOD_NONE
:
444 case SVGA3DSRCMOD_NEG
:
445 case SVGA3DSRCMOD_COMP
:
446 case SVGA3DSRCMOD_NOT
:
448 case SVGA3DSRCMOD_BIAS
:
449 case SVGA3DSRCMOD_BIASNEG
:
450 _debug_printf( "_bias" );
452 case SVGA3DSRCMOD_SIGN
:
453 case SVGA3DSRCMOD_SIGNNEG
:
454 _debug_printf( "_bx2" );
456 case SVGA3DSRCMOD_X2
:
457 case SVGA3DSRCMOD_X2NEG
:
458 _debug_printf( "_x2" );
460 case SVGA3DSRCMOD_DZ
:
461 _debug_printf( "_dz" );
463 case SVGA3DSRCMOD_DW
:
464 _debug_printf( "_dw" );
466 case SVGA3DSRCMOD_ABS
:
467 case SVGA3DSRCMOD_ABSNEG
:
468 _debug_printf("_abs");
473 if (srcreg
.swizzle_x
!= 0 || srcreg
.swizzle_y
!= 1 || srcreg
.swizzle_z
!= 2 || srcreg
.swizzle_w
!= 3) {
474 _debug_printf( "." );
475 if (srcreg
.swizzle_x
== srcreg
.swizzle_y
&& srcreg
.swizzle_y
== srcreg
.swizzle_z
&& srcreg
.swizzle_z
== srcreg
.swizzle_w
) {
476 _debug_printf( "%c", "xyzw"[srcreg
.swizzle_x
] );
479 _debug_printf( "%c", "xyzw"[srcreg
.swizzle_x
] );
480 _debug_printf( "%c", "xyzw"[srcreg
.swizzle_y
] );
481 _debug_printf( "%c", "xyzw"[srcreg
.swizzle_z
] );
482 _debug_printf( "%c", "xyzw"[srcreg
.swizzle_w
] );
488 parse_op(struct dump_info
*di
,
496 assert(num_dst
<= 1);
497 assert(num_src
<= DUMP_MAX_OP_SRC
);
499 op
->op
= *(struct sh_op
*)*token
;
500 *token
+= sizeof(struct sh_op
) / sizeof(uint
);
503 op
->dst
= *(struct sh_dstreg
*)*token
;
504 *token
+= sizeof(struct sh_dstreg
) / sizeof(uint
);
505 if (op
->dst
.relative
&&
506 (!di
->is_ps
&& di
->version
>= SVGA3D_VS_30
)) {
507 op
->dstind
= *(struct sh_srcreg
*)*token
;
508 *token
+= sizeof(struct sh_srcreg
) / sizeof(uint
);
512 if (op
->op
.predicated
) {
513 op
->p0
= *(struct sh_srcreg
*)*token
;
514 *token
+= sizeof(struct sh_srcreg
) / sizeof(uint
);
517 for (i
= 0; i
< num_src
; ++i
) {
518 op
->src
[i
] = *(struct sh_srcreg
*)*token
;
519 *token
+= sizeof(struct sh_srcreg
) / sizeof(uint
);
520 if (op
->src
[i
].relative
&&
521 ((!di
->is_ps
&& di
->version
>= SVGA3D_VS_20
) ||
522 (di
->is_ps
&& di
->version
>= SVGA3D_PS_30
))) {
523 op
->srcind
[i
] = *(struct sh_srcreg
*)*token
;
524 *token
+= sizeof(struct sh_srcreg
) / sizeof(uint
);
530 dump_inst(struct dump_info
*di
,
531 const unsigned **assem
,
533 const struct sh_opcode_info
*info
)
536 boolean not_first_arg
= FALSE
;
539 assert(info
->num_dst
<= 1);
541 di
->indent
-= info
->pre_dedent
;
542 dump_indent(di
->indent
);
543 di
->indent
+= info
->post_indent
;
545 dump_op(op
, info
->mnemonic
);
547 parse_op(di
, assem
, &dop
, info
->num_dst
, info
->num_src
);
548 if (info
->num_dst
> 0) {
549 dump_dstreg(dop
.dst
, &dop
.dstind
, di
);
550 not_first_arg
= TRUE
;
553 for (i
= 0; i
< info
->num_src
; i
++) {
559 dump_srcreg(dop
.src
[i
], &dop
.srcind
[i
], di
);
560 not_first_arg
= TRUE
;
568 const unsigned *assem
,
572 boolean finished
= FALSE
;
575 di
.version
= *assem
++;
576 di
.is_ps
= (di
.version
& 0xFFFF0000) == 0xFFFF0000;
581 di
.is_ps
? "ps" : "vs",
582 (di
.version
>> 8) & 0xff,
586 struct sh_op op
= *(struct sh_op
*) assem
;
591 struct sh_dcl dcl
= *(struct sh_dcl
*) assem
;
593 _debug_printf( "dcl" );
594 switch (sh_dstreg_type(dcl
.reg
)) {
595 case SVGA3DREG_INPUT
:
596 if ((di
.is_ps
&& di
.version
>= SVGA3D_PS_30
) ||
597 (!di
.is_ps
&& di
.version
>= SVGA3D_VS_30
)) {
598 dump_semantic(dcl
.u
.semantic
.usage
,
599 dcl
.u
.semantic
.usage_index
);
602 case SVGA3DREG_TEXCRDOUT
:
603 if (!di
.is_ps
&& di
.version
>= SVGA3D_VS_30
) {
604 dump_semantic(dcl
.u
.semantic
.usage
,
605 dcl
.u
.semantic
.usage_index
);
608 case SVGA3DREG_SAMPLER
:
609 dump_sampleinfo( dcl
.u
.sampleinfo
);
612 dump_dstreg(dcl
.reg
, NULL
, &di
);
613 _debug_printf( "\n" );
614 assem
+= sizeof( struct sh_dcl
) / sizeof( unsigned );
620 struct sh_defb defb
= *(struct sh_defb
*) assem
;
622 _debug_printf( "defb " );
623 dump_reg( defb
.reg
, NULL
, &di
);
624 _debug_printf( ", " );
625 dump_bdata( defb
.data
);
626 _debug_printf( "\n" );
627 assem
+= sizeof( struct sh_defb
) / sizeof( unsigned );
633 struct sh_defi defi
= *(struct sh_defi
*) assem
;
635 _debug_printf( "defi " );
636 dump_reg( defi
.reg
, NULL
, &di
);
637 _debug_printf( ", " );
638 dump_idata( defi
.idata
);
639 _debug_printf( "\n" );
640 assem
+= sizeof( struct sh_defi
) / sizeof( unsigned );
644 case SVGA3DOP_TEXCOORD
:
646 struct sh_opcode_info info
= *svga_opcode_info(op
.opcode
);
649 if (di
.version
> SVGA3D_PS_13
) {
650 assert(info
.num_src
== 0);
655 dump_inst(&di
, &assem
, op
, &info
);
661 struct sh_opcode_info info
= *svga_opcode_info(op
.opcode
);
664 if (di
.version
> SVGA3D_PS_13
) {
665 assert(info
.num_src
== 0);
667 if (di
.version
> SVGA3D_PS_14
) {
669 info
.mnemonic
= "texld";
675 dump_inst(&di
, &assem
, op
, &info
);
681 struct sh_def def
= *(struct sh_def
*) assem
;
683 _debug_printf( "def " );
684 dump_reg( def
.reg
, NULL
, &di
);
685 _debug_printf( ", " );
686 dump_cdata( def
.cdata
);
687 _debug_printf( "\n" );
688 assem
+= sizeof( struct sh_def
) / sizeof( unsigned );
692 case SVGA3DOP_SINCOS
:
694 struct sh_opcode_info info
= *svga_opcode_info(op
.opcode
);
696 if ((di
.is_ps
&& di
.version
>= SVGA3D_PS_30
) ||
697 (!di
.is_ps
&& di
.version
>= SVGA3D_VS_30
)) {
698 assert(info
.num_src
== 3);
703 dump_inst(&di
, &assem
, op
, &info
);
708 _debug_printf( "phase\n" );
709 assem
+= sizeof( struct sh_op
) / sizeof( unsigned );
712 case SVGA3DOP_COMMENT
:
714 struct sh_comment comment
= *(struct sh_comment
*)assem
;
716 /* Ignore comment contents. */
717 assem
+= sizeof(struct sh_comment
) / sizeof(unsigned) + comment
.size
;
727 const struct sh_opcode_info
*info
= svga_opcode_info(op
.opcode
);
729 dump_inst(&di
, &assem
, op
, info
);