Merge remote branch 'origin/mesa_7_6_branch'
[mesa.git] / src / mesa / shader / prog_print.c
index 9967f2978de819be589ee71a45020ab56a256c51..ba4d39452f4cb4b088cee5ca602aaaa0be351ab4 100644 (file)
@@ -75,7 +75,11 @@ file_string(gl_register_file f, gl_prog_print_mode mode)
    case PROGRAM_UNDEFINED:
       return "UNDEFINED";
    default:
-      return "Unknown program file!";
+      {
+         static char s[20];
+         _mesa_snprintf(s, sizeof(s), "FILE%u", f);
+         return s;
+      }
    }
 }
 
@@ -529,7 +533,7 @@ void
 _mesa_print_alu_instruction(const struct prog_instruction *inst,
                             const char *opcode_string, GLuint numRegs)
 {
-   fprint_alu_instruction(stdout, inst, opcode_string,
+   fprint_alu_instruction(stderr, inst, opcode_string,
                           numRegs, PROG_PRINT_DEBUG, NULL);
 }
 
@@ -537,7 +541,7 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst,
 /**
  * Print a single vertex/fragment program instruction.
  */
-static GLint
+GLint
 _mesa_fprint_instruction_opt(FILE *f,
                             const struct prog_instruction *inst,
                             GLint indent,
@@ -736,7 +740,10 @@ _mesa_fprint_instruction_opt(FILE *f,
                                 mode, prog);
       }
       else {
-         _mesa_fprintf(f, "Other opcode %d\n", inst->Opcode);
+         fprint_alu_instruction(f, inst,
+                                _mesa_opcode_string(inst->Opcode),
+                                3/*_mesa_num_inst_src_regs(inst->Opcode)*/,
+                                mode, prog);
       }
       break;
    }
@@ -750,7 +757,7 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst,
                             gl_prog_print_mode mode,
                             const struct gl_program *prog)
 {
-   return _mesa_fprint_instruction_opt(stdout, inst, indent, mode, prog);
+   return _mesa_fprint_instruction_opt(stderr, inst, indent, mode, prog);
 }
 
 
@@ -758,7 +765,7 @@ void
 _mesa_print_instruction(const struct prog_instruction *inst)
 {
    /* note: 4th param should be ignored for PROG_PRINT_DEBUG */
-   _mesa_fprint_instruction_opt(stdout, inst, 0, PROG_PRINT_DEBUG, NULL);
+   _mesa_fprint_instruction_opt(stderr, inst, 0, PROG_PRINT_DEBUG, NULL);
 }
 
 
