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.
This commit is contained in:
@@ -44,6 +44,10 @@
|
|||||||
#include "arbprogparse.h"
|
#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
|
static GLvoid
|
||||||
debug_vp_inst(GLint num, struct vp_instruction *vp)
|
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:
|
case VP_OPCODE_SWZ:
|
||||||
fprintf(stderr, "VP_OPCODE_SWZ"); break;
|
fprintf(stderr, "VP_OPCODE_SWZ"); break;
|
||||||
|
|
||||||
|
case VP_OPCODE_PRINT:
|
||||||
|
fprintf(stderr, "VP_OPCODE_PRINT"); break;
|
||||||
|
|
||||||
case VP_OPCODE_END:
|
case VP_OPCODE_END:
|
||||||
fprintf(stderr, "VP_OPCODE_END"); break;
|
fprintf(stderr, "VP_OPCODE_END"); break;
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
* Version: 6.1
|
* Version: 6.3
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
|
* 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:
|
case PROGRAM_INPUT:
|
||||||
ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_INPUTS);
|
ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_INPUTS);
|
||||||
return state->Inputs[source->Index];
|
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:
|
case PROGRAM_LOCAL_PARAM:
|
||||||
ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);
|
ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS);
|
||||||
return state->Current->Base.LocalParams[source->Index];
|
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 );
|
store_vector4( &inst->DstReg, state, result );
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case VP_OPCODE_END:
|
||||||
ctx->_CurrentProgram = 0;
|
ctx->_CurrentProgram = 0;
|
||||||
return;
|
return;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
* Version: 6.1
|
* Version: 6.3
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
|
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
|
||||||
*
|
*
|
||||||
@@ -299,6 +299,8 @@ static const char *Opcodes[] = {
|
|||||||
"ABS", "END",
|
"ABS", "END",
|
||||||
/* GL_ARB_vertex_program */
|
/* GL_ARB_vertex_program */
|
||||||
"FLR", "FRC", "EX2", "LG2", "POW", "XPD", "SWZ",
|
"FLR", "FRC", "EX2", "LG2", "POW", "XPD", "SWZ",
|
||||||
|
/* Mesa-specific */
|
||||||
|
"PRINT",
|
||||||
NULL
|
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
|
static GLboolean
|
||||||
Parse_OptionSequence(struct parse_state *parseState,
|
Parse_OptionSequence(struct parse_state *parseState,
|
||||||
struct vp_instruction program[])
|
struct vp_instruction program[])
|
||||||
@@ -1051,6 +1145,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
|
|||||||
inst->SrcReg[1].File = (enum register_file) -1;
|
inst->SrcReg[1].File = (enum register_file) -1;
|
||||||
inst->SrcReg[2].File = (enum register_file) -1;
|
inst->SrcReg[2].File = (enum register_file) -1;
|
||||||
inst->DstReg.File = (enum register_file) -1;
|
inst->DstReg.File = (enum register_file) -1;
|
||||||
|
inst->Data = NULL;
|
||||||
|
|
||||||
if (Parse_String(parseState, "MOV")) {
|
if (Parse_String(parseState, "MOV")) {
|
||||||
if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV))
|
if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV))
|
||||||
@@ -1136,6 +1231,10 @@ Parse_InstructionSequence(struct parse_state *parseState,
|
|||||||
if (!Parse_AddressInstruction(parseState, inst))
|
if (!Parse_AddressInstruction(parseState, inst))
|
||||||
RETURN_ERROR;
|
RETURN_ERROR;
|
||||||
}
|
}
|
||||||
|
else if (Parse_String(parseState, "PRINT")) {
|
||||||
|
if (!Parse_PrintInstruction(parseState, inst))
|
||||||
|
RETURN_ERROR;
|
||||||
|
}
|
||||||
else if (Parse_String(parseState, "END")) {
|
else if (Parse_String(parseState, "END")) {
|
||||||
if (!Parse_EndInstruction(parseState, inst))
|
if (!Parse_EndInstruction(parseState, inst))
|
||||||
RETURN_ERROR;
|
RETURN_ERROR;
|
||||||
@@ -1303,7 +1402,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
|
|||||||
program->IsPositionInvariant = parseState.isPositionInvariant;
|
program->IsPositionInvariant = parseState.isPositionInvariant;
|
||||||
program->IsNVProgram = GL_TRUE;
|
program->IsNVProgram = GL_TRUE;
|
||||||
|
|
||||||
#ifdef DEBUG_foo
|
#ifdef DEBUG
|
||||||
_mesa_printf("--- glLoadProgramNV result ---\n");
|
_mesa_printf("--- glLoadProgramNV result ---\n");
|
||||||
_mesa_print_nv_vertex_program(program);
|
_mesa_print_nv_vertex_program(program);
|
||||||
_mesa_printf("------------------------------\n");
|
_mesa_printf("------------------------------\n");
|
||||||
@@ -1457,6 +1556,17 @@ _mesa_print_nv_vertex_instruction(const struct vp_instruction *inst)
|
|||||||
PrintSrcReg(&inst->SrcReg[0]);
|
PrintSrcReg(&inst->SrcReg[0]);
|
||||||
_mesa_printf(";\n");
|
_mesa_printf(";\n");
|
||||||
break;
|
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:
|
case VP_OPCODE_END:
|
||||||
_mesa_printf("END\n");
|
_mesa_printf("END\n");
|
||||||
break;
|
break;
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -66,7 +66,9 @@ enum vp_opcode
|
|||||||
VP_OPCODE_LG2,
|
VP_OPCODE_LG2,
|
||||||
VP_OPCODE_POW,
|
VP_OPCODE_POW,
|
||||||
VP_OPCODE_XPD,
|
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
|
#if FEATURE_MESA_program_debug
|
||||||
GLint StringPos;
|
GLint StringPos;
|
||||||
#endif
|
#endif
|
||||||
|
void *Data; /* some arbitrary data, only used for PRINT instruction now */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
#include "nvfragparse.h"
|
#include "nvfragparse.h"
|
||||||
#include "nvfragprog.h"
|
#include "nvfragprog.h"
|
||||||
#include "nvvertparse.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 ||
|
if (prog->Target == GL_VERTEX_PROGRAM_NV ||
|
||||||
prog->Target == GL_VERTEX_STATE_PROGRAM_NV) {
|
prog->Target == GL_VERTEX_STATE_PROGRAM_NV) {
|
||||||
struct vertex_program *vprog = (struct vertex_program *) prog;
|
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);
|
_mesa_free(vprog->Instructions);
|
||||||
|
}
|
||||||
if (vprog->Parameters)
|
if (vprog->Parameters)
|
||||||
_mesa_free_parameter_list(vprog->Parameters);
|
_mesa_free_parameter_list(vprog->Parameters);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user