blob: 07b383dc5689702d844b02fcce257d1c0903b732 [file] [log] [blame]
Brian00cdc0a2006-12-14 15:01:06 -07001/*
2 * Mesa 3-D graphics library
3 * Version: 6.5.3
4 *
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
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.
23 */
24
25/**
26 * \file prog_print.c
27 * Print vertex/fragment programs - for debugging.
28 * \author Brian Paul
29 */
30
31#include "glheader.h"
32#include "context.h"
33#include "imports.h"
Brian00cdc0a2006-12-14 15:01:06 -070034#include "prog_instruction.h"
35#include "prog_parameter.h"
36#include "prog_print.h"
37#include "prog_statevars.h"
38
39
Brian00cdc0a2006-12-14 15:01:06 -070040/**
41 * Return string name for given program/register file.
42 */
43static const char *
44program_file_string(enum register_file f)
45{
46 switch (f) {
47 case PROGRAM_TEMPORARY:
48 return "TEMP";
49 case PROGRAM_LOCAL_PARAM:
50 return "LOCAL";
51 case PROGRAM_ENV_PARAM:
52 return "ENV";
53 case PROGRAM_STATE_VAR:
54 return "STATE";
55 case PROGRAM_INPUT:
56 return "INPUT";
57 case PROGRAM_OUTPUT:
58 return "OUTPUT";
59 case PROGRAM_NAMED_PARAM:
60 return "NAMED";
61 case PROGRAM_CONSTANT:
62 return "CONST";
63 case PROGRAM_UNIFORM:
64 return "UNIFORM";
65 case PROGRAM_VARYING:
66 return "VARYING";
67 case PROGRAM_WRITE_ONLY:
68 return "WRITE_ONLY";
69 case PROGRAM_ADDRESS:
70 return "ADDR";
71 default:
72 return "Unknown program file!";
73 }
74}
75
76
77/**
78 * Return a string representation of the given swizzle word.
79 * If extended is true, use extended (comma-separated) format.
Brian3a281532006-12-16 12:51:34 -070080 * \param swizzle the swizzle field
81 * \param negateBase 4-bit negation vector
82 * \param extended if true, also allow 0, 1 values
Brian00cdc0a2006-12-14 15:01:06 -070083 */
84static const char *
85swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
86{
87 static const char swz[] = "xyzw01";
88 static char s[20];
89 GLuint i = 0;
90
91 if (!extended && swizzle == SWIZZLE_NOOP && negateBase == 0)
92 return ""; /* no swizzle/negation */
93
94 if (!extended)
95 s[i++] = '.';
96
97 if (negateBase & 0x1)
98 s[i++] = '-';
99 s[i++] = swz[GET_SWZ(swizzle, 0)];
100
101 if (extended) {
102 s[i++] = ',';
103 }
104
105 if (negateBase & 0x2)
106 s[i++] = '-';
107 s[i++] = swz[GET_SWZ(swizzle, 1)];
108
109 if (extended) {
110 s[i++] = ',';
111 }
112
113 if (negateBase & 0x4)
114 s[i++] = '-';
115 s[i++] = swz[GET_SWZ(swizzle, 2)];
116
117 if (extended) {
118 s[i++] = ',';
119 }
120
121 if (negateBase & 0x8)
122 s[i++] = '-';
123 s[i++] = swz[GET_SWZ(swizzle, 3)];
124
125 s[i] = 0;
126 return s;
127}
128
129
130static const char *
131writemask_string(GLuint writeMask)
132{
133 static char s[10];
134 GLuint i = 0;
135
136 if (writeMask == WRITEMASK_XYZW)
137 return "";
138
139 s[i++] = '.';
140 if (writeMask & WRITEMASK_X)
141 s[i++] = 'x';
142 if (writeMask & WRITEMASK_Y)
143 s[i++] = 'y';
144 if (writeMask & WRITEMASK_Z)
145 s[i++] = 'z';
146 if (writeMask & WRITEMASK_W)
147 s[i++] = 'w';
148
149 s[i] = 0;
150 return s;
151}
152
Brian3a281532006-12-16 12:51:34 -0700153
154static const char *
155condcode_string(GLuint condcode)
156{
157 switch (condcode) {
158 case COND_GT: return "GT";
159 case COND_EQ: return "EQ";
160 case COND_LT: return "LT";
161 case COND_UN: return "UN";
162 case COND_GE: return "GE";
163 case COND_LE: return "LE";
164 case COND_NE: return "NE";
165 case COND_TR: return "TR";
166 case COND_FL: return "FL";
167 default: return "cond???";
168 }
169}
170
171
Brian00cdc0a2006-12-14 15:01:06 -0700172static void
173print_dst_reg(const struct prog_dst_register *dstReg)
174{
175 _mesa_printf(" %s[%d]%s",
176 program_file_string((enum register_file) dstReg->File),
177 dstReg->Index,
178 writemask_string(dstReg->WriteMask));
179}
180
181static void
182print_src_reg(const struct prog_src_register *srcReg)
183{
184 _mesa_printf("%s[%d]%s",
185 program_file_string((enum register_file) srcReg->File),
186 srcReg->Index,
187 swizzle_string(srcReg->Swizzle,
188 srcReg->NegateBase, GL_FALSE));
189}
190
191static void
192print_comment(const struct prog_instruction *inst)
193{
194 if (inst->Comment)
195 _mesa_printf("; # %s\n", inst->Comment);
196 else
197 _mesa_printf(";\n");
198}
199
200
201void
202_mesa_print_alu_instruction(const struct prog_instruction *inst,
203 const char *opcode_string,
204 GLuint numRegs)
205{
206 GLuint j;
207
208 _mesa_printf("%s", opcode_string);
Brianb50280e2006-12-18 16:21:58 -0700209 if (inst->CondUpdate)
210 _mesa_printf(".C");
Brian00cdc0a2006-12-14 15:01:06 -0700211
212 /* frag prog only */
213 if (inst->SaturateMode == SATURATE_ZERO_ONE)
214 _mesa_printf("_SAT");
215
216 if (inst->DstReg.File != PROGRAM_UNDEFINED) {
Brianb50280e2006-12-18 16:21:58 -0700217 print_dst_reg(&inst->DstReg);
Brian00cdc0a2006-12-14 15:01:06 -0700218 }
219 else {
220 _mesa_printf(" ???");
221 }
222
223 if (numRegs > 0)
224 _mesa_printf(", ");
225
226 for (j = 0; j < numRegs; j++) {
227 print_src_reg(inst->SrcReg + j);
228 if (j + 1 < numRegs)
229 _mesa_printf(", ");
230 }
231
Brian00cdc0a2006-12-14 15:01:06 -0700232 print_comment(inst);
233}
234
235
236/**
237 * Print a single vertex/fragment program instruction.
238 */
239void
240_mesa_print_instruction(const struct prog_instruction *inst)
241{
242 switch (inst->Opcode) {
243 case OPCODE_PRINT:
244 _mesa_printf("PRINT '%s'", inst->Data);
245 if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
246 _mesa_printf(", ");
247 _mesa_printf("%s[%d]%s",
248 program_file_string((enum register_file) inst->SrcReg[0].File),
249 inst->SrcReg[0].Index,
250 swizzle_string(inst->SrcReg[0].Swizzle,
251 inst->SrcReg[0].NegateBase, GL_FALSE));
252 }
253 if (inst->Comment)
254 _mesa_printf(" # %s", inst->Comment);
255 print_comment(inst);
256 break;
257 case OPCODE_SWZ:
258 _mesa_printf("SWZ");
259 if (inst->SaturateMode == SATURATE_ZERO_ONE)
260 _mesa_printf("_SAT");
261 print_dst_reg(&inst->DstReg);
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_TRUE));
267 print_comment(inst);
268 break;
269 case OPCODE_TEX:
270 case OPCODE_TXP:
271 case OPCODE_TXB:
272 _mesa_printf("%s", _mesa_opcode_string(inst->Opcode));
273 if (inst->SaturateMode == SATURATE_ZERO_ONE)
274 _mesa_printf("_SAT");
275 _mesa_printf(" ");
276 print_dst_reg(&inst->DstReg);
277 _mesa_printf(", ");
278 print_src_reg(&inst->SrcReg[0]);
279 _mesa_printf(", texture[%d], ", inst->TexSrcUnit);
280 switch (inst->TexSrcTarget) {
281 case TEXTURE_1D_INDEX: _mesa_printf("1D"); break;
282 case TEXTURE_2D_INDEX: _mesa_printf("2D"); break;
283 case TEXTURE_3D_INDEX: _mesa_printf("3D"); break;
284 case TEXTURE_CUBE_INDEX: _mesa_printf("CUBE"); break;
285 case TEXTURE_RECT_INDEX: _mesa_printf("RECT"); break;
286 default:
287 ;
288 }
289 print_comment(inst);
290 break;
291 case OPCODE_ARL:
292 _mesa_printf("ARL addr.x, ");
293 print_src_reg(&inst->SrcReg[0]);
294 print_comment(inst);
295 break;
296 case OPCODE_BRA:
Brian3a281532006-12-16 12:51:34 -0700297 _mesa_printf("BRA %u (%s.%s)",
298 inst->BranchTarget,
299 condcode_string(inst->DstReg.CondMask),
300 swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
Brian00cdc0a2006-12-14 15:01:06 -0700301 print_comment(inst);
302 break;
303 case OPCODE_CAL:
304 _mesa_printf("CAL %u", inst->BranchTarget);
305 print_comment(inst);
306 break;
307 case OPCODE_END:
308 _mesa_printf("END");
309 print_comment(inst);
310 break;
Brian3a281532006-12-16 12:51:34 -0700311 case OPCODE_NOP:
312 _mesa_printf("NOP");
313 print_comment(inst);
314 break;
Brian00cdc0a2006-12-14 15:01:06 -0700315 /* XXX may need other special-case instructions */
316 default:
317 /* typical alu instruction */
318 _mesa_print_alu_instruction(inst,
319 _mesa_opcode_string(inst->Opcode),
320 _mesa_num_inst_src_regs(inst->Opcode));
321 break;
322 }
323}
324
325
326/**
327 * Print a vertx/fragment program to stdout.
328 * XXX this function could be greatly improved.
329 */
330void
331_mesa_print_program(const struct gl_program *prog)
332{
333 GLuint i;
334 for (i = 0; i < prog->NumInstructions; i++) {
335 _mesa_printf("%3d: ", i);
336 _mesa_print_instruction(prog->Instructions + i);
337 }
338}
339
340
341/**
342 * Print all of a program's parameters.
343 */
344void
345_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
346{
Brian00cdc0a2006-12-14 15:01:06 -0700347 _mesa_printf("InputsRead: 0x%x\n", prog->InputsRead);
348 _mesa_printf("OutputsWritten: 0x%x\n", prog->OutputsWritten);
349 _mesa_printf("NumInstructions=%d\n", prog->NumInstructions);
350 _mesa_printf("NumTemporaries=%d\n", prog->NumTemporaries);
351 _mesa_printf("NumParameters=%d\n", prog->NumParameters);
352 _mesa_printf("NumAttributes=%d\n", prog->NumAttributes);
353 _mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs);
354
355 _mesa_load_state_parameters(ctx, prog->Parameters);
356
357#if 0
358 _mesa_printf("Local Params:\n");
359 for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){
360 const GLfloat *p = prog->LocalParams[i];
361 _mesa_printf("%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]);
362 }
363#endif
Brian83ca3ff2006-12-20 17:17:38 -0700364 _mesa_print_parameter_list(prog->Parameters);
365}
Brian00cdc0a2006-12-14 15:01:06 -0700366
Brian83ca3ff2006-12-20 17:17:38 -0700367
368void
369_mesa_print_parameter_list(const struct gl_program_parameter_list *list)
370{
371 GLuint i;
372 _mesa_printf("param list %p\n", (void *) list);
373 for (i = 0; i < list->NumParameters; i++){
374 struct gl_program_parameter *param = list->Parameters + i;
375 const GLfloat *v = list->ParameterValues[i];
376 _mesa_printf("param[%d] sz=%d %s %s = {%.3f, %.3f, %.3f, %.3f};\n",
377 i, param->Size,
378 program_file_string(list->Parameters[i].Type),
Brian00cdc0a2006-12-14 15:01:06 -0700379 param->Name, v[0], v[1], v[2], v[3]);
380 }
381}