@@ -781,7 +788,7 @@ _mesa_fprint_program_opt(FILE *f,
       else if (mode == PROG_PRINT_NV)
          _mesa_fprintf(f, "!!VP1.0\n");
       else
-         _mesa_fprintf(f, "# Vertex Program/Shader\n");
+         _mesa_fprintf(f, "# Vertex Program/Shader %u\n", prog->Id);
       break;
    case GL_FRAGMENT_PROGRAM_ARB:
    case GL_FRAGMENT_PROGRAM_NV:
@@ -790,7 +797,7 @@ _mesa_fprint_program_opt(FILE *f,
       else if (mode == PROG_PRINT_NV)
          _mesa_fprintf(f, "!!FP1.0\n");
       else
-         _mesa_fprintf(f, "# Fragment Program/Shader\n");
+         _mesa_fprintf(f, "# Fragment Program/Shader %u\n", prog->Id);
       break;
    }
 
@@ -804,12 +811,35 @@ _mesa_fprint_program_opt(FILE *f,
 
 
 /**
- * Print program to stdout, default options.
+ * Print program to stderr, default options.
  */
 void
 _mesa_print_program(const struct gl_program *prog)
 {
-   _mesa_fprint_program_opt(stdout, prog, PROG_PRINT_DEBUG, GL_TRUE);
+   _mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE);
+}
+
+
+/**
+ * Return binary representation of value (as a string).
+ * Insert a comma to separate each group of 8 bits.
+ * XXX move to imports.[ch] if useful elsewhere.
+ */
+static const char *
+binary(GLbitfield val)
+{
+   static char buf[50];
+   GLint i, len = 0;
+   for (i = 31; i >= 0; --i) {
+      if (val & (1 << i))
+         buf[len++] = '1';
+      else if (len > 0 || i == 0)
+         buf[len++] = '0';
+      if (len > 0 && ((i-1) % 8) == 7)
+         buf[len++] = ',';
+   }
+   buf[len] = '\0';
+   return buf;
 }
 
 
@@ -823,13 +853,17 @@ _mesa_fprint_program_parameters(FILE *f,
 {
    GLuint i;
 
-   _mesa_fprintf(f, "InputsRead: 0x%x\n", prog->InputsRead);
-   _mesa_fprintf(f, "OutputsWritten: 0x%x\n", prog->OutputsWritten);
+   _mesa_fprintf(f, "InputsRead: 0x%x (0b%s)\n",
+                 prog->InputsRead, binary(prog->InputsRead));
+   _mesa_fprintf(f, "OutputsWritten: 0x%x (0b%s)\n",
+                 prog->OutputsWritten, binary(prog->OutputsWritten));
    _mesa_fprintf(f, "NumInstructions=%d\n", prog->NumInstructions);
    _mesa_fprintf(f, "NumTemporaries=%d\n", prog->NumTemporaries);
    _mesa_fprintf(f, "NumParameters=%d\n", prog->NumParameters);
    _mesa_fprintf(f, "NumAttributes=%d\n", prog->NumAttributes);
    _mesa_fprintf(f, "NumAddressRegs=%d\n", prog->NumAddressRegs);
+   _mesa_fprintf(f, "SamplersUsed: 0x%x (0b%s)\n",
+                 prog->SamplersUsed, binary(prog->SamplersUsed));
    _mesa_fprintf(f, "Samplers=[ ");
    for (i = 0; i < MAX_SAMPLERS; i++) {
       _mesa_fprintf(f, "%d ", prog->SamplerUnits[i]);
@@ -850,12 +884,12 @@ _mesa_fprint_program_parameters(FILE *f,
 
 
 /**
- * Print all of a program's parameters/fields to stdout.
+ * Print all of a program's parameters/fields to stderr.
  */
 void
 _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
 {
-   _mesa_fprint_program_parameters(stdout, ctx, prog);
+   _mesa_fprint_program_parameters(stderr, ctx, prog);
 }
 
 
@@ -872,7 +906,8 @@ _mesa_fprint_parameter_list(FILE *f,
    if (!list)
       return;
 
-   _mesa_fprintf(f, "param list %p\n", (void *) list);
+   if (0)
+      _mesa_fprintf(f, "param list %p\n", (void *) list);
    _mesa_fprintf(f, "dirty state flags: 0x%x\n", list->StateFlags);
    for (i = 0; i < list->NumParameters; i++){
       struct gl_program_parameter *param = list->Parameters + i;
@@ -895,12 +930,12 @@ _mesa_fprint_parameter_list(FILE *f,
 
 
 /**
- * Print a program parameter list to stdout.
+ * Print a program parameter list to stderr.
  */
 void
 _mesa_print_parameter_list(const struct gl_program_parameter_list *list)
 {
-   _mesa_fprint_parameter_list(stdout, list);
+   _mesa_fprint_parameter_list(stderr, list);
 }
 
 
@@ -926,7 +961,7 @@ _mesa_write_shader_to_file(const struct gl_shader *shader)
       return;
    }
 
-   fprintf(f, "/* Shader %u source */\n", shader->Name);
+   fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum);
    fputs(shader->Source, f);
    fprintf(f, "\n");
 
@@ -941,9 +976,45 @@ _mesa_write_shader_to_file(const struct gl_shader *shader)
       fprintf(f, "/*\n");
       _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE);
       fprintf(f, "*/\n");
+      fprintf(f, "/* Parameters / constants */\n");
+      fprintf(f, "/*\n");
+      _mesa_fprint_parameter_list(f, shader->Program->Parameters);
+      fprintf(f, "*/\n");
    }
 
    fclose(f);
 }
 
 
+/**
+ * Append the shader's uniform info/values to the shader log file.
+ * The log file will typically have been created by the
+ * _mesa_write_shader_to_file function.
+ */
+void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader,
+                              const struct gl_program *prog)
+{
+   const char *type;
+   char filename[100];
+   FILE *f;
+
+   if (shader->Type == GL_FRAGMENT_SHADER)
+      type = "frag";
+   else
+      type = "vert";
+
+   _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
+   f = fopen(filename, "a"); /* append */
+   if (!f) {
+      fprintf(stderr, "Unable to open %s for appending\n", filename);
+      return;
+   }
+
+   fprintf(f, "/* First-draw parameters / constants */\n");
+   fprintf(f, "/*\n");
+   _mesa_fprint_parameter_list(f, prog->Parameters);
+   fprintf(f, "*/\n");
+
+   fclose(f);
+}