2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Print vertex/fragment programs - for debugging.
34 #include "prog_instruction.h"
35 #include "prog_parameter.h"
36 #include "prog_print.h"
37 #include "prog_statevars.h"
41 * Return string name for given program/register file.
44 program_file_string(enum register_file f
)
47 case PROGRAM_TEMPORARY
:
49 case PROGRAM_LOCAL_PARAM
:
51 case PROGRAM_ENV_PARAM
:
53 case PROGRAM_STATE_VAR
:
59 case PROGRAM_NAMED_PARAM
:
61 case PROGRAM_CONSTANT
:
67 case PROGRAM_WRITE_ONLY
:
74 return "Unknown program file!";
80 * Return a string representation of the given swizzle word.
81 * If extended is true, use extended (comma-separated) format.
82 * \param swizzle the swizzle field
83 * \param negateBase 4-bit negation vector
84 * \param extended if true, also allow 0, 1 values
87 swizzle_string(GLuint swizzle
, GLuint negateBase
, GLboolean extended
)
89 static const char swz
[] = "xyzw01?!";
93 if (!extended
&& swizzle
== SWIZZLE_NOOP
&& negateBase
== 0)
94 return ""; /* no swizzle/negation */
101 s
[i
++] = swz
[GET_SWZ(swizzle
, 0)];
107 if (negateBase
& 0x2)
109 s
[i
++] = swz
[GET_SWZ(swizzle
, 1)];
115 if (negateBase
& 0x4)
117 s
[i
++] = swz
[GET_SWZ(swizzle
, 2)];
123 if (negateBase
& 0x8)
125 s
[i
++] = swz
[GET_SWZ(swizzle
, 3)];
133 writemask_string(GLuint writeMask
)
138 if (writeMask
== WRITEMASK_XYZW
)
142 if (writeMask
& WRITEMASK_X
)
144 if (writeMask
& WRITEMASK_Y
)
146 if (writeMask
& WRITEMASK_Z
)
148 if (writeMask
& WRITEMASK_W
)
157 condcode_string(GLuint condcode
)
160 case COND_GT
: return "GT";
161 case COND_EQ
: return "EQ";
162 case COND_LT
: return "LT";
163 case COND_UN
: return "UN";
164 case COND_GE
: return "GE";
165 case COND_LE
: return "LE";
166 case COND_NE
: return "NE";
167 case COND_TR
: return "TR";
168 case COND_FL
: return "FL";
169 default: return "cond???";
175 print_dst_reg(const struct prog_dst_register
*dstReg
)
177 _mesa_printf(" %s[%d]%s",
178 program_file_string((enum register_file
) dstReg
->File
),
180 writemask_string(dstReg
->WriteMask
));
184 print_src_reg(const struct prog_src_register
*srcReg
)
186 _mesa_printf("%s[%d]%s",
187 program_file_string((enum register_file
) srcReg
->File
),
189 swizzle_string(srcReg
->Swizzle
,
190 srcReg
->NegateBase
, GL_FALSE
));
194 print_comment(const struct prog_instruction
*inst
)
197 _mesa_printf("; # %s\n", inst
->Comment
);
204 _mesa_print_alu_instruction(const struct prog_instruction
*inst
,
205 const char *opcode_string
,
210 _mesa_printf("%s", opcode_string
);
211 if (inst
->CondUpdate
)
215 if (inst
->SaturateMode
== SATURATE_ZERO_ONE
)
216 _mesa_printf("_SAT");
218 if (inst
->DstReg
.File
!= PROGRAM_UNDEFINED
) {
219 print_dst_reg(&inst
->DstReg
);
222 _mesa_printf(" ???");
228 for (j
= 0; j
< numRegs
; j
++) {
229 print_src_reg(inst
->SrcReg
+ j
);
239 * Print a single vertex/fragment program instruction.
242 _mesa_print_instruction(const struct prog_instruction
*inst
, GLint indent
)
246 if (inst
->Opcode
== OPCODE_ELSE
||
247 inst
->Opcode
== OPCODE_ENDIF
||
248 inst
->Opcode
== OPCODE_ENDLOOP
||
249 inst
->Opcode
== OPCODE_ENDSUB
) {
253 for (i
= 0; i
< indent
; i
++) {
257 switch (inst
->Opcode
) {
259 _mesa_printf("PRINT '%s'", inst
->Data
);
260 if (inst
->SrcReg
[0].File
!= PROGRAM_UNDEFINED
) {
262 _mesa_printf("%s[%d]%s",
263 program_file_string((enum register_file
) inst
->SrcReg
[0].File
),
264 inst
->SrcReg
[0].Index
,
265 swizzle_string(inst
->SrcReg
[0].Swizzle
,
266 inst
->SrcReg
[0].NegateBase
, GL_FALSE
));
269 _mesa_printf(" # %s", inst
->Comment
);
274 if (inst
->SaturateMode
== SATURATE_ZERO_ONE
)
275 _mesa_printf("_SAT");
276 print_dst_reg(&inst
->DstReg
);
277 _mesa_printf("%s[%d], %s",
278 program_file_string((enum register_file
) inst
->SrcReg
[0].File
),
279 inst
->SrcReg
[0].Index
,
280 swizzle_string(inst
->SrcReg
[0].Swizzle
,
281 inst
->SrcReg
[0].NegateBase
, GL_TRUE
));
287 _mesa_printf("%s", _mesa_opcode_string(inst
->Opcode
));
288 if (inst
->SaturateMode
== SATURATE_ZERO_ONE
)
289 _mesa_printf("_SAT");
290 print_dst_reg(&inst
->DstReg
);
292 print_src_reg(&inst
->SrcReg
[0]);
293 _mesa_printf(", texture[%d], ", inst
->TexSrcUnit
);
294 switch (inst
->TexSrcTarget
) {
295 case TEXTURE_1D_INDEX
: _mesa_printf("1D"); break;
296 case TEXTURE_2D_INDEX
: _mesa_printf("2D"); break;
297 case TEXTURE_3D_INDEX
: _mesa_printf("3D"); break;
298 case TEXTURE_CUBE_INDEX
: _mesa_printf("CUBE"); break;
299 case TEXTURE_RECT_INDEX
: _mesa_printf("RECT"); break;
306 _mesa_printf("ARL addr.x, ");
307 print_src_reg(&inst
->SrcReg
[0]);
311 _mesa_printf("BRA %u (%s%s)",
313 condcode_string(inst
->DstReg
.CondMask
),
314 swizzle_string(inst
->DstReg
.CondSwizzle
, 0, GL_FALSE
));
318 _mesa_printf("CAL %u", inst
->BranchTarget
);
322 _mesa_printf("IF (%s%s) (if false, goto %d)",
323 condcode_string(inst
->DstReg
.CondMask
),
324 swizzle_string(inst
->DstReg
.CondSwizzle
, 0, GL_FALSE
),
329 _mesa_printf("ELSE (goto %d)\n", inst
->BranchTarget
);
332 _mesa_printf("ENDIF\n");
335 _mesa_printf("BGNLOOP (end at %d)\n", inst
->BranchTarget
);
338 _mesa_printf("ENDLOOP (goto %d)\n", inst
->BranchTarget
);
341 /* XXX just like BRA */
342 _mesa_printf("BRK (%s%s) (for loop beginning at %d)",
343 condcode_string(inst
->DstReg
.CondMask
),
344 swizzle_string(inst
->DstReg
.CondSwizzle
, 0, GL_FALSE
),
349 _mesa_printf("SUB;\n");
353 _mesa_printf("ENDSUB;\n");
364 /* XXX may need other special-case instructions */
366 /* typical alu instruction */
367 _mesa_print_alu_instruction(inst
,
368 _mesa_opcode_string(inst
->Opcode
),
369 _mesa_num_inst_src_regs(inst
->Opcode
));
377 * Print a vertx/fragment program to stdout.
378 * XXX this function could be greatly improved.
381 _mesa_print_program(const struct gl_program
*prog
)
383 GLuint i
, indent
= 0;
384 for (i
= 0; i
< prog
->NumInstructions
; i
++) {
385 _mesa_printf("%3d: ", i
);
386 indent
= _mesa_print_instruction(prog
->Instructions
+ i
, indent
);
392 * Print all of a program's parameters.
395 _mesa_print_program_parameters(GLcontext
*ctx
, const struct gl_program
*prog
)
397 _mesa_printf("InputsRead: 0x%x\n", prog
->InputsRead
);
398 _mesa_printf("OutputsWritten: 0x%x\n", prog
->OutputsWritten
);
399 _mesa_printf("NumInstructions=%d\n", prog
->NumInstructions
);
400 _mesa_printf("NumTemporaries=%d\n", prog
->NumTemporaries
);
401 _mesa_printf("NumParameters=%d\n", prog
->NumParameters
);
402 _mesa_printf("NumAttributes=%d\n", prog
->NumAttributes
);
403 _mesa_printf("NumAddressRegs=%d\n", prog
->NumAddressRegs
);
405 _mesa_load_state_parameters(ctx
, prog
->Parameters
);
408 _mesa_printf("Local Params:\n");
409 for (i
= 0; i
< MAX_PROGRAM_LOCAL_PARAMS
; i
++){
410 const GLfloat
*p
= prog
->LocalParams
[i
];
411 _mesa_printf("%2d: %f, %f, %f, %f\n", i
, p
[0], p
[1], p
[2], p
[3]);
414 _mesa_print_parameter_list(prog
->Parameters
);
419 _mesa_print_parameter_list(const struct gl_program_parameter_list
*list
)
422 _mesa_printf("param list %p\n", (void *) list
);
423 for (i
= 0; i
< list
->NumParameters
; i
++){
424 struct gl_program_parameter
*param
= list
->Parameters
+ i
;
425 const GLfloat
*v
= list
->ParameterValues
[i
];
426 _mesa_printf("param[%d] sz=%d %s %s = {%.3f, %.3f, %.3f, %.3f};\n",
428 program_file_string(list
->Parameters
[i
].Type
),
429 param
->Name
, v
[0], v
[1], v
[2], v
[3]);