Get rid of BRK0, BRK1, CONT0, CONT1 instructions.
[mesa.git] / src / mesa / shader / prog_print.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.3
4 *
5 * Copyright (C) 1999-2007 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"
34 #include "prog_instruction.h"
35 #include "prog_parameter.h"
36 #include "prog_print.h"
37 #include "prog_statevars.h"
38
39
40
41 /**
42 * Return string name for given program/register file.
43 */
44 static const char *
45 file_string(enum register_file f, gl_prog_print_mode mode)
46 {
47 switch (f) {
48 case PROGRAM_TEMPORARY:
49 return "TEMP";
50 case PROGRAM_LOCAL_PARAM:
51 return "LOCAL";
52 case PROGRAM_ENV_PARAM:
53 return "ENV";
54 case PROGRAM_STATE_VAR:
55 return "STATE";
56 case PROGRAM_INPUT:
57 return "INPUT";
58 case PROGRAM_OUTPUT:
59 return "OUTPUT";
60 case PROGRAM_NAMED_PARAM:
61 return "NAMED";
62 case PROGRAM_CONSTANT:
63 return "CONST";
64 case PROGRAM_UNIFORM:
65 return "UNIFORM";
66 case PROGRAM_VARYING:
67 return "VARYING";
68 case PROGRAM_WRITE_ONLY:
69 return "WRITE_ONLY";
70 case PROGRAM_ADDRESS:
71 return "ADDR";
72 case PROGRAM_SAMPLER:
73 return "SAMPLER";
74 default:
75 return "Unknown program file!";
76 }
77 }
78
79
80 /**
81 * Return ARB_v/f_prog-style input attrib string.
82 */
83 static const char *
84 arb_input_attrib_string(GLint index, GLenum progType)
85 {
86 const char *vertAttribs[] = {
87 "vertex.position",
88 "vertex.weight",
89 "vertex.normal",
90 "vertex.color.primary",
91 "vertex.color.secondary",
92 "vertex.fogcoord",
93 "vertex.(six)",
94 "vertex.(seven)",
95 "vertex.texcoord[0]",
96 "vertex.texcoord[1]",
97 "vertex.texcoord[2]",
98 "vertex.texcoord[3]",
99 "vertex.texcoord[4]",
100 "vertex.texcoord[5]",
101 "vertex.texcoord[6]",
102 "vertex.texcoord[7]"
103 };
104 const char *fragAttribs[] = {
105 "fragment.position",
106 "fragment.color.primary",
107 "fragment.color.secondary",
108 "fragment.fogcoord",
109 "fragment.texcoord[0]",
110 "fragment.texcoord[1]",
111 "fragment.texcoord[2]",
112 "fragment.texcoord[3]",
113 "fragment.texcoord[4]",
114 "fragment.texcoord[5]",
115 "fragment.texcoord[6]",
116 "fragment.texcoord[7]",
117 "fragment.varying[0]",
118 "fragment.varying[1]",
119 "fragment.varying[2]",
120 "fragment.varying[3]",
121 "fragment.varying[4]",
122 "fragment.varying[5]",
123 "fragment.varying[6]",
124 "fragment.varying[7]"
125 };
126
127 if (progType == GL_VERTEX_PROGRAM_ARB) {
128 assert(index < sizeof(vertAttribs) / sizeof(vertAttribs[0]));
129 return vertAttribs[index];
130 }
131 else {
132 assert(index < sizeof(fragAttribs) / sizeof(fragAttribs[0]));
133 return fragAttribs[index];
134 }
135 }
136
137
138 /**
139 * Return ARB_v/f_prog-style output attrib string.
140 */
141 static const char *
142 arb_output_attrib_string(GLint index, GLenum progType)
143 {
144 const char *vertResults[] = {
145 "result.position",
146 "result.color.primary",
147 "result.color.secondary",
148 "result.fogcoord",
149 "result.texcoord[0]",
150 "result.texcoord[1]",
151 "result.texcoord[2]",
152 "result.texcoord[3]",
153 "result.texcoord[4]",
154 "result.texcoord[5]",
155 "result.texcoord[6]",
156 "result.texcoord[7]",
157 "result.varying[0]",
158 "result.varying[1]",
159 "result.varying[2]",
160 "result.varying[3]",
161 "result.varying[4]",
162 "result.varying[5]",
163 "result.varying[6]",
164 "result.varying[7]"
165 };
166 const char *fragResults[] = {
167 "result.color",
168 "result.depth"
169 };
170
171 if (progType == GL_VERTEX_PROGRAM_ARB) {
172 assert(index < sizeof(vertResults) / sizeof(vertResults[0]));
173 return vertResults[index];
174 }
175 else {
176 assert(index < sizeof(fragResults) / sizeof(fragResults[0]));
177 return fragResults[index];
178 }
179 }
180
181
182 /**
183 * Return string representation of the given register.
184 * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined
185 * by the ARB/NV program languages so we've taken some liberties here.
186 * \param file the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc)
187 * \param index number of the register in the register file
188 * \param mode the output format/mode/style
189 * \param prog pointer to containing program
190 */
191 static const char *
192 reg_string(enum register_file f, GLint index, gl_prog_print_mode mode,
193 const struct gl_program *prog)
194 {
195 static char str[100];
196
197 str[0] = 0;
198
199 switch (mode) {
200 case PROG_PRINT_DEBUG:
201 sprintf(str, "%s[%d]", file_string(f, mode), index);
202 break;
203
204 case PROG_PRINT_ARB:
205 switch (f) {
206 case PROGRAM_INPUT:
207 sprintf(str, "%s", arb_input_attrib_string(index, prog->Target));
208 break;
209 case PROGRAM_OUTPUT:
210 sprintf(str, "%s", arb_output_attrib_string(index, prog->Target));
211 break;
212 case PROGRAM_TEMPORARY:
213 sprintf(str, "temp%d", index);
214 break;
215 case PROGRAM_ENV_PARAM:
216 sprintf(str, "program.env[%d]", index);
217 break;
218 case PROGRAM_LOCAL_PARAM:
219 sprintf(str, "program.local[%d]", index);
220 break;
221 case PROGRAM_VARYING: /* extension */
222 sprintf(str, "varying[%d]", index);
223 break;
224 case PROGRAM_CONSTANT: /* extension */
225 sprintf(str, "constant[%d]", index);
226 break;
227 case PROGRAM_UNIFORM: /* extension */
228 sprintf(str, "uniform[%d]", index);
229 break;
230 case PROGRAM_STATE_VAR:
231 {
232 struct gl_program_parameter *param
233 = prog->Parameters->Parameters + index;
234 sprintf(str, _mesa_program_state_string(param->StateIndexes));
235 }
236 break;
237 case PROGRAM_ADDRESS:
238 sprintf(str, "A%d", index);
239 break;
240 default:
241 _mesa_problem(NULL, "bad file in reg_string()");
242 }
243 break;
244
245 case PROG_PRINT_NV:
246 switch (f) {
247 case PROGRAM_INPUT:
248 if (prog->Target == GL_VERTEX_PROGRAM_ARB)
249 sprintf(str, "v[%d]", index);
250 else
251 sprintf(str, "f[%d]", index);
252 break;
253 case PROGRAM_OUTPUT:
254 sprintf(str, "o[%d]", index);
255 break;
256 case PROGRAM_TEMPORARY:
257 sprintf(str, "R%d", index);
258 break;
259 case PROGRAM_ENV_PARAM:
260 sprintf(str, "c[%d]", index);
261 break;
262 case PROGRAM_VARYING: /* extension */
263 sprintf(str, "varying[%d]", index);
264 break;
265 case PROGRAM_UNIFORM: /* extension */
266 sprintf(str, "uniform[%d]", index);
267 break;
268 case PROGRAM_CONSTANT: /* extension */
269 sprintf(str, "constant[%d]", index);
270 break;
271 case PROGRAM_STATE_VAR: /* extension */
272 sprintf(str, "state[%d]", index);
273 break;
274 default:
275 _mesa_problem(NULL, "bad file in reg_string()");
276 }
277 break;
278
279 default:
280 _mesa_problem(NULL, "bad mode in reg_string()");
281 }
282
283 return str;
284 }
285
286
287 /**
288 * Return a string representation of the given swizzle word.
289 * If extended is true, use extended (comma-separated) format.
290 * \param swizzle the swizzle field
291 * \param negateBase 4-bit negation vector
292 * \param extended if true, also allow 0, 1 values
293 */
294 const char *
295 _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
296 {
297 static const char swz[] = "xyzw01?!";
298 static char s[20];
299 GLuint i = 0;
300
301 if (!extended && swizzle == SWIZZLE_NOOP && negateBase == 0)
302 return ""; /* no swizzle/negation */
303
304 if (!extended)
305 s[i++] = '.';
306
307 if (negateBase & 0x1)
308 s[i++] = '-';
309 s[i++] = swz[GET_SWZ(swizzle, 0)];
310
311 if (extended) {
312 s[i++] = ',';
313 }
314
315 if (negateBase & 0x2)
316 s[i++] = '-';
317 s[i++] = swz[GET_SWZ(swizzle, 1)];
318
319 if (extended) {
320 s[i++] = ',';
321 }
322
323 if (negateBase & 0x4)
324 s[i++] = '-';
325 s[i++] = swz[GET_SWZ(swizzle, 2)];
326
327 if (extended) {
328 s[i++] = ',';
329 }
330
331 if (negateBase & 0x8)
332 s[i++] = '-';
333 s[i++] = swz[GET_SWZ(swizzle, 3)];
334
335 s[i] = 0;
336 return s;
337 }
338
339
340 static const char *
341 writemask_string(GLuint writeMask)
342 {
343 static char s[10];
344 GLuint i = 0;
345
346 if (writeMask == WRITEMASK_XYZW)
347 return "";
348
349 s[i++] = '.';
350 if (writeMask & WRITEMASK_X)
351 s[i++] = 'x';
352 if (writeMask & WRITEMASK_Y)
353 s[i++] = 'y';
354 if (writeMask & WRITEMASK_Z)
355 s[i++] = 'z';
356 if (writeMask & WRITEMASK_W)
357 s[i++] = 'w';
358
359 s[i] = 0;
360 return s;
361 }
362
363
364 const char *
365 _mesa_condcode_string(GLuint condcode)
366 {
367 switch (condcode) {
368 case COND_GT: return "GT";
369 case COND_EQ: return "EQ";
370 case COND_LT: return "LT";
371 case COND_UN: return "UN";
372 case COND_GE: return "GE";
373 case COND_LE: return "LE";
374 case COND_NE: return "NE";
375 case COND_TR: return "TR";
376 case COND_FL: return "FL";
377 default: return "cond???";
378 }
379 }
380
381
382 static void
383 print_dst_reg(const struct prog_dst_register *dstReg, gl_prog_print_mode mode,
384 const struct gl_program *prog)
385 {
386 _mesa_printf("%s%s",
387 reg_string((enum register_file) dstReg->File,
388 dstReg->Index, mode, prog),
389 writemask_string(dstReg->WriteMask));
390
391 if (dstReg->CondMask != COND_TR) {
392 _mesa_printf(" (%s.%s)",
393 _mesa_condcode_string(dstReg->CondMask),
394 _mesa_swizzle_string(dstReg->CondSwizzle, GL_FALSE, GL_FALSE));
395 }
396
397 #if 0
398 _mesa_printf("%s[%d]%s",
399 file_string((enum register_file) dstReg->File, mode),
400 dstReg->Index,
401 writemask_string(dstReg->WriteMask));
402 #endif
403 }
404
405 static void
406 print_src_reg(const struct prog_src_register *srcReg, gl_prog_print_mode mode,
407 const struct gl_program *prog)
408 {
409 _mesa_printf("%s%s",
410 reg_string((enum register_file) srcReg->File,
411 srcReg->Index, mode, prog),
412 _mesa_swizzle_string(srcReg->Swizzle,
413 srcReg->NegateBase, GL_FALSE));
414 #if 0
415 _mesa_printf("%s[%d]%s",
416 file_string((enum register_file) srcReg->File, mode),
417 srcReg->Index,
418 _mesa_swizzle_string(srcReg->Swizzle,
419 srcReg->NegateBase, GL_FALSE));
420 #endif
421 }
422
423 static void
424 print_comment(const struct prog_instruction *inst)
425 {
426 if (inst->Comment)
427 _mesa_printf("; # %s\n", inst->Comment);
428 else
429 _mesa_printf(";\n");
430 }
431
432
433 static void
434 print_alu_instruction(const struct prog_instruction *inst,
435 const char *opcode_string, GLuint numRegs,
436 gl_prog_print_mode mode,
437 const struct gl_program *prog)
438 {
439 GLuint j;
440
441 _mesa_printf("%s", opcode_string);
442 if (inst->CondUpdate)
443 _mesa_printf(".C");
444
445 /* frag prog only */
446 if (inst->SaturateMode == SATURATE_ZERO_ONE)
447 _mesa_printf("_SAT");
448
449 _mesa_printf(" ");
450 if (inst->DstReg.File != PROGRAM_UNDEFINED) {
451 print_dst_reg(&inst->DstReg, mode, prog);
452 }
453 else {
454 _mesa_printf(" ???");
455 }
456
457 if (numRegs > 0)
458 _mesa_printf(", ");
459
460 for (j = 0; j < numRegs; j++) {
461 print_src_reg(inst->SrcReg + j, mode, prog);
462 if (j + 1 < numRegs)
463 _mesa_printf(", ");
464 }
465
466 print_comment(inst);
467 }
468
469
470 void
471 _mesa_print_alu_instruction(const struct prog_instruction *inst,
472 const char *opcode_string, GLuint numRegs)
473 {
474 print_alu_instruction(inst, opcode_string, numRegs, PROG_PRINT_DEBUG, NULL);
475 }
476
477
478 void
479 _mesa_print_instruction(const struct prog_instruction *inst)
480 {
481 /* note: 4th param should be ignored for PROG_PRINT_DEBUG */
482 _mesa_print_instruction_opt(inst, 0, PROG_PRINT_DEBUG, NULL);
483 }
484
485
486 /**
487 * Print a single vertex/fragment program instruction.
488 */
489 GLint
490 _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
491 gl_prog_print_mode mode,
492 const struct gl_program *prog)
493 {
494 GLint i;
495
496 if (inst->Opcode == OPCODE_ELSE ||
497 inst->Opcode == OPCODE_ENDIF ||
498 inst->Opcode == OPCODE_ENDLOOP ||
499 inst->Opcode == OPCODE_ENDSUB) {
500 indent -= 3;
501 }
502 for (i = 0; i < indent; i++) {
503 _mesa_printf(" ");
504 }
505
506 switch (inst->Opcode) {
507 case OPCODE_PRINT:
508 _mesa_printf("PRINT '%s'", inst->Data);
509 if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
510 _mesa_printf(", ");
511 _mesa_printf("%s[%d]%s",
512 file_string((enum register_file) inst->SrcReg[0].File,
513 mode),
514 inst->SrcReg[0].Index,
515 _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
516 inst->SrcReg[0].NegateBase, GL_FALSE));
517 }
518 if (inst->Comment)
519 _mesa_printf(" # %s", inst->Comment);
520 print_comment(inst);
521 break;
522 case OPCODE_SWZ:
523 _mesa_printf("SWZ");
524 if (inst->SaturateMode == SATURATE_ZERO_ONE)
525 _mesa_printf("_SAT");
526 _mesa_printf(" ");
527 print_dst_reg(&inst->DstReg, mode, prog);
528 _mesa_printf("%s[%d], %s",
529 file_string((enum register_file) inst->SrcReg[0].File,
530 mode),
531 inst->SrcReg[0].Index,
532 _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
533 inst->SrcReg[0].NegateBase, GL_TRUE));
534 print_comment(inst);
535 break;
536 case OPCODE_TEX:
537 case OPCODE_TXP:
538 case OPCODE_TXB:
539 _mesa_printf("%s", _mesa_opcode_string(inst->Opcode));
540 if (inst->SaturateMode == SATURATE_ZERO_ONE)
541 _mesa_printf("_SAT");
542 _mesa_printf(" ");
543 print_dst_reg(&inst->DstReg, mode, prog);
544 _mesa_printf(", ");
545 print_src_reg(&inst->SrcReg[0], mode, prog);
546 _mesa_printf(", texture[%d], ", inst->TexSrcUnit);
547 switch (inst->TexSrcTarget) {
548 case TEXTURE_1D_INDEX: _mesa_printf("1D"); break;
549 case TEXTURE_2D_INDEX: _mesa_printf("2D"); break;
550 case TEXTURE_3D_INDEX: _mesa_printf("3D"); break;
551 case TEXTURE_CUBE_INDEX: _mesa_printf("CUBE"); break;
552 case TEXTURE_RECT_INDEX: _mesa_printf("RECT"); break;
553 default:
554 ;
555 }
556 print_comment(inst);
557 break;
558 case OPCODE_ARL:
559 _mesa_printf("ARL addr.x, ");
560 print_src_reg(&inst->SrcReg[0], mode, prog);
561 print_comment(inst);
562 break;
563 case OPCODE_BRA:
564 _mesa_printf("BRA %d (%s%s)",
565 inst->BranchTarget,
566 _mesa_condcode_string(inst->DstReg.CondMask),
567 _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
568 print_comment(inst);
569 break;
570 case OPCODE_IF:
571 if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
572 /* Use ordinary register */
573 _mesa_printf("IF ");
574 print_src_reg(&inst->SrcReg[0], mode, prog);
575 _mesa_printf("; ");
576 }
577 else {
578 /* Use cond codes */
579 _mesa_printf("IF (%s%s);",
580 _mesa_condcode_string(inst->DstReg.CondMask),
581 _mesa_swizzle_string(inst->DstReg.CondSwizzle,
582 0, GL_FALSE));
583 }
584 _mesa_printf(" # (if false, goto %d)", inst->BranchTarget);
585 print_comment(inst);
586 return indent + 3;
587 case OPCODE_ELSE:
588 _mesa_printf("ELSE; # (goto %d)\n", inst->BranchTarget);
589 return indent + 3;
590 case OPCODE_ENDIF:
591 _mesa_printf("ENDIF;\n");
592 break;
593 case OPCODE_BGNLOOP:
594 _mesa_printf("BGNLOOP; # (end at %d)\n", inst->BranchTarget);
595 return indent + 3;
596 case OPCODE_ENDLOOP:
597 _mesa_printf("ENDLOOP; # (goto %d)\n", inst->BranchTarget);
598 break;
599 case OPCODE_BRK:
600 case OPCODE_CONT:
601 _mesa_printf("%s (%s%s); # (goto %d)",
602 _mesa_opcode_string(inst->Opcode),
603 _mesa_condcode_string(inst->DstReg.CondMask),
604 _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
605 inst->BranchTarget);
606 print_comment(inst);
607 break;
608
609 case OPCODE_BGNSUB:
610 if (mode == PROG_PRINT_NV) {
611 _mesa_printf("%s:\n", inst->Comment); /* comment is label */
612 return indent;
613 }
614 else {
615 _mesa_printf("BGNSUB");
616 print_comment(inst);
617 return indent + 3;
618 }
619 case OPCODE_ENDSUB:
620 if (mode == PROG_PRINT_DEBUG) {
621 _mesa_printf("ENDSUB");
622 print_comment(inst);
623 }
624 break;
625 case OPCODE_CAL:
626 if (mode == PROG_PRINT_NV) {
627 _mesa_printf("CAL %s; # (goto %d)\n", inst->Comment, inst->BranchTarget);
628 }
629 else {
630 _mesa_printf("CAL %u", inst->BranchTarget);
631 print_comment(inst);
632 }
633 break;
634 case OPCODE_RET:
635 _mesa_printf("RET (%s%s)",
636 _mesa_condcode_string(inst->DstReg.CondMask),
637 _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
638 print_comment(inst);
639 break;
640
641 case OPCODE_END:
642 _mesa_printf("END\n");
643 break;
644 case OPCODE_NOP:
645 if (mode == PROG_PRINT_DEBUG) {
646 _mesa_printf("NOP");
647 print_comment(inst);
648 }
649 else if (inst->Comment) {
650 /* ARB/NV extensions don't have NOP instruction */
651 _mesa_printf("# %s\n", inst->Comment);
652 }
653 break;
654 /* XXX may need other special-case instructions */
655 default:
656 /* typical alu instruction */
657 print_alu_instruction(inst,
658 _mesa_opcode_string(inst->Opcode),
659 _mesa_num_inst_src_regs(inst->Opcode),
660 mode, prog);
661 break;
662 }
663 return indent;
664 }
665
666
667 /**
668 * Print program to stdout, default options.
669 */
670 void
671 _mesa_print_program(const struct gl_program *prog)
672 {
673 _mesa_print_program_opt(prog, PROG_PRINT_DEBUG, GL_TRUE);
674 }
675
676
677 /**
678 * Print program, with options.
679 */
680 void
681 _mesa_print_program_opt(const struct gl_program *prog,
682 gl_prog_print_mode mode,
683 GLboolean lineNumbers)
684 {
685 GLuint i, indent = 0;
686
687 switch (prog->Target) {
688 case GL_VERTEX_PROGRAM_ARB:
689 if (mode == PROG_PRINT_ARB)
690 _mesa_printf("!!ARBvp1.0\n");
691 else if (mode == PROG_PRINT_NV)
692 _mesa_printf("!!VP1.0\n");
693 else
694 _mesa_printf("# Vertex Program/Shader\n");
695 break;
696 case GL_FRAGMENT_PROGRAM_ARB:
697 case GL_FRAGMENT_PROGRAM_NV:
698 if (mode == PROG_PRINT_ARB)
699 _mesa_printf("!!ARBfp1.0\n");
700 else if (mode == PROG_PRINT_NV)
701 _mesa_printf("!!FP1.0\n");
702 else
703 _mesa_printf("# Fragment Program/Shader\n");
704 break;
705 }
706
707 for (i = 0; i < prog->NumInstructions; i++) {
708 if (lineNumbers)
709 _mesa_printf("%3d: ", i);
710 indent = _mesa_print_instruction_opt(prog->Instructions + i,
711 indent, mode, prog);
712 }
713 }
714
715
716 /**
717 * Print all of a program's parameters.
718 */
719 void
720 _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
721 {
722 _mesa_printf("InputsRead: 0x%x\n", prog->InputsRead);
723 _mesa_printf("OutputsWritten: 0x%x\n", prog->OutputsWritten);
724 _mesa_printf("NumInstructions=%d\n", prog->NumInstructions);
725 _mesa_printf("NumTemporaries=%d\n", prog->NumTemporaries);
726 _mesa_printf("NumParameters=%d\n", prog->NumParameters);
727 _mesa_printf("NumAttributes=%d\n", prog->NumAttributes);
728 _mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs);
729
730 _mesa_load_state_parameters(ctx, prog->Parameters);
731
732 #if 0
733 _mesa_printf("Local Params:\n");
734 for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){
735 const GLfloat *p = prog->LocalParams[i];
736 _mesa_printf("%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]);
737 }
738 #endif
739 _mesa_print_parameter_list(prog->Parameters);
740 }
741
742
743 void
744 _mesa_print_parameter_list(const struct gl_program_parameter_list *list)
745 {
746 const gl_prog_print_mode mode = PROG_PRINT_DEBUG;
747 GLuint i;
748
749 _mesa_printf("param list %p\n", (void *) list);
750 for (i = 0; i < list->NumParameters; i++){
751 struct gl_program_parameter *param = list->Parameters + i;
752 const GLfloat *v = list->ParameterValues[i];
753 _mesa_printf("param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g};\n",
754 i, param->Size,
755 file_string(list->Parameters[i].Type, mode),
756 param->Name, v[0], v[1], v[2], v[3]);
757 }
758 }