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"
43 SVGA3dShaderVersion version
;
47 static void dump_op( struct sh_op op
, const char *mnemonic
)
49 assert( op
.predicated
== 0 );
50 assert( op
.is_reg
== 0 );
54 _debug_printf( "%s", mnemonic
);
58 case SVGA3DOPCONT_PROJECT
:
61 case SVGA3DOPCONT_BIAS
:
70 static void dump_comp_op( struct sh_op op
, const char *mnemonic
)
72 assert( op
.is_reg
== 0 );
76 _debug_printf( "%s", mnemonic
);
78 case SVGA3DOPCOMP_RESERVED0
:
92 case SVGA3DOPCOMPC_NE
:
98 case SVGA3DOPCOMP_RESERVED1
:
105 static void dump_reg( struct sh_reg reg
, struct sh_srcreg
*indreg
, const struct dump_info
*di
)
107 assert( sh_reg_type( reg
) == SVGA3DREG_CONST
|| reg
.relative
== 0 );
108 assert( reg
.is_reg
== 1 );
110 switch (sh_reg_type( reg
)) {
112 _debug_printf( "r%u", reg
.number
);
115 case SVGA3DREG_INPUT
:
116 _debug_printf( "v%u", reg
.number
);
119 case SVGA3DREG_CONST
:
121 if (sh_srcreg_type( *indreg
) == SVGA3DREG_LOOP
)
122 _debug_printf( "c[aL+%u]", reg
.number
);
124 _debug_printf( "c[a%u.x+%u]", indreg
->number
, reg
.number
);
127 _debug_printf( "c%u", reg
.number
);
130 case SVGA3DREG_ADDR
: /* VS */
131 /* SVGA3DREG_TEXTURE */ /* PS */
133 _debug_printf( "t%u", reg
.number
);
135 _debug_printf( "a%u", reg
.number
);
138 case SVGA3DREG_RASTOUT
:
139 switch (reg
.number
) {
141 _debug_printf( "oPos" );
144 _debug_printf( "oFog" );
146 case 2 /*POINT_SIZE*/:
147 _debug_printf( "oPts" );
151 _debug_printf( "???" );
155 case SVGA3DREG_ATTROUT
:
156 assert( reg
.number
< 2 );
157 _debug_printf( "oD%u", reg
.number
);
160 case SVGA3DREG_TEXCRDOUT
:
161 /* SVGA3DREG_OUTPUT */
162 _debug_printf( "oT%u", reg
.number
);
165 case SVGA3DREG_COLOROUT
:
166 _debug_printf( "oC%u", reg
.number
);
169 case SVGA3DREG_DEPTHOUT
:
170 _debug_printf( "oD%u", reg
.number
);
173 case SVGA3DREG_SAMPLER
:
174 _debug_printf( "s%u", reg
.number
);
177 case SVGA3DREG_CONSTBOOL
:
178 assert( !reg
.relative
);
179 _debug_printf( "b%u", reg
.number
);
182 case SVGA3DREG_CONSTINT
:
183 assert( !reg
.relative
);
184 _debug_printf( "i%u", reg
.number
);
188 assert( reg
.number
== 0 );
189 _debug_printf( "aL" );
192 case SVGA3DREG_MISCTYPE
:
193 switch (reg
.number
) {
194 case SVGA3DMISCREG_POSITION
:
195 _debug_printf( "vPos" );
197 case SVGA3DMISCREG_FACE
:
198 _debug_printf( "vFace" );
206 case SVGA3DREG_LABEL
:
207 _debug_printf( "l%u", reg
.number
);
210 case SVGA3DREG_PREDICATE
:
211 _debug_printf( "p%u", reg
.number
);
217 _debug_printf( "???" );
221 static void dump_cdata( struct sh_cdata cdata
)
223 _debug_printf( "%f, %f, %f, %f", cdata
.xyzw
[0], cdata
.xyzw
[1], cdata
.xyzw
[2], cdata
.xyzw
[3] );
226 static void dump_idata( struct sh_idata idata
)
228 _debug_printf( "%d, %d, %d, %d", idata
.xyzw
[0], idata
.xyzw
[1], idata
.xyzw
[2], idata
.xyzw
[3] );
231 static void dump_bdata( boolean bdata
)
233 _debug_printf( bdata
? "TRUE" : "FALSE" );
236 static void dump_sampleinfo( struct ps_sampleinfo sampleinfo
)
238 switch (sampleinfo
.texture_type
) {
240 _debug_printf( "_2d" );
242 case SVGA3DSAMP_CUBE
:
243 _debug_printf( "_cube" );
245 case SVGA3DSAMP_VOLUME
:
246 _debug_printf( "_volume" );
254 static void dump_usageinfo( struct vs_semantic semantic
)
256 switch (semantic
.usage
) {
257 case SVGA3D_DECLUSAGE_POSITION
:
258 _debug_printf("_position" );
260 case SVGA3D_DECLUSAGE_BLENDWEIGHT
:
261 _debug_printf("_blendweight" );
263 case SVGA3D_DECLUSAGE_BLENDINDICES
:
264 _debug_printf("_blendindices" );
266 case SVGA3D_DECLUSAGE_NORMAL
:
267 _debug_printf("_normal" );
269 case SVGA3D_DECLUSAGE_PSIZE
:
270 _debug_printf("_psize" );
272 case SVGA3D_DECLUSAGE_TEXCOORD
:
273 _debug_printf("_texcoord");
275 case SVGA3D_DECLUSAGE_TANGENT
:
276 _debug_printf("_tangent" );
278 case SVGA3D_DECLUSAGE_BINORMAL
:
279 _debug_printf("_binormal" );
281 case SVGA3D_DECLUSAGE_TESSFACTOR
:
282 _debug_printf("_tessfactor" );
284 case SVGA3D_DECLUSAGE_POSITIONT
:
285 _debug_printf("_positiont" );
287 case SVGA3D_DECLUSAGE_COLOR
:
288 _debug_printf("_color" );
290 case SVGA3D_DECLUSAGE_FOG
:
291 _debug_printf("_fog" );
293 case SVGA3D_DECLUSAGE_DEPTH
:
294 _debug_printf("_depth" );
296 case SVGA3D_DECLUSAGE_SAMPLE
:
297 _debug_printf("_sample");
304 if (semantic
.usage_index
!= 0) {
305 _debug_printf("%d", semantic
.usage_index
);
309 static void dump_dstreg( struct sh_dstreg dstreg
, const struct dump_info
*di
)
313 struct sh_dstreg dstreg
;
316 assert( (dstreg
.modifier
& (SVGA3DDSTMOD_SATURATE
| SVGA3DDSTMOD_PARTIALPRECISION
)) == dstreg
.modifier
);
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
) {
326 _debug_printf( "_x2" );
329 _debug_printf( "_x4" );
332 _debug_printf( "_x8" );
335 _debug_printf( "_d8" );
338 _debug_printf( "_d4" );
341 _debug_printf( "_d2" );
346 _debug_printf( " " );
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" );
363 static void dump_srcreg( struct sh_srcreg srcreg
, struct sh_srcreg
*indreg
, const struct dump_info
*di
)
367 struct sh_srcreg srcreg
;
370 switch (srcreg
.modifier
) {
371 case SVGA3DSRCMOD_NEG
:
372 case SVGA3DSRCMOD_BIASNEG
:
373 case SVGA3DSRCMOD_SIGNNEG
:
374 case SVGA3DSRCMOD_X2NEG
:
375 _debug_printf( "-" );
377 case SVGA3DSRCMOD_ABS
:
378 _debug_printf( "|" );
380 case SVGA3DSRCMOD_ABSNEG
:
381 _debug_printf( "-|" );
383 case SVGA3DSRCMOD_COMP
:
384 _debug_printf( "1-" );
386 case SVGA3DSRCMOD_NOT
:
387 _debug_printf( "!" );
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
:
398 case SVGA3DSRCMOD_ABS
:
399 case SVGA3DSRCMOD_ABSNEG
:
400 _debug_printf( "|" );
402 case SVGA3DSRCMOD_BIAS
:
403 case SVGA3DSRCMOD_BIASNEG
:
404 _debug_printf( "_bias" );
406 case SVGA3DSRCMOD_SIGN
:
407 case SVGA3DSRCMOD_SIGNNEG
:
408 _debug_printf( "_bx2" );
410 case SVGA3DSRCMOD_X2
:
411 case SVGA3DSRCMOD_X2NEG
:
412 _debug_printf( "_x2" );
414 case SVGA3DSRCMOD_DZ
:
415 _debug_printf( "_dz" );
417 case SVGA3DSRCMOD_DW
:
418 _debug_printf( "_dw" );
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
] );
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
] );
439 const unsigned *assem
,
443 const unsigned *start
= assem
;
444 boolean finished
= FALSE
;
449 for (i
= 0; i
< dwords
; i
++)
450 _debug_printf(" 0x%08x,\n", assem
[i
]);
452 _debug_printf("\n\n");
455 di
.version
.value
= *assem
++;
456 di
.is_ps
= (di
.version
.type
== SVGA3D_PS_TYPE
);
460 di
.is_ps
? "ps" : "vs",
465 struct sh_op op
= *(struct sh_op
*) assem
;
467 if (assem
- start
>= dwords
) {
468 _debug_printf("... ran off end of buffer\n");
476 struct sh_dcl dcl
= *(struct sh_dcl
*) assem
;
478 _debug_printf( "dcl" );
479 if (sh_dstreg_type( dcl
.reg
) == SVGA3DREG_SAMPLER
)
480 dump_sampleinfo( dcl
.u
.ps
.sampleinfo
);
482 if (di
.version
.major
== 3 &&
483 sh_dstreg_type( dcl
.reg
) != SVGA3DREG_MISCTYPE
)
484 dump_usageinfo( dcl
.u
.vs
.semantic
);
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 );
496 struct sh_defb defb
= *(struct sh_defb
*) assem
;
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 );
509 struct sh_defi defi
= *(struct sh_defi
*) assem
;
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 );
520 case SVGA3DOP_TEXCOORD
:
522 dump_op( op
, "texcoord" );
524 struct sh_dstop dstop
= *(struct sh_dstop
*) assem
;
525 dump_dstreg( dstop
.dst
, &di
);
526 assem
+= sizeof( struct sh_dstop
) / sizeof( unsigned );
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 );
535 _debug_printf( "\n" );
541 dump_op( op
, "tex" );
543 struct sh_dstop dstop
= *(struct sh_dstop
*) assem
;
545 dump_dstreg( dstop
.dst
, &di
);
546 assem
+= sizeof( struct sh_dstop
) / sizeof( unsigned );
549 struct sh_unaryop unaryop
= *(struct sh_unaryop
*) assem
;
551 dump_dstreg( unaryop
.dst
, &di
);
552 _debug_printf( ", " );
553 dump_srcreg( unaryop
.src
, NULL
, &di
);
554 assem
+= sizeof( struct sh_unaryop
) / sizeof( unsigned );
558 struct sh_binaryop binaryop
= *(struct sh_binaryop
*) assem
;
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 );
568 _debug_printf( "\n" );
573 struct sh_def def
= *(struct sh_def
*) assem
;
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 );
585 _debug_printf( "phase\n" );
586 assem
+= sizeof( struct sh_op
) / sizeof( unsigned );
589 case SVGA3DOP_COMMENT
:
591 struct sh_comment comment
= *(struct sh_comment
*)assem
;
593 /* Ignore comment contents. */
594 assem
+= sizeof(struct sh_comment
) / sizeof(unsigned) + comment
.size
;
599 _debug_printf( "ret\n" );
600 assem
+= sizeof( struct sh_op
) / sizeof( unsigned );
604 _debug_printf( "end\n" );
610 const struct sh_opcode_info
*info
= svga_opcode_info( op
.opcode
);
612 uint num_src
= info
->num_src
+ op
.predicated
;
613 boolean not_first_arg
= FALSE
;
615 assert( info
->num_dst
<= 1 );
617 if (op
.opcode
== SVGA3DOP_SINCOS
&& di
.version
.major
< 3)
620 dump_comp_op( op
, info
->mnemonic
);
621 assem
+= sizeof( struct sh_op
) / sizeof( unsigned );
623 if (info
->num_dst
> 0) {
624 struct sh_dstreg dstreg
= *(struct sh_dstreg
*) assem
;
626 dump_dstreg( dstreg
, &di
);
627 assem
+= sizeof( struct sh_dstreg
) / sizeof( unsigned );
628 not_first_arg
= TRUE
;
631 for (i
= 0; i
< num_src
; i
++) {
632 struct sh_srcreg srcreg
;
633 struct sh_srcreg indreg
;
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 );
643 _debug_printf( ", " );
645 _debug_printf( " " );
646 dump_srcreg( srcreg
, &indreg
, &di
);
647 not_first_arg
= TRUE
;
650 _debug_printf( "\n" );