Improve _mesa_print_program().
authorBrian Paul <brian.paul@tungstengraphics.com>
Sat, 12 Nov 2005 23:25:49 +0000 (23:25 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sat, 12 Nov 2005 23:25:49 +0000 (23:25 +0000)
Added make_state_string() to produce a string from a GL state vector.

src/mesa/shader/program.c

index a9b84fc754e5a283edce599671bea43318d07e3a..6e0805c3cb2d1ac161558b2c1e166a3c512b7d8b 100644 (file)
 #include "atifragshader.h"
 
 
+static const char *
+make_state_string(const GLint stateTokens[6]);
+
+
 /**********************************************************************/
 /* Utility functions                                                  */
 /**********************************************************************/
@@ -474,8 +478,9 @@ _mesa_add_state_reference(struct program_parameter_list *paramList,
     * the new state reference is already present.
     */
    GLint index;
+   const char *name = make_state_string(stateTokens);
 
-   index = add_parameter(paramList, NULL, NULL, PROGRAM_STATE_VAR);
+   index = add_parameter(paramList, name, NULL, PROGRAM_STATE_VAR);
    if (index >= 0) {
       GLuint i;
       for (i = 0; i < 6; i++)
@@ -921,6 +926,273 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[],
 }
 
 
+static void
+append(char *dst, const char *src)
+{
+   while (*dst)
+      dst++;
+   while (*src)
+     *dst++ = *src++;
+   *dst = 0;
+}
+
+static void
+append_token(char *dst, enum state_index k)
+{
+   switch (k) {
+   case STATE_MATERIAL:
+      append(dst, "material.");
+      break;
+   case STATE_LIGHT:
+      append(dst, "light");
+      break;
+   case STATE_LIGHTMODEL_AMBIENT:
+      append(dst, "lightmodel.ambient");
+      break;
+   case STATE_LIGHTMODEL_SCENECOLOR:
+      break;
+   case STATE_LIGHTPROD:
+      append(dst, "lightprod");
+      break;
+   case STATE_TEXGEN:
+      append(dst, "texgen");
+      break;
+   case STATE_FOG_COLOR:
+      append(dst, "fog.color");
+      break;
+   case STATE_FOG_PARAMS:
+      append(dst, "fog.params");
+      break;
+   case STATE_CLIPPLANE:
+      append(dst, "clip");
+      break;
+   case STATE_POINT_SIZE:
+      append(dst, "point.size");
+      break;
+   case STATE_POINT_ATTENUATION:
+      append(dst, "point.attenuation");
+      break;
+   case STATE_MATRIX:
+      append(dst, "matrix.");
+      break;
+   case STATE_MODELVIEW:
+      append(dst, "modelview");
+      break;
+   case STATE_PROJECTION:
+      append(dst, "projection");
+      break;
+   case STATE_MVP:
+      append(dst, "mvp");
+      break;
+   case STATE_TEXTURE:
+      append(dst, "texture");
+      break;
+   case STATE_PROGRAM:
+      append(dst, "program");
+      break;
+   case STATE_MATRIX_INVERSE:
+      append(dst, ".inverse");
+      break;
+   case STATE_MATRIX_TRANSPOSE:
+      append(dst, ".transpose");
+      break;
+   case STATE_MATRIX_INVTRANS:
+      append(dst, ".invtrans");
+      break;
+   case STATE_AMBIENT:
+      append(dst, "ambient");
+      break;
+   case STATE_DIFFUSE:
+      append(dst, "diffuse");
+      break;
+   case STATE_SPECULAR:
+      append(dst, "specular");
+      break;
+   case STATE_EMISSION:
+      append(dst, "emission");
+      break;
+   case STATE_SHININESS:
+      append(dst, "shininess");
+      break;
+   case STATE_HALF:
+      append(dst, "half");
+      break;
+   case STATE_POSITION:
+      append(dst, ".position");
+      break;
+   case STATE_ATTENUATION:
+      append(dst, ".attenuation");
+      break;
+   case STATE_SPOT_DIRECTION:
+      append(dst, ".spot.direction");
+      break;
+   case STATE_TEXGEN_EYE_S:
+      append(dst, "eye.s");
+      break;
+   case STATE_TEXGEN_EYE_T:
+      append(dst, "eye.t");
+      break;
+   case STATE_TEXGEN_EYE_R:
+      append(dst, "eye.r");
+      break;
+   case STATE_TEXGEN_EYE_Q:
+      append(dst, "eye.q");
+      break;
+   case STATE_TEXGEN_OBJECT_S:
+      append(dst, "object.s");
+      break;
+   case STATE_TEXGEN_OBJECT_T:
+      append(dst, "object.t");
+      break;
+   case STATE_TEXGEN_OBJECT_R:
+      append(dst, "object.r");
+      break;
+   case STATE_TEXGEN_OBJECT_Q:
+      append(dst, "object.q");
+      break;
+   case STATE_TEXENV_COLOR:
+      append(dst, "texenv");
+      break;
+   case STATE_DEPTH_RANGE:
+      append(dst, "depth.range");
+      break;
+   case STATE_VERTEX_PROGRAM:
+   case STATE_FRAGMENT_PROGRAM:
+      break;
+   case STATE_ENV:
+      append(dst, "env");
+      break;
+   case STATE_LOCAL:
+      append(dst, "local");
+      break;
+   case STATE_INTERNAL:
+   case STATE_NORMAL_SCALE:
+   case STATE_POSITION_NORMALIZED:
+      append(dst, "(internal)");
+      break;
+   default:
+      ;
+   }
+}
+
+static void
+append_face(char *dst, GLint face)
+{
+   if (face == 0)
+      append(dst, "front.");
+   else
+      append(dst, "back.");
+}
+
+static void
+append_index(char *dst, GLint index)
+{
+   char s[20];
+   _mesa_sprintf(s, "[%d].", index);
+   append(dst, s);
+}
+
+/**
+ * Make a string from the given state vector.
+ * For example, return "state.matrix.texture[2].inverse".
+ */
+static const char *
+make_state_string(const GLint state[6])
+{
+   char str[1000] = "";
+   char tmp[30];
+
+   append(str, "state.");
+   append_token(str, state[0]);
+
+   switch (state[0]) {
+   case STATE_MATERIAL:
+      append_face(str, state[1]);
+      append_token(str, state[2]);
+      break;
+   case STATE_LIGHT:
+      append(str, "light");
+      append_index(str, state[1]); /* light number [i]. */
+      append_token(str, state[2]); /* coefficients */
+      break;
+   case STATE_LIGHTMODEL_AMBIENT:
+      append(str, "lightmodel.ambient");
+      break;
+   case STATE_LIGHTMODEL_SCENECOLOR:
+      if (state[1] == 0) {
+         append(str, "lightmodel.front.scenecolor");
+      }
+      else {
+         append(str, "lightmodel.back.scenecolor");
+      }
+      break;
+   case STATE_LIGHTPROD:
+      append_index(str, state[1]); /* light number [i]. */
+      append_face(str, state[2]);
+      append_token(str, state[3]);
+      break;
+   case STATE_TEXGEN:
+      append_index(str, state[1]); /* tex unit [i] */
+      append_token(str, state[2]); /* plane coef */
+      break;
+   case STATE_TEXENV_COLOR:
+      append_index(str, state[1]); /* tex unit [i] */
+      append(str, "color");
+      break;
+   case STATE_FOG_COLOR:
+   case STATE_FOG_PARAMS:
+      break;
+   case STATE_CLIPPLANE:
+      append_index(str, state[1]); /* plane [i] */
+      append(str, "plane");
+      break;
+   case STATE_POINT_SIZE:
+   case STATE_POINT_ATTENUATION:
+      break;
+   case STATE_MATRIX:
+      {
+         /* state[1] = modelview, projection, texture, etc. */
+         /* state[2] = which texture matrix or program matrix */
+         /* state[3] = first column to fetch */
+         /* state[4] = last column to fetch */
+         /* state[5] = transpose, inverse or invtrans */
+         const enum state_index mat = state[1];
+         const GLuint index = (GLuint) state[2];
+         const GLuint first = (GLuint) state[3];
+         const GLuint last = (GLuint) state[4];
+         const enum state_index modifier = state[5];
+         append_token(str, mat);
+         if (index)
+            append_index(str, index);
+         if (modifier)
+            append_token(str, modifier);
+         if (first == last)
+            _mesa_sprintf(tmp, ".row[%d]", first);
+         else
+            _mesa_sprintf(tmp, ".row[%d..%d]", first, last);
+         append(str, tmp);
+      }
+      break;
+   case STATE_DEPTH_RANGE:
+      break;
+   case STATE_FRAGMENT_PROGRAM:
+   case STATE_VERTEX_PROGRAM:
+      /* state[1] = {STATE_ENV, STATE_LOCAL} */
+      /* state[2] = parameter index          */
+      append_token(str, state[1]);
+      append_index(str, state[2]);
+      break;
+   case STATE_INTERNAL:
+      break;
+   default:
+      _mesa_problem(NULL, "Invalid state in maka_state_string");
+      break;
+   }
+
+   return _mesa_strdup(str);
+}
+
+
 /**
  * Loop over all the parameters in a parameter list.  If the parameter
  * is a GL state reference, look up the current value of that state
@@ -1101,31 +1373,45 @@ program_file_string(enum register_file f)
 
 /**
  * Return a string representation of the given swizzle word.
+ * If extended is true, use extended (comma-separated) format.
  */
 static const char *
-swizzle_string(GLuint swizzle, GLuint negateBase)
+swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended)
 {
    static const char swz[] = "xyzw01";
    static char s[20];
    GLuint i = 0;
 
-   if (swizzle == SWIZZLE_NOOP && negateBase == 0)
+   if (!extended && swizzle == SWIZZLE_NOOP && negateBase == 0)
       return ""; /* no swizzle/negation */
 
-   s[i++] = '.';
+   if (!extended)
+      s[i++] = '.';
 
    if (negateBase & 0x1)
       s[i++] = '-';
    s[i++] = swz[GET_SWZ(swizzle, 0)];
 
+   if (extended) {
+      s[i++] = ',';
+   }
+
    if (negateBase & 0x2)
       s[i++] = '-';
    s[i++] = swz[GET_SWZ(swizzle, 1)];
 
+   if (extended) {
+      s[i++] = ',';
+   }
+
    if (negateBase & 0x4)
       s[i++] = '-';
    s[i++] = swz[GET_SWZ(swizzle, 2)];
 
+   if (extended) {
+      s[i++] = ',';
+   }
+
    if (negateBase & 0x8)
       s[i++] = '-';
    s[i++] = swz[GET_SWZ(swizzle, 3)];
@@ -1158,6 +1444,25 @@ writemask_string(GLuint writeMask)
    return s;
 }
 
+static void
+print_dst_reg(const struct prog_dst_register *dstReg)
+{
+   _mesa_printf(" %s[%d]%s",
+                program_file_string(dstReg->File),
+                dstReg->Index,
+                writemask_string(dstReg->WriteMask));
+}
+
+static void
+print_src_reg(const struct prog_src_register *srcReg)
+{
+   _mesa_printf("%s[%d]%s",
+                program_file_string(srcReg->File),
+                srcReg->Index,
+                swizzle_string(srcReg->Swizzle,
+                               srcReg->NegateBase, GL_FALSE));
+}
+
 
 /**
  * Print a single vertex/fragment program instruction.
@@ -1174,11 +1479,49 @@ _mesa_print_instruction(const struct prog_instruction *inst)
                       program_file_string(inst->SrcReg[0].File),
                       inst->SrcReg[0].Index,
                       swizzle_string(inst->SrcReg[0].Swizzle,
-                                     inst->SrcReg[0].NegateBase));
+                                     inst->SrcReg[0].NegateBase, GL_FALSE));
       }
       _mesa_printf(";\n");
       break;
-   /* XXX check for a bunch of other special-case instructions */
+   case OPCODE_SWZ:
+      _mesa_printf("SWZ");
+      if (inst->Saturate)
+         _mesa_printf("_SAT");
+      print_dst_reg(&inst->DstReg);
+      _mesa_printf("%s[%d], %s;\n",
+                   program_file_string(inst->SrcReg[0].File),
+                   inst->SrcReg[0].Index,
+                   swizzle_string(inst->SrcReg[0].Swizzle,
+                                  inst->SrcReg[0].NegateBase, GL_TRUE));
+      break;
+   case OPCODE_TEX:
+   case OPCODE_TXP:
+   case OPCODE_TXB:
+      _mesa_printf("%s", _mesa_opcode_string(inst->Opcode));
+      if (inst->Saturate)
+         _mesa_printf("_SAT");
+      _mesa_printf(" ");
+      print_dst_reg(&inst->DstReg);
+      _mesa_printf(", ");
+      print_src_reg(&inst->SrcReg[0]);
+      _mesa_printf(", texture[%d], ", inst->TexSrcUnit);
+      switch (inst->TexSrcTarget) {
+      case TEXTURE_1D_INDEX:   _mesa_printf("1D");    break;
+      case TEXTURE_2D_INDEX:   _mesa_printf("2D");    break;
+      case TEXTURE_3D_INDEX:   _mesa_printf("3D");    break;
+      case TEXTURE_CUBE_INDEX: _mesa_printf("CUBE");  break;
+      case TEXTURE_RECT_INDEX: _mesa_printf("RECT");  break;
+      default:
+         ;
+      }
+      _mesa_printf("\n");
+      break;
+   case OPCODE_ARL:
+      _mesa_printf("ARL addr.x, ");
+      print_src_reg(&inst->SrcReg[0]);
+      _mesa_printf(";\n");
+      break;
+   /* XXX may need for other special-case instructions */
    default:
       /* typical alu instruction */
       {
@@ -1202,11 +1545,7 @@ _mesa_print_instruction(const struct prog_instruction *inst)
             _mesa_printf(", ");
 
          for (j = 0; j < numRegs; j++) {
-            _mesa_printf("%s[%d]%s",
-                         program_file_string(inst->SrcReg[j].File),
-                         inst->SrcReg[j].Index,
-                         swizzle_string(inst->SrcReg[j].Swizzle,
-                                        inst->SrcReg[j].NegateBase));
+            print_src_reg(inst->SrcReg + j);
             if (j + 1 < numRegs)
                _mesa_printf(", ");
          }
@@ -1257,26 +1596,10 @@ _mesa_print_program_parameters(GLcontext *ctx, const struct program *prog)
 #endif 
 
    for (i = 0; i < prog->Parameters->NumParameters; i++){
-      const GLfloat *p = prog->Parameters->ParameterValues[i];
-      _mesa_printf("param %02d:", i);
-               
-      switch (prog->Parameters->Parameters[i].Type) {
-      case PROGRAM_NAMED_PARAM:
-         _mesa_printf("%s", prog->Parameters->Parameters[i].Name);
-         _mesa_printf("(NAMED_PARAMETER)");
-         break;
-      case PROGRAM_CONSTANT:
-         _mesa_printf("(CONSTANT)");
-         break;
-      case PROGRAM_STATE_VAR:
-         _mesa_printf("(STATE)\n");
-         break;
-      default:
-         _mesa_printf("(UNK)\n");
-         break;
-      }
-      
-      _mesa_printf("{ %f, %f, %f, %f }\n", p[0], p[1], p[2], p[3]);
+      struct program_parameter *param = prog->Parameters->Parameters + i;
+      const GLfloat *v = prog->Parameters->ParameterValues[i];
+      _mesa_printf("param[%d] %s = {%.3f, %.3f, %.3f, %.3f};\n",
+                   i, param->Name, v[0], v[1], v[2], v[3]);
    }
 }