Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /************************************************************************** |
2 | * |
||
3 | * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
||
4 | * All Rights Reserved. |
||
5 | * |
||
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
7 | * copy of this software and associated documentation files (the |
||
8 | * "Software"), to deal in the Software without restriction, including |
||
9 | * without limitation the rights to use, copy, modify, merge, publish, |
||
10 | * distribute, sub license, and/or sell copies of the Software, and to |
||
11 | * permit persons to whom the Software is furnished to do so, subject to |
||
12 | * the following conditions: |
||
13 | * |
||
14 | * The above copyright notice and this permission notice (including the |
||
15 | * next paragraph) shall be included in all copies or substantial portions |
||
16 | * of the Software. |
||
17 | * |
||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
||
21 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR |
||
22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||
23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||
24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
25 | * |
||
26 | **************************************************************************/ |
||
27 | |||
28 | #include "util/u_debug.h" |
||
29 | #include "util/u_string.h" |
||
30 | #include "util/u_math.h" |
||
31 | #include "util/u_memory.h" |
||
32 | #include "tgsi_dump.h" |
||
33 | #include "tgsi_info.h" |
||
34 | #include "tgsi_iterate.h" |
||
35 | #include "tgsi_strings.h" |
||
36 | |||
37 | |||
38 | /** Number of spaces to indent for IF/LOOP/etc */ |
||
39 | static const int indent_spaces = 3; |
||
40 | |||
41 | |||
42 | struct dump_ctx |
||
43 | { |
||
44 | struct tgsi_iterate_context iter; |
||
45 | |||
46 | uint instno; |
||
47 | uint immno; |
||
48 | int indent; |
||
49 | |||
50 | uint indentation; |
||
51 | |||
52 | void (*dump_printf)(struct dump_ctx *ctx, const char *format, ...); |
||
53 | }; |
||
54 | |||
55 | static void |
||
56 | dump_ctx_printf(struct dump_ctx *ctx, const char *format, ...) |
||
57 | { |
||
58 | va_list ap; |
||
59 | (void)ctx; |
||
60 | va_start(ap, format); |
||
61 | _debug_vprintf(format, ap); |
||
62 | va_end(ap); |
||
63 | } |
||
64 | |||
65 | static void |
||
66 | dump_enum( |
||
67 | struct dump_ctx *ctx, |
||
68 | uint e, |
||
69 | const char **enums, |
||
70 | uint enum_count ) |
||
71 | { |
||
72 | if (e >= enum_count) |
||
73 | ctx->dump_printf( ctx, "%u", e ); |
||
74 | else |
||
75 | ctx->dump_printf( ctx, "%s", enums[e] ); |
||
76 | } |
||
77 | |||
78 | #define EOL() ctx->dump_printf( ctx, "\n" ) |
||
79 | #define TXT(S) ctx->dump_printf( ctx, "%s", S ) |
||
80 | #define CHR(C) ctx->dump_printf( ctx, "%c", C ) |
||
81 | #define UIX(I) ctx->dump_printf( ctx, "0x%x", I ) |
||
82 | #define UID(I) ctx->dump_printf( ctx, "%u", I ) |
||
83 | #define INSTID(I) ctx->dump_printf( ctx, "% 3u", I ) |
||
84 | #define SID(I) ctx->dump_printf( ctx, "%d", I ) |
||
85 | #define FLT(F) ctx->dump_printf( ctx, "%10.4f", F ) |
||
86 | #define ENM(E,ENUMS) dump_enum( ctx, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) |
||
87 | |||
88 | const char * |
||
89 | tgsi_swizzle_names[4] = |
||
90 | { |
||
91 | "x", |
||
92 | "y", |
||
93 | "z", |
||
94 | "w" |
||
95 | }; |
||
96 | |||
97 | static void |
||
98 | _dump_register_src( |
||
99 | struct dump_ctx *ctx, |
||
100 | const struct tgsi_full_src_register *src ) |
||
101 | { |
||
102 | TXT(tgsi_file_name(src->Register.File)); |
||
103 | if (src->Register.Dimension) { |
||
104 | if (src->Dimension.Indirect) { |
||
105 | CHR( '[' ); |
||
106 | TXT(tgsi_file_name(src->DimIndirect.File)); |
||
107 | CHR( '[' ); |
||
108 | SID( src->DimIndirect.Index ); |
||
109 | TXT( "]." ); |
||
110 | ENM( src->DimIndirect.Swizzle, tgsi_swizzle_names ); |
||
111 | if (src->Dimension.Index != 0) { |
||
112 | if (src->Dimension.Index > 0) |
||
113 | CHR( '+' ); |
||
114 | SID( src->Dimension.Index ); |
||
115 | } |
||
116 | CHR( ']' ); |
||
117 | if (src->DimIndirect.ArrayID) { |
||
118 | CHR( '(' ); |
||
119 | SID( src->DimIndirect.ArrayID ); |
||
120 | CHR( ')' ); |
||
121 | } |
||
122 | } else { |
||
123 | CHR('['); |
||
124 | SID(src->Dimension.Index); |
||
125 | CHR(']'); |
||
126 | } |
||
127 | } |
||
128 | if (src->Register.Indirect) { |
||
129 | CHR( '[' ); |
||
130 | TXT(tgsi_file_name(src->Indirect.File)); |
||
131 | CHR( '[' ); |
||
132 | SID( src->Indirect.Index ); |
||
133 | TXT( "]." ); |
||
134 | ENM( src->Indirect.Swizzle, tgsi_swizzle_names ); |
||
135 | if (src->Register.Index != 0) { |
||
136 | if (src->Register.Index > 0) |
||
137 | CHR( '+' ); |
||
138 | SID( src->Register.Index ); |
||
139 | } |
||
140 | CHR( ']' ); |
||
141 | if (src->Indirect.ArrayID) { |
||
142 | CHR( '(' ); |
||
143 | SID( src->Indirect.ArrayID ); |
||
144 | CHR( ')' ); |
||
145 | } |
||
146 | } else { |
||
147 | CHR( '[' ); |
||
148 | SID( src->Register.Index ); |
||
149 | CHR( ']' ); |
||
150 | } |
||
151 | } |
||
152 | |||
153 | |||
154 | static void |
||
155 | _dump_register_dst( |
||
156 | struct dump_ctx *ctx, |
||
157 | const struct tgsi_full_dst_register *dst ) |
||
158 | { |
||
159 | TXT(tgsi_file_name(dst->Register.File)); |
||
160 | if (dst->Register.Dimension) { |
||
161 | if (dst->Dimension.Indirect) { |
||
162 | CHR( '[' ); |
||
163 | TXT(tgsi_file_name(dst->DimIndirect.File)); |
||
164 | CHR( '[' ); |
||
165 | SID( dst->DimIndirect.Index ); |
||
166 | TXT( "]." ); |
||
167 | ENM( dst->DimIndirect.Swizzle, tgsi_swizzle_names ); |
||
168 | if (dst->Dimension.Index != 0) { |
||
169 | if (dst->Dimension.Index > 0) |
||
170 | CHR( '+' ); |
||
171 | SID( dst->Dimension.Index ); |
||
172 | } |
||
173 | CHR( ']' ); |
||
174 | if (dst->DimIndirect.ArrayID) { |
||
175 | CHR( '(' ); |
||
176 | SID( dst->DimIndirect.ArrayID ); |
||
177 | CHR( ')' ); |
||
178 | } |
||
179 | } else { |
||
180 | CHR('['); |
||
181 | SID(dst->Dimension.Index); |
||
182 | CHR(']'); |
||
183 | } |
||
184 | } |
||
185 | if (dst->Register.Indirect) { |
||
186 | CHR( '[' ); |
||
187 | TXT(tgsi_file_name(dst->Indirect.File)); |
||
188 | CHR( '[' ); |
||
189 | SID( dst->Indirect.Index ); |
||
190 | TXT( "]." ); |
||
191 | ENM( dst->Indirect.Swizzle, tgsi_swizzle_names ); |
||
192 | if (dst->Register.Index != 0) { |
||
193 | if (dst->Register.Index > 0) |
||
194 | CHR( '+' ); |
||
195 | SID( dst->Register.Index ); |
||
196 | } |
||
197 | CHR( ']' ); |
||
198 | if (dst->Indirect.ArrayID) { |
||
199 | CHR( '(' ); |
||
200 | SID( dst->Indirect.ArrayID ); |
||
201 | CHR( ')' ); |
||
202 | } |
||
203 | } else { |
||
204 | CHR( '[' ); |
||
205 | SID( dst->Register.Index ); |
||
206 | CHR( ']' ); |
||
207 | } |
||
208 | } |
||
209 | static void |
||
210 | _dump_writemask( |
||
211 | struct dump_ctx *ctx, |
||
212 | uint writemask ) |
||
213 | { |
||
214 | if (writemask != TGSI_WRITEMASK_XYZW) { |
||
215 | CHR( '.' ); |
||
216 | if (writemask & TGSI_WRITEMASK_X) |
||
217 | CHR( 'x' ); |
||
218 | if (writemask & TGSI_WRITEMASK_Y) |
||
219 | CHR( 'y' ); |
||
220 | if (writemask & TGSI_WRITEMASK_Z) |
||
221 | CHR( 'z' ); |
||
222 | if (writemask & TGSI_WRITEMASK_W) |
||
223 | CHR( 'w' ); |
||
224 | } |
||
225 | } |
||
226 | |||
227 | static void |
||
228 | dump_imm_data(struct tgsi_iterate_context *iter, |
||
229 | union tgsi_immediate_data *data, |
||
230 | unsigned num_tokens, |
||
231 | unsigned data_type) |
||
232 | { |
||
233 | struct dump_ctx *ctx = (struct dump_ctx *)iter; |
||
234 | unsigned i ; |
||
235 | |||
236 | TXT( " {" ); |
||
237 | |||
238 | assert( num_tokens <= 4 ); |
||
239 | for (i = 0; i < num_tokens; i++) { |
||
240 | switch (data_type) { |
||
241 | case TGSI_IMM_FLOAT32: |
||
242 | FLT( data[i].Float ); |
||
243 | break; |
||
244 | case TGSI_IMM_UINT32: |
||
245 | UID(data[i].Uint); |
||
246 | break; |
||
247 | case TGSI_IMM_INT32: |
||
248 | SID(data[i].Int); |
||
249 | break; |
||
250 | default: |
||
251 | assert( 0 ); |
||
252 | } |
||
253 | |||
254 | if (i < num_tokens - 1) |
||
255 | TXT( ", " ); |
||
256 | } |
||
257 | TXT( "}" ); |
||
258 | } |
||
259 | |||
260 | static boolean |
||
261 | iter_declaration( |
||
262 | struct tgsi_iterate_context *iter, |
||
263 | struct tgsi_full_declaration *decl ) |
||
264 | { |
||
265 | struct dump_ctx *ctx = (struct dump_ctx *)iter; |
||
266 | |||
267 | TXT( "DCL " ); |
||
268 | |||
269 | TXT(tgsi_file_name(decl->Declaration.File)); |
||
270 | |||
271 | /* all geometry shader inputs are two dimensional */ |
||
272 | if (decl->Declaration.File == TGSI_FILE_INPUT && |
||
273 | iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) { |
||
274 | TXT("[]"); |
||
275 | } |
||
276 | |||
277 | if (decl->Declaration.Dimension) { |
||
278 | CHR('['); |
||
279 | SID(decl->Dim.Index2D); |
||
280 | CHR(']'); |
||
281 | } |
||
282 | |||
283 | CHR('['); |
||
284 | SID(decl->Range.First); |
||
285 | if (decl->Range.First != decl->Range.Last) { |
||
286 | TXT(".."); |
||
287 | SID(decl->Range.Last); |
||
288 | } |
||
289 | CHR(']'); |
||
290 | |||
291 | _dump_writemask( |
||
292 | ctx, |
||
293 | decl->Declaration.UsageMask ); |
||
294 | |||
295 | if (decl->Declaration.Array) { |
||
296 | TXT( ", ARRAY(" ); |
||
297 | SID(decl->Array.ArrayID); |
||
298 | CHR(')'); |
||
299 | } |
||
300 | |||
301 | if (decl->Declaration.Local) |
||
302 | TXT( ", LOCAL" ); |
||
303 | |||
304 | if (decl->Declaration.Semantic) { |
||
305 | TXT( ", " ); |
||
306 | ENM( decl->Semantic.Name, tgsi_semantic_names ); |
||
307 | if (decl->Semantic.Index != 0 || |
||
308 | decl->Semantic.Name == TGSI_SEMANTIC_TEXCOORD || |
||
309 | decl->Semantic.Name == TGSI_SEMANTIC_GENERIC) { |
||
310 | CHR( '[' ); |
||
311 | UID( decl->Semantic.Index ); |
||
312 | CHR( ']' ); |
||
313 | } |
||
314 | } |
||
315 | |||
316 | if (decl->Declaration.File == TGSI_FILE_RESOURCE) { |
||
317 | TXT(", "); |
||
318 | ENM(decl->Resource.Resource, tgsi_texture_names); |
||
319 | if (decl->Resource.Writable) |
||
320 | TXT(", WR"); |
||
321 | if (decl->Resource.Raw) |
||
322 | TXT(", RAW"); |
||
323 | } |
||
324 | |||
325 | if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { |
||
326 | TXT(", "); |
||
327 | ENM(decl->SamplerView.Resource, tgsi_texture_names); |
||
328 | TXT(", "); |
||
329 | if ((decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeY) && |
||
330 | (decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeZ) && |
||
331 | (decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeW)) { |
||
332 | ENM(decl->SamplerView.ReturnTypeX, tgsi_type_names); |
||
333 | } else { |
||
334 | ENM(decl->SamplerView.ReturnTypeX, tgsi_type_names); |
||
335 | TXT(", "); |
||
336 | ENM(decl->SamplerView.ReturnTypeY, tgsi_type_names); |
||
337 | TXT(", "); |
||
338 | ENM(decl->SamplerView.ReturnTypeZ, tgsi_type_names); |
||
339 | TXT(", "); |
||
340 | ENM(decl->SamplerView.ReturnTypeW, tgsi_type_names); |
||
341 | } |
||
342 | } |
||
343 | |||
344 | if (decl->Declaration.Interpolate) { |
||
345 | if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT && |
||
346 | decl->Declaration.File == TGSI_FILE_INPUT) |
||
347 | { |
||
348 | TXT( ", " ); |
||
349 | ENM( decl->Interp.Interpolate, tgsi_interpolate_names ); |
||
350 | } |
||
351 | |||
352 | if (decl->Interp.Centroid) { |
||
353 | TXT( ", CENTROID" ); |
||
354 | } |
||
355 | |||
356 | if (decl->Interp.CylindricalWrap) { |
||
357 | TXT(", CYLWRAP_"); |
||
358 | if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_X) { |
||
359 | CHR('X'); |
||
360 | } |
||
361 | if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Y) { |
||
362 | CHR('Y'); |
||
363 | } |
||
364 | if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Z) { |
||
365 | CHR('Z'); |
||
366 | } |
||
367 | if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_W) { |
||
368 | CHR('W'); |
||
369 | } |
||
370 | } |
||
371 | } |
||
372 | |||
373 | if (decl->Declaration.Invariant) { |
||
374 | TXT( ", INVARIANT" ); |
||
375 | } |
||
376 | |||
377 | EOL(); |
||
378 | |||
379 | return TRUE; |
||
380 | } |
||
381 | |||
382 | void |
||
383 | tgsi_dump_declaration( |
||
384 | const struct tgsi_full_declaration *decl ) |
||
385 | { |
||
386 | struct dump_ctx ctx; |
||
387 | |||
388 | ctx.dump_printf = dump_ctx_printf; |
||
389 | |||
390 | iter_declaration( &ctx.iter, (struct tgsi_full_declaration *)decl ); |
||
391 | } |
||
392 | |||
393 | static boolean |
||
394 | iter_property( |
||
395 | struct tgsi_iterate_context *iter, |
||
396 | struct tgsi_full_property *prop ) |
||
397 | { |
||
398 | unsigned i; |
||
399 | struct dump_ctx *ctx = (struct dump_ctx *)iter; |
||
400 | |||
401 | TXT( "PROPERTY " ); |
||
402 | ENM(prop->Property.PropertyName, tgsi_property_names); |
||
403 | |||
404 | if (prop->Property.NrTokens > 1) |
||
405 | TXT(" "); |
||
406 | |||
407 | for (i = 0; i < prop->Property.NrTokens - 1; ++i) { |
||
408 | switch (prop->Property.PropertyName) { |
||
409 | case TGSI_PROPERTY_GS_INPUT_PRIM: |
||
410 | case TGSI_PROPERTY_GS_OUTPUT_PRIM: |
||
411 | ENM(prop->u[i].Data, tgsi_primitive_names); |
||
412 | break; |
||
413 | case TGSI_PROPERTY_FS_COORD_ORIGIN: |
||
414 | ENM(prop->u[i].Data, tgsi_fs_coord_origin_names); |
||
415 | break; |
||
416 | case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER: |
||
417 | ENM(prop->u[i].Data, tgsi_fs_coord_pixel_center_names); |
||
418 | break; |
||
419 | default: |
||
420 | SID( prop->u[i].Data ); |
||
421 | break; |
||
422 | } |
||
423 | if (i < prop->Property.NrTokens - 2) |
||
424 | TXT( ", " ); |
||
425 | } |
||
426 | EOL(); |
||
427 | |||
428 | return TRUE; |
||
429 | } |
||
430 | |||
431 | void tgsi_dump_property( |
||
432 | const struct tgsi_full_property *prop ) |
||
433 | { |
||
434 | struct dump_ctx ctx; |
||
435 | |||
436 | ctx.dump_printf = dump_ctx_printf; |
||
437 | |||
438 | iter_property( &ctx.iter, (struct tgsi_full_property *)prop ); |
||
439 | } |
||
440 | |||
441 | static boolean |
||
442 | iter_immediate( |
||
443 | struct tgsi_iterate_context *iter, |
||
444 | struct tgsi_full_immediate *imm ) |
||
445 | { |
||
446 | struct dump_ctx *ctx = (struct dump_ctx *) iter; |
||
447 | |||
448 | TXT( "IMM[" ); |
||
449 | SID( ctx->immno++ ); |
||
450 | TXT( "] " ); |
||
451 | ENM( imm->Immediate.DataType, tgsi_immediate_type_names ); |
||
452 | |||
453 | dump_imm_data(iter, imm->u, imm->Immediate.NrTokens - 1, |
||
454 | imm->Immediate.DataType); |
||
455 | |||
456 | EOL(); |
||
457 | |||
458 | return TRUE; |
||
459 | } |
||
460 | |||
461 | void |
||
462 | tgsi_dump_immediate( |
||
463 | const struct tgsi_full_immediate *imm ) |
||
464 | { |
||
465 | struct dump_ctx ctx; |
||
466 | |||
467 | ctx.dump_printf = dump_ctx_printf; |
||
468 | |||
469 | iter_immediate( &ctx.iter, (struct tgsi_full_immediate *)imm ); |
||
470 | } |
||
471 | |||
472 | static boolean |
||
473 | iter_instruction( |
||
474 | struct tgsi_iterate_context *iter, |
||
475 | struct tgsi_full_instruction *inst ) |
||
476 | { |
||
477 | struct dump_ctx *ctx = (struct dump_ctx *) iter; |
||
478 | uint instno = ctx->instno++; |
||
479 | const struct tgsi_opcode_info *info = tgsi_get_opcode_info( inst->Instruction.Opcode ); |
||
480 | uint i; |
||
481 | boolean first_reg = TRUE; |
||
482 | |||
483 | INSTID( instno ); |
||
484 | TXT( ": " ); |
||
485 | |||
486 | ctx->indent -= info->pre_dedent; |
||
487 | for(i = 0; (int)i < ctx->indent; ++i) |
||
488 | TXT( " " ); |
||
489 | ctx->indent += info->post_indent; |
||
490 | |||
491 | if (inst->Instruction.Predicate) { |
||
492 | CHR( '(' ); |
||
493 | |||
494 | if (inst->Predicate.Negate) |
||
495 | CHR( '!' ); |
||
496 | |||
497 | TXT( "PRED[" ); |
||
498 | SID( inst->Predicate.Index ); |
||
499 | CHR( ']' ); |
||
500 | |||
501 | if (inst->Predicate.SwizzleX != TGSI_SWIZZLE_X || |
||
502 | inst->Predicate.SwizzleY != TGSI_SWIZZLE_Y || |
||
503 | inst->Predicate.SwizzleZ != TGSI_SWIZZLE_Z || |
||
504 | inst->Predicate.SwizzleW != TGSI_SWIZZLE_W) { |
||
505 | CHR( '.' ); |
||
506 | ENM( inst->Predicate.SwizzleX, tgsi_swizzle_names ); |
||
507 | ENM( inst->Predicate.SwizzleY, tgsi_swizzle_names ); |
||
508 | ENM( inst->Predicate.SwizzleZ, tgsi_swizzle_names ); |
||
509 | ENM( inst->Predicate.SwizzleW, tgsi_swizzle_names ); |
||
510 | } |
||
511 | |||
512 | TXT( ") " ); |
||
513 | } |
||
514 | |||
515 | TXT( info->mnemonic ); |
||
516 | |||
517 | switch (inst->Instruction.Saturate) { |
||
518 | case TGSI_SAT_NONE: |
||
519 | break; |
||
520 | case TGSI_SAT_ZERO_ONE: |
||
521 | TXT( "_SAT" ); |
||
522 | break; |
||
523 | case TGSI_SAT_MINUS_PLUS_ONE: |
||
524 | TXT( "_SATNV" ); |
||
525 | break; |
||
526 | default: |
||
527 | assert( 0 ); |
||
528 | } |
||
529 | |||
530 | for (i = 0; i < inst->Instruction.NumDstRegs; i++) { |
||
531 | const struct tgsi_full_dst_register *dst = &inst->Dst[i]; |
||
532 | |||
533 | if (!first_reg) |
||
534 | CHR( ',' ); |
||
535 | CHR( ' ' ); |
||
536 | |||
537 | _dump_register_dst( ctx, dst ); |
||
538 | _dump_writemask( ctx, dst->Register.WriteMask ); |
||
539 | |||
540 | first_reg = FALSE; |
||
541 | } |
||
542 | |||
543 | for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { |
||
544 | const struct tgsi_full_src_register *src = &inst->Src[i]; |
||
545 | |||
546 | if (!first_reg) |
||
547 | CHR( ',' ); |
||
548 | CHR( ' ' ); |
||
549 | |||
550 | if (src->Register.Negate) |
||
551 | CHR( '-' ); |
||
552 | if (src->Register.Absolute) |
||
553 | CHR( '|' ); |
||
554 | |||
555 | _dump_register_src(ctx, src); |
||
556 | |||
557 | if (src->Register.SwizzleX != TGSI_SWIZZLE_X || |
||
558 | src->Register.SwizzleY != TGSI_SWIZZLE_Y || |
||
559 | src->Register.SwizzleZ != TGSI_SWIZZLE_Z || |
||
560 | src->Register.SwizzleW != TGSI_SWIZZLE_W) { |
||
561 | CHR( '.' ); |
||
562 | ENM( src->Register.SwizzleX, tgsi_swizzle_names ); |
||
563 | ENM( src->Register.SwizzleY, tgsi_swizzle_names ); |
||
564 | ENM( src->Register.SwizzleZ, tgsi_swizzle_names ); |
||
565 | ENM( src->Register.SwizzleW, tgsi_swizzle_names ); |
||
566 | } |
||
567 | |||
568 | if (src->Register.Absolute) |
||
569 | CHR( '|' ); |
||
570 | |||
571 | first_reg = FALSE; |
||
572 | } |
||
573 | |||
574 | if (inst->Instruction.Texture) { |
||
575 | TXT( ", " ); |
||
576 | ENM( inst->Texture.Texture, tgsi_texture_names ); |
||
577 | for (i = 0; i < inst->Texture.NumOffsets; i++) { |
||
578 | TXT( ", " ); |
||
579 | TXT(tgsi_file_name(inst->TexOffsets[i].File)); |
||
580 | CHR( '[' ); |
||
581 | SID( inst->TexOffsets[i].Index ); |
||
582 | CHR( ']' ); |
||
583 | CHR( '.' ); |
||
584 | ENM( inst->TexOffsets[i].SwizzleX, tgsi_swizzle_names); |
||
585 | ENM( inst->TexOffsets[i].SwizzleY, tgsi_swizzle_names); |
||
586 | ENM( inst->TexOffsets[i].SwizzleZ, tgsi_swizzle_names); |
||
587 | } |
||
588 | } |
||
589 | |||
590 | switch (inst->Instruction.Opcode) { |
||
591 | case TGSI_OPCODE_IF: |
||
592 | case TGSI_OPCODE_UIF: |
||
593 | case TGSI_OPCODE_ELSE: |
||
594 | case TGSI_OPCODE_BGNLOOP: |
||
595 | case TGSI_OPCODE_ENDLOOP: |
||
596 | case TGSI_OPCODE_CAL: |
||
597 | TXT( " :" ); |
||
598 | UID( inst->Label.Label ); |
||
599 | break; |
||
600 | } |
||
601 | |||
602 | /* update indentation */ |
||
603 | if (inst->Instruction.Opcode == TGSI_OPCODE_IF || |
||
604 | inst->Instruction.Opcode == TGSI_OPCODE_UIF || |
||
605 | inst->Instruction.Opcode == TGSI_OPCODE_ELSE || |
||
606 | inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP) { |
||
607 | ctx->indentation += indent_spaces; |
||
608 | } |
||
609 | |||
610 | EOL(); |
||
611 | |||
612 | return TRUE; |
||
613 | } |
||
614 | |||
615 | void |
||
616 | tgsi_dump_instruction( |
||
617 | const struct tgsi_full_instruction *inst, |
||
618 | uint instno ) |
||
619 | { |
||
620 | struct dump_ctx ctx; |
||
621 | |||
622 | ctx.instno = instno; |
||
623 | ctx.immno = instno; |
||
624 | ctx.indent = 0; |
||
625 | ctx.dump_printf = dump_ctx_printf; |
||
626 | ctx.indentation = 0; |
||
627 | |||
628 | iter_instruction( &ctx.iter, (struct tgsi_full_instruction *)inst ); |
||
629 | } |
||
630 | |||
631 | static boolean |
||
632 | prolog( |
||
633 | struct tgsi_iterate_context *iter ) |
||
634 | { |
||
635 | struct dump_ctx *ctx = (struct dump_ctx *) iter; |
||
636 | ENM( iter->processor.Processor, tgsi_processor_type_names ); |
||
637 | EOL(); |
||
638 | return TRUE; |
||
639 | } |
||
640 | |||
641 | void |
||
642 | tgsi_dump( |
||
643 | const struct tgsi_token *tokens, |
||
644 | uint flags ) |
||
645 | { |
||
646 | struct dump_ctx ctx; |
||
647 | |||
648 | ctx.iter.prolog = prolog; |
||
649 | ctx.iter.iterate_instruction = iter_instruction; |
||
650 | ctx.iter.iterate_declaration = iter_declaration; |
||
651 | ctx.iter.iterate_immediate = iter_immediate; |
||
652 | ctx.iter.iterate_property = iter_property; |
||
653 | ctx.iter.epilog = NULL; |
||
654 | |||
655 | ctx.instno = 0; |
||
656 | ctx.immno = 0; |
||
657 | ctx.indent = 0; |
||
658 | ctx.dump_printf = dump_ctx_printf; |
||
659 | ctx.indentation = 0; |
||
660 | |||
661 | tgsi_iterate_shader( tokens, &ctx.iter ); |
||
662 | } |
||
663 | |||
664 | struct str_dump_ctx |
||
665 | { |
||
666 | struct dump_ctx base; |
||
667 | char *str; |
||
668 | char *ptr; |
||
669 | int left; |
||
670 | }; |
||
671 | |||
672 | static void |
||
673 | str_dump_ctx_printf(struct dump_ctx *ctx, const char *format, ...) |
||
674 | { |
||
675 | struct str_dump_ctx *sctx = (struct str_dump_ctx *)ctx; |
||
676 | |||
677 | if(sctx->left > 1) { |
||
678 | int written; |
||
679 | va_list ap; |
||
680 | va_start(ap, format); |
||
681 | written = util_vsnprintf(sctx->ptr, sctx->left, format, ap); |
||
682 | va_end(ap); |
||
683 | |||
684 | /* Some complicated logic needed to handle the return value of |
||
685 | * vsnprintf: |
||
686 | */ |
||
687 | if (written > 0) { |
||
688 | written = MIN2(sctx->left, written); |
||
689 | sctx->ptr += written; |
||
690 | sctx->left -= written; |
||
691 | } |
||
692 | } |
||
693 | } |
||
694 | |||
695 | void |
||
696 | tgsi_dump_str( |
||
697 | const struct tgsi_token *tokens, |
||
698 | uint flags, |
||
699 | char *str, |
||
700 | size_t size) |
||
701 | { |
||
702 | struct str_dump_ctx ctx; |
||
703 | |||
704 | ctx.base.iter.prolog = prolog; |
||
705 | ctx.base.iter.iterate_instruction = iter_instruction; |
||
706 | ctx.base.iter.iterate_declaration = iter_declaration; |
||
707 | ctx.base.iter.iterate_immediate = iter_immediate; |
||
708 | ctx.base.iter.iterate_property = iter_property; |
||
709 | ctx.base.iter.epilog = NULL; |
||
710 | |||
711 | ctx.base.instno = 0; |
||
712 | ctx.base.immno = 0; |
||
713 | ctx.base.indent = 0; |
||
714 | ctx.base.dump_printf = &str_dump_ctx_printf; |
||
715 | ctx.base.indentation = 0; |
||
716 | |||
717 | ctx.str = str; |
||
718 | ctx.str[0] = 0; |
||
719 | ctx.ptr = str; |
||
720 | ctx.left = (int)size; |
||
721 | |||
722 | tgsi_iterate_shader( tokens, &ctx.base.iter ); |
||
723 | }>>>>>>>>=> |