summaryrefslogtreecommitdiffstats
path: root/src/mesa/shader
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2004-12-16 03:07:18 +0000
committerBrian Paul <[email protected]>2004-12-16 03:07:18 +0000
commit575700fbdcdde9c31ee6ccdd0369604b8ee2df91 (patch)
tree2bc35036e7f335f2dfa7211334108ce8bd34fbb3 /src/mesa/shader
parentc75900e7a2ad17ecf832e7e9aa41e714a1a78f2a (diff)
Experimental PRINT instruction for NV_vertex_program.
Basically, this lets you put a "PRINT 'mesage', register;" statement in a vertex program to aid in debugging.
Diffstat (limited to 'src/mesa/shader')
-rw-r--r--src/mesa/shader/arbvertparse.c7
-rw-r--r--src/mesa/shader/nvvertexec.c18
-rw-r--r--src/mesa/shader/nvvertparse.c114
-rw-r--r--src/mesa/shader/nvvertprog.h9
-rw-r--r--src/mesa/shader/program.c9
5 files changed, 149 insertions, 8 deletions
diff --git a/src/mesa/shader/arbvertparse.c b/src/mesa/shader/arbvertparse.c
index fb6a642b647..33086c2f723 100644
--- a/src/mesa/shader/arbvertparse.c
+++ b/src/mesa/shader/arbvertparse.c
@@ -44,6 +44,10 @@
#include "arbprogparse.h"
+/**
+ * XXX this is probably redundant. We've already got code like this
+ * in the nvvertparse.c file. Combine/clean-up someday.
+ */
static GLvoid
debug_vp_inst(GLint num, struct vp_instruction *vp)
{
@@ -135,6 +139,9 @@ debug_vp_inst(GLint num, struct vp_instruction *vp)
case VP_OPCODE_SWZ:
fprintf(stderr, "VP_OPCODE_SWZ"); break;
+ case VP_OPCODE_PRINT:
+ fprintf(stderr, "VP_OPCODE_PRINT"); break;
+
case VP_OPCODE_END:
fprintf(stderr, "VP_OPCODE_END"); break;
}
diff --git a/src/mesa/shader/nvvertexec.c b/src/mesa/shader/nvvertexec.c
index 269c4c93d8c..064a7f020b9 100644
--- a/src/mesa/shader/nvvertexec.c
+++ b/src/mesa/shader/nvvertexec.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.1
+ * Version: 6.3
*
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
@@ -249,6 +249,10 @@ get_register_pointer( const struct vp_src_register *source,
case PROGRAM_INPUT:
ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_INPUTS);
return state->Inputs[source->Index];
+ case PROGRAM_OUTPUT:
+ /* This is only needed for the PRINT instruction */
+ ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
+ return state->Outputs[source->Index];
case PROGRAM_LOCAL_PARAM:
ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);
return state->Current->Base.LocalParams[source->Index];
@@ -774,7 +778,17 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
store_vector4( &inst->DstReg, state, result );
}
break;
-
+ case VP_OPCODE_PRINT:
+ if (inst->SrcReg[0].File) {
+ GLfloat t[4];
+ fetch_vector4( &inst->SrcReg[0], state, t );
+ _mesa_printf("%s%g, %g, %g, %g\n",
+ (char *) inst->Data, t[0], t[1], t[2], t[3]);
+ }
+ else {
+ _mesa_printf("%s\n", (char *) inst->Data);
+ }
+ break;
case VP_OPCODE_END:
ctx->_CurrentProgram = 0;
return;
diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c
index 7e8e749d8cc..e84cf9d5049 100644
--- a/src/mesa/shader/nvvertparse.c
+++ b/src/mesa/shader/nvvertparse.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.1
+ * Version: 6.3
*
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
@@ -299,6 +299,8 @@ static const char *Opcodes[] = {
"ABS", "END",
/* GL_ARB_vertex_program */
"FLR", "FRC", "EX2", "LG2", "POW", "XPD", "SWZ",
+ /* Mesa-specific */
+ "PRINT",
NULL
};
@@ -1019,6 +1021,98 @@ Parse_EndInstruction(struct parse_state *parseState, struct vp_instruction *inst
}
+/**
+ * The PRINT instruction is Mesa-specific and is meant as a debugging aid for
+ * the vertex program developer.
+ * The NV_vertex_program extension grammar is modified as follows:
+ *
+ * <instruction> ::= <ARL-instruction>
+ * | ...
+ * | <PRINT-instruction>
+ *
+ * <PRINT-instruction> ::= "PRINT" <string literal>
+ * | "PRINT" <string literal> "," <srcReg>
+ * | "PRINT" <string literal> "," <dstReg>
+ */
+static GLboolean
+Parse_PrintInstruction(struct parse_state *parseState, struct vp_instruction *inst)
+{
+ const GLubyte *str;
+ GLubyte *msg;
+ GLuint len;
+ GLubyte token[100];
+ struct vp_src_register *srcReg = &inst->SrcReg[0];
+
+ inst->Opcode = VP_OPCODE_PRINT;
+ inst->StringPos = parseState->curLine - parseState->start;
+
+ /* The first argument is a literal string 'just like this' */
+ if (!Parse_String(parseState, "'"))
+ RETURN_ERROR;
+
+ str = parseState->pos;
+ for (len = 0; str[len] != '\''; len++) /* find closing quote */
+ ;
+ parseState->pos += len + 1;
+ msg = _mesa_malloc(len + 1);
+
+ _mesa_memcpy(msg, str, len);
+ msg[len] = 0;
+ inst->Data = msg;
+
+ /* comma */
+ if (Parse_String(parseState, ",")) {
+
+ /* The second argument is a register name */
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+
+ srcReg->RelAddr = GL_FALSE;
+ srcReg->Negate = GL_FALSE;
+ srcReg->Swizzle[0] = 0;
+ srcReg->Swizzle[1] = 1;
+ srcReg->Swizzle[2] = 2;
+ srcReg->Swizzle[3] = 3;
+
+ /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,
+ * or an o[n] output register.
+ */
+ if (token[0] == 'R') {
+ srcReg->File = PROGRAM_TEMPORARY;
+ if (!Parse_TempReg(parseState, &srcReg->Index))
+ RETURN_ERROR;
+ }
+ else if (token[0] == 'c') {
+ srcReg->File = PROGRAM_ENV_PARAM;
+ if (!Parse_ParamReg(parseState, srcReg))
+ RETURN_ERROR;
+ }
+ else if (token[0] == 'v') {
+ srcReg->File = PROGRAM_INPUT;
+ if (!Parse_AttribReg(parseState, &srcReg->Index))
+ RETURN_ERROR;
+ }
+ else if (token[0] == 'o') {
+ srcReg->File = PROGRAM_OUTPUT;
+ if (!Parse_OutputReg(parseState, &srcReg->Index))
+ RETURN_ERROR;
+ }
+ else {
+ RETURN_ERROR2("Bad source register name", token);
+ }
+ }
+ else {
+ srcReg->File = 0;
+ }
+
+ /* semicolon */
+ if (!Parse_String(parseState, ";"))
+ RETURN_ERROR;
+
+ return GL_TRUE;
+}
+
+
static GLboolean
Parse_OptionSequence(struct parse_state *parseState,
struct vp_instruction program[])
@@ -1051,6 +1145,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
inst->SrcReg[1].File = (enum register_file) -1;
inst->SrcReg[2].File = (enum register_file) -1;
inst->DstReg.File = (enum register_file) -1;
+ inst->Data = NULL;
if (Parse_String(parseState, "MOV")) {
if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV))
@@ -1136,6 +1231,10 @@ Parse_InstructionSequence(struct parse_state *parseState,
if (!Parse_AddressInstruction(parseState, inst))
RETURN_ERROR;
}
+ else if (Parse_String(parseState, "PRINT")) {
+ if (!Parse_PrintInstruction(parseState, inst))
+ RETURN_ERROR;
+ }
else if (Parse_String(parseState, "END")) {
if (!Parse_EndInstruction(parseState, inst))
RETURN_ERROR;
@@ -1303,7 +1402,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
program->IsPositionInvariant = parseState.isPositionInvariant;
program->IsNVProgram = GL_TRUE;
-#ifdef DEBUG_foo
+#ifdef DEBUG
_mesa_printf("--- glLoadProgramNV result ---\n");
_mesa_print_nv_vertex_program(program);
_mesa_printf("------------------------------\n");
@@ -1457,6 +1556,17 @@ _mesa_print_nv_vertex_instruction(const struct vp_instruction *inst)
PrintSrcReg(&inst->SrcReg[0]);
_mesa_printf(";\n");
break;
+ case VP_OPCODE_PRINT:
+ _mesa_printf("PRINT '%s'", inst->Data);
+ if (inst->SrcReg[0].File) {
+ _mesa_printf(", ");
+ PrintSrcReg(&inst->SrcReg[0]);
+ _mesa_printf(";\n");
+ }
+ else {
+ _mesa_printf("\n");
+ }
+ break;
case VP_OPCODE_END:
_mesa_printf("END\n");
break;
diff --git a/src/mesa/shader/nvvertprog.h b/src/mesa/shader/nvvertprog.h
index 820b3e5692b..583b9012079 100644
--- a/src/mesa/shader/nvvertprog.h
+++ b/src/mesa/shader/nvvertprog.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 5.1
+ * Version: 6.3
*
- * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -66,7 +66,9 @@ enum vp_opcode
VP_OPCODE_LG2,
VP_OPCODE_POW,
VP_OPCODE_XPD,
- VP_OPCODE_SWZ
+ VP_OPCODE_SWZ,
+ /* Special Mesa opcodes */
+ VP_OPCODE_PRINT
};
@@ -101,6 +103,7 @@ struct vp_instruction
#if FEATURE_MESA_program_debug
GLint StringPos;
#endif
+ void *Data; /* some arbitrary data, only used for PRINT instruction now */
};
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index c2f4b146b6c..ca0421181ce 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -39,6 +39,7 @@
#include "nvfragparse.h"
#include "nvfragprog.h"
#include "nvvertparse.h"
+#include "nvvertprog.h"
/**********************************************************************/
@@ -263,8 +264,14 @@ _mesa_delete_program(GLcontext *ctx, struct program *prog)
if (prog->Target == GL_VERTEX_PROGRAM_NV ||
prog->Target == GL_VERTEX_STATE_PROGRAM_NV) {
struct vertex_program *vprog = (struct vertex_program *) prog;
- if (vprog->Instructions)
+ if (vprog->Instructions) {
+ GLuint i;
+ for (i = 0; i < vprog->Base.NumInstructions; i++) {
+ if (vprog->Instructions[i].Data)
+ _mesa_free(vprog->Instructions[i].Data);
+ }
_mesa_free(vprog->Instructions);
+ }
if (vprog->Parameters)
_mesa_free_parameter_list(vprog->Parameters);
}