+/**
+ * Return ARB_v/f_prog-style input attrib string.
+ */
+static const char *
+arb_input_attrib_string(GLint index, GLenum progType)
+{
+ const char *vertAttribs[] = {
+ "vertex.position",
+ "vertex.weight",
+ "vertex.normal",
+ "vertex.color.primary",
+ "vertex.color.secondary",
+ "vertex.fogcoord",
+ "vertex.(six)",
+ "vertex.(seven)",
+ "vertex.texcoord[0]",
+ "vertex.texcoord[1]",
+ "vertex.texcoord[2]",
+ "vertex.texcoord[3]",
+ "vertex.texcoord[4]",
+ "vertex.texcoord[5]",
+ "vertex.texcoord[6]",
+ "vertex.texcoord[7]",
+ "vertex.attrib[0]",
+ "vertex.attrib[1]",
+ "vertex.attrib[2]",
+ "vertex.attrib[3]",
+ "vertex.attrib[4]",
+ "vertex.attrib[5]",
+ "vertex.attrib[6]",
+ "vertex.attrib[7]",
+ "vertex.attrib[8]",
+ "vertex.attrib[9]",
+ "vertex.attrib[10]",
+ "vertex.attrib[11]",
+ "vertex.attrib[12]",
+ "vertex.attrib[13]",
+ "vertex.attrib[14]",
+ "vertex.attrib[15]"
+ };
+ const char *fragAttribs[] = {
+ "fragment.position",
+ "fragment.color.primary",
+ "fragment.color.secondary",
+ "fragment.fogcoord",
+ "fragment.texcoord[0]",
+ "fragment.texcoord[1]",
+ "fragment.texcoord[2]",
+ "fragment.texcoord[3]",
+ "fragment.texcoord[4]",
+ "fragment.texcoord[5]",
+ "fragment.texcoord[6]",
+ "fragment.texcoord[7]",
+ "fragment.varying[0]",
+ "fragment.varying[1]",
+ "fragment.varying[2]",
+ "fragment.varying[3]",
+ "fragment.varying[4]",
+ "fragment.varying[5]",
+ "fragment.varying[6]",
+ "fragment.varying[7]"
+ };
+
+ if (progType == GL_VERTEX_PROGRAM_ARB) {
+ assert(index < sizeof(vertAttribs) / sizeof(vertAttribs[0]));
+ return vertAttribs[index];
+ }
+ else {
+ assert(index < sizeof(fragAttribs) / sizeof(fragAttribs[0]));
+ return fragAttribs[index];
+ }
+}
+
+
+/**
+ * Return ARB_v/f_prog-style output attrib string.
+ */
+static const char *
+arb_output_attrib_string(GLint index, GLenum progType)
+{
+ const char *vertResults[] = {
+ "result.position",
+ "result.color.primary",
+ "result.color.secondary",
+ "result.fogcoord",
+ "result.texcoord[0]",
+ "result.texcoord[1]",
+ "result.texcoord[2]",
+ "result.texcoord[3]",
+ "result.texcoord[4]",
+ "result.texcoord[5]",
+ "result.texcoord[6]",
+ "result.texcoord[7]",
+ "result.varying[0]",
+ "result.varying[1]",
+ "result.varying[2]",
+ "result.varying[3]",
+ "result.varying[4]",
+ "result.varying[5]",
+ "result.varying[6]",
+ "result.varying[7]"
+ };
+ const char *fragResults[] = {
+ "result.color",
+ "result.depth"
+ };
+
+ if (progType == GL_VERTEX_PROGRAM_ARB) {
+ assert(index < sizeof(vertResults) / sizeof(vertResults[0]));
+ return vertResults[index];
+ }
+ else {
+ assert(index < sizeof(fragResults) / sizeof(fragResults[0]));
+ return fragResults[index];
+ }
+}
+
+
+/**
+ * Return string representation of the given register.
+ * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined
+ * by the ARB/NV program languages so we've taken some liberties here.
+ * \param file the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc)
+ * \param index number of the register in the register file
+ * \param mode the output format/mode/style
+ * \param prog pointer to containing program
+ */
+static const char *
+reg_string(enum register_file f, GLint index, gl_prog_print_mode mode,
+ GLboolean relAddr, const struct gl_program *prog)
+{
+ static char str[100];
+
+ str[0] = 0;
+
+ switch (mode) {
+ case PROG_PRINT_DEBUG:
+ if (relAddr)
+ sprintf(str, "%s[ADDR+%d]", file_string(f, mode), index);
+ else
+ sprintf(str, "%s[%d]", file_string(f, mode), index);
+ break;
+
+ case PROG_PRINT_ARB:
+ switch (f) {
+ case PROGRAM_INPUT:
+ sprintf(str, "%s", arb_input_attrib_string(index, prog->Target));
+ break;
+ case PROGRAM_OUTPUT:
+ sprintf(str, "%s", arb_output_attrib_string(index, prog->Target));
+ break;
+ case PROGRAM_TEMPORARY:
+ sprintf(str, "temp%d", index);
+ break;
+ case PROGRAM_ENV_PARAM:
+ sprintf(str, "program.env[%d]", index);
+ break;
+ case PROGRAM_LOCAL_PARAM:
+ sprintf(str, "program.local[%d]", index);
+ break;
+ case PROGRAM_VARYING: /* extension */
+ sprintf(str, "varying[%d]", index);
+ break;
+ case PROGRAM_CONSTANT: /* extension */
+ sprintf(str, "constant[%d]", index);
+ break;
+ case PROGRAM_UNIFORM: /* extension */
+ sprintf(str, "uniform[%d]", index);
+ break;
+ case PROGRAM_STATE_VAR:
+ {
+ struct gl_program_parameter *param
+ = prog->Parameters->Parameters + index;
+ char *state = _mesa_program_state_string(param->StateIndexes);
+ sprintf(str, state);
+ _mesa_free(state);
+ }
+ break;
+ case PROGRAM_ADDRESS:
+ sprintf(str, "A%d", index);
+ break;
+ default:
+ _mesa_problem(NULL, "bad file in reg_string()");
+ }
+ break;
+
+ case PROG_PRINT_NV:
+ switch (f) {
+ case PROGRAM_INPUT:
+ if (prog->Target == GL_VERTEX_PROGRAM_ARB)
+ sprintf(str, "v[%d]", index);
+ else
+ sprintf(str, "f[%d]", index);
+ break;
+ case PROGRAM_OUTPUT:
+ sprintf(str, "o[%d]", index);
+ break;
+ case PROGRAM_TEMPORARY:
+ sprintf(str, "R%d", index);
+ break;
+ case PROGRAM_ENV_PARAM:
+ sprintf(str, "c[%d]", index);
+ break;
+ case PROGRAM_VARYING: /* extension */
+ sprintf(str, "varying[%d]", index);
+ break;
+ case PROGRAM_UNIFORM: /* extension */
+ sprintf(str, "uniform[%d]", index);
+ break;
+ case PROGRAM_CONSTANT: /* extension */
+ sprintf(str, "constant[%d]", index);
+ break;
+ case PROGRAM_STATE_VAR: /* extension */
+ sprintf(str, "state[%d]", index);
+ break;
+ default:
+ _mesa_problem(NULL, "bad file in reg_string()");
+ }
+ break;
+
+ default:
+ _mesa_problem(NULL, "bad mode in reg_string()");
+ }
+
+ return str;
+}
+
+