From 08ff059f203f05a0cc417a46fe37f83929963db5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 21 Jul 2003 04:22:40 +0000 Subject: Initial implementation of GL_MESA_program_debug - a vertex/fragment program debugging extension. --- src/mesa/main/arbprogram.c | 216 ++++++++++++++++++++++++++++++++++++++++- src/mesa/main/arbprogram.h | 9 +- src/mesa/main/config.h | 1 + src/mesa/main/context.c | 1 + src/mesa/main/dlist.c | 1 + src/mesa/main/enable.c | 18 ++++ src/mesa/main/extensions.c | 6 +- src/mesa/main/get.c | 108 +++++++++++++++++++++ src/mesa/main/mtypes.h | 15 +++ src/mesa/main/nvfragparse.c | 37 ++++++- src/mesa/main/nvfragparse.h | 8 ++ src/mesa/main/nvfragprog.h | 9 +- src/mesa/main/nvvertparse.c | 19 +++- src/mesa/main/nvvertparse.h | 5 + src/mesa/main/nvvertprog.h | 2 +- src/mesa/swrast/s_nvfragprog.c | 26 +++-- 16 files changed, 461 insertions(+), 20 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c index 08d72fa..20118d4 100644 --- a/src/mesa/main/arbprogram.c +++ b/src/mesa/main/arbprogram.c @@ -37,7 +37,9 @@ #include "macros.h" #include "mtypes.h" #include "nvprogram.h" +#include "nvfragparse.h" #include "nvfragprog.h" +#include "nvvertparse.h" #include "nvvertprog.h" @@ -482,7 +484,7 @@ _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params) prog = &(ctx->VertexProgram.Current->Base); } else if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { + && ctx->Extensions.ARB_fragment_program) { prog = &(ctx->FragmentProgram.Current->Base); } else { @@ -702,3 +704,215 @@ _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String)); } + + + +/* XXX temporary */ +void +glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, + GLvoid *data) +{ + _mesa_ProgramCallbackMESA(target, callback, data); +} + + +void +_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, + GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + + switch (target) { + case GL_FRAGMENT_PROGRAM_ARB: + if (!ctx->Extensions.ARB_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } + ctx->FragmentProgram.Callback = callback; + ctx->FragmentProgram.CallbackData = data; + break; + case GL_FRAGMENT_PROGRAM_NV: + if (!ctx->Extensions.NV_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } + ctx->FragmentProgram.Callback = callback; + ctx->FragmentProgram.CallbackData = data; + break; + case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ + if (!ctx->Extensions.ARB_vertex_program && + !ctx->Extensions.ARB_vertex_program) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } + ctx->VertexProgram.Callback = callback; + ctx->VertexProgram.CallbackData = data; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } +} + + +/* XXX temporary */ +void +glGetProgramRegisterfvMESA(GLenum target, + GLsizei len, const GLubyte *registerName, + GLfloat *v) +{ + _mesa_GetProgramRegisterfvMESA(target, len, registerName, v); +} + + +void +_mesa_GetProgramRegisterfvMESA(GLenum target, + GLsizei len, const GLubyte *registerName, + GLfloat *v) +{ + char reg[1000]; + GET_CURRENT_CONTEXT(ctx); + + /* We _should_ be inside glBegin/glEnd */ +#if 0 + if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); + return; + } +#endif + + /* make null-terminated copy of registerName */ + _mesa_memcpy(reg, registerName, len); + reg[len] = 0; + + switch (target) { + case GL_VERTEX_PROGRAM_NV: + if (!ctx->Extensions.ARB_vertex_program && + !ctx->Extensions.NV_vertex_program) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + if (!ctx->VertexProgram.Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramRegisterfvMESA"); + return; + } + /* GL_NV_vertex_program */ + if (reg[0] == 'R') { + /* Temp register */ + GLint i = _mesa_atoi(reg + 1); + if (i >= ctx->Const.MaxVertexProgramTemps) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + COPY_4V(v, ctx->VertexProgram.Machine.Registers + [VP_TEMP_REG_START + i]); + } + else if (reg[0] == 'v' && reg[1] == '[') { + /* Vertex Input attribute */ + GLint i; + for (i = 0; i < ctx->Const.MaxVertexProgramAttribs; i++) { + const char *name = _mesa_nv_vertex_input_register_name(i); + if (_mesa_strncmp(reg + 2, name, 4) == 0) { + COPY_4V(v, ctx->VertexProgram.Machine.Registers + [VP_INPUT_REG_START + i]); + return; + } + } + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + else if (reg[0] == 'o' && reg[1] == '[') { + /* Vertex output attribute */ + } + /* GL_ARB_vertex_program */ + else if (_mesa_strncmp(reg, "vertex.", 7) == 0) { + + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + break; + case GL_FRAGMENT_PROGRAM_ARB: + if (!ctx->Extensions.ARB_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + if (!ctx->FragmentProgram.Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramRegisterfvMESA"); + return; + } + /* XXX to do */ + break; + case GL_FRAGMENT_PROGRAM_NV: + if (!ctx->Extensions.NV_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + if (!ctx->FragmentProgram.Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramRegisterfvMESA"); + return; + } + if (reg[0] == 'R') { + /* Temp register */ + GLint i = _mesa_atoi(reg + 1); + if (i >= ctx->Const.MaxFragmentProgramTemps) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + COPY_4V(v, + ctx->FragmentProgram.Machine.Registers[FP_TEMP_REG_START + i]); + } + else if (reg[0] == 'f' && reg[1] == '[') { + /* Fragment input attribute */ + GLint i; + for (i = 0; i < ctx->Const.MaxFragmentProgramAttribs; i++) { + const char *name = _mesa_nv_fragment_input_register_name(i); + if (_mesa_strncmp(reg + 2, name, 4) == 0) { + COPY_4V(v, ctx->FragmentProgram.Machine.Registers + [FP_INPUT_REG_START + i]); + return; + } + } + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + else if (_mesa_strcmp(reg, "o[COLR]") == 0) { + /* Fragment output color */ + COPY_4V(v, ctx->FragmentProgram.Machine.Registers + [FP_OUTPUT_REG_START + FRAG_OUTPUT_COLR]); + } + else if (_mesa_strcmp(reg, "o[COLH]") == 0) { + /* Fragment output color */ + COPY_4V(v, ctx->FragmentProgram.Machine.Registers + [FP_OUTPUT_REG_START + FRAG_OUTPUT_COLH]); + } + else if (_mesa_strcmp(reg, "o[DEPR]") == 0) { + /* Fragment output depth */ + COPY_4V(v, ctx->FragmentProgram.Machine.Registers + [FP_OUTPUT_REG_START + FRAG_OUTPUT_DEPR]); + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + +} diff --git a/src/mesa/main/arbprogram.h b/src/mesa/main/arbprogram.h index 7f4dd87..bc5a662 100644 --- a/src/mesa/main/arbprogram.h +++ b/src/mesa/main/arbprogram.h @@ -125,5 +125,12 @@ extern void _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string); -#endif +extern void +_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, + GLvoid *data); +extern void +_mesa_GetProgramRegisterfvMESA(GLenum target, GLsizei len, + const GLubyte *registerName, GLfloat *v); + +#endif diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index cb94a29..bbffcd0 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -256,6 +256,7 @@ #define FEATURE_ARB_vertex_program 1 #define FEATURE_ARB_fragment_program 1 #define FEATURE_ARB_occlusion_query 1 +#define FEATURE_MESA_program_debug 1 #define FEATURE_NV_fence 1 #define FEATURE_userclip 1 #define FEATURE_texgen 1 diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index b4b9659..b44f74b 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1105,6 +1105,7 @@ init_attrib_groups( GLcontext *ctx ) _mesa_init_pixel( ctx ); _mesa_init_point( ctx ); _mesa_init_polygon( ctx ); + /* XXX _mesa_init_program( ctx ); */ _mesa_init_rastpos( ctx ); _mesa_init_stencil( ctx ); _mesa_init_transform( ctx ); diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 928b74c..5588f44 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -5355,6 +5355,7 @@ _mesa_CallList( GLuint list ) /* VERY IMPORTANT: Save the CompileFlag status, turn it off, */ /* execute the display list, and restore the CompileFlag. */ + printf("%s %d\n", __FUNCTION__, list); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glCallList %d\n", list); diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index de08fa3..3106a98 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -971,6 +971,16 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) ctx->Depth.BoundsTest = state; break; + /* GL_MESA_program_debug */ + case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION(MESA_program_debug, cap); + ctx->FragmentProgram.CallbackEnabled = state; + break; + case GL_VERTEX_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION(MESA_program_debug, cap); + ctx->VertexProgram.CallbackEnabled = state; + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "%s(0x%x)", state ? "glEnable" : "glDisable", cap); @@ -1401,6 +1411,14 @@ _mesa_IsEnabled( GLenum cap ) CHECK_EXTENSION(EXT_depth_bounds_test); return ctx->Depth.BoundsTest; + /* GL_MESA_program_debug */ + case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION(MESA_program_debug); + return ctx->FragmentProgram.CallbackEnabled; + case GL_VERTEX_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION(MESA_program_debug); + return ctx->VertexProgram.CallbackEnabled; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap); return GL_FALSE; diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index efc9267..95c680c 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -115,6 +115,7 @@ static const struct { { OFF, "GL_INGR_blend_func_separate", F(EXT_blend_func_separate) }, { OFF, "GL_MESA_pack_invert", F(MESA_pack_invert) }, { OFF, "GL_MESA_packed_depth_stencil", F(MESA_packed_depth_stencil) }, + { OFF, "GL_MESA_program_debug", F(MESA_program_debug) }, { OFF, "GL_MESA_resize_buffers", F(MESA_resize_buffers) }, { OFF, "GL_MESA_ycbcr_texture", F(MESA_ycbcr_texture) }, { ON, "GL_MESA_window_pos", F(ARB_window_pos) }, @@ -151,7 +152,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) { ctx->Extensions.ARB_depth_texture = GL_TRUE; #if FEATURE_ARB_fragment_program - /*ctx->Extensions.ARB_fragment_program = GL_TRUE;*/ + ctx->Extensions.ARB_fragment_program = GL_TRUE; #endif ctx->Extensions.ARB_imaging = GL_TRUE; ctx->Extensions.ARB_multitexture = GL_TRUE; @@ -193,6 +194,9 @@ _mesa_enable_sw_extensions(GLcontext *ctx) ctx->Extensions.EXT_texture_lod_bias = GL_TRUE; ctx->Extensions.HP_occlusion_test = GL_TRUE; ctx->Extensions.MESA_pack_invert = GL_TRUE; +#if FEATURE_MESA_program_debug + ctx->Extensions.MESA_program_debug = GL_TRUE; +#endif ctx->Extensions.MESA_resize_buffers = GL_TRUE; ctx->Extensions.MESA_ycbcr_texture = GL_TRUE; ctx->Extensions.NV_blend_square = GL_TRUE; diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index a237775..3cf8453 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1630,6 +1630,25 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[1] = FLOAT_TO_BOOL(ctx->Depth.BoundsMax); break; +#if FEATURE_MESA_program_debug + case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION_B(MESA_program_debug, pname); + *params = ctx->FragmentProgram.CallbackEnabled; + break; + case GL_VERTEX_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION_B(MESA_program_debug, pname); + *params = ctx->VertexProgram.CallbackEnabled; + break; + case GL_FRAGMENT_PROGRAM_POSITION_MESA: + CHECK_EXTENSION_B(MESA_program_debug, pname); + *params = INT_TO_BOOL(ctx->FragmentProgram.CurrentPosition); + break; + case GL_VERTEX_PROGRAM_POSITION_MESA: + CHECK_EXTENSION_B(MESA_program_debug, pname); + *params = INT_TO_BOOL(ctx->VertexProgram.CurrentPosition); + break; +#endif + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname); } @@ -3148,6 +3167,25 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) params[1] = ctx->Depth.BoundsMax; break; +#if FEATURE_MESA_program_debug + case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION_D(MESA_program_debug, pname); + *params = (GLdouble) ctx->FragmentProgram.CallbackEnabled; + break; + case GL_VERTEX_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION_D(MESA_program_debug, pname); + *params = (GLdouble) ctx->VertexProgram.CallbackEnabled; + break; + case GL_FRAGMENT_PROGRAM_POSITION_MESA: + CHECK_EXTENSION_D(MESA_program_debug, pname); + *params = (GLdouble) ctx->FragmentProgram.CurrentPosition; + break; + case GL_VERTEX_PROGRAM_POSITION_MESA: + CHECK_EXTENSION_D(MESA_program_debug, pname); + *params = (GLdouble) ctx->VertexProgram.CurrentPosition; + break; +#endif + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev(pname=0x%x)", pname); } @@ -4642,6 +4680,25 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[1] = ctx->Depth.BoundsMax; break; +#if FEATURE_MESA_program_debug + case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION_F(MESA_program_debug, pname); + *params = (GLfloat) ctx->FragmentProgram.CallbackEnabled; + break; + case GL_VERTEX_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION_F(MESA_program_debug, pname); + *params = (GLfloat) ctx->VertexProgram.CallbackEnabled; + break; + case GL_FRAGMENT_PROGRAM_POSITION_MESA: + CHECK_EXTENSION_F(MESA_program_debug, pname); + *params = (GLfloat) ctx->FragmentProgram.CurrentPosition; + break; + case GL_VERTEX_PROGRAM_POSITION_MESA: + CHECK_EXTENSION_F(MESA_program_debug, pname); + *params = (GLfloat) ctx->VertexProgram.CurrentPosition; + break; +#endif + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(0x%x)", pname); } @@ -4672,6 +4729,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) if (!params) return; +#if 0 /* We need this in order to get correct results for * GL_OCCLUSION_TEST_RESULT_HP. There might be other important cases. */ @@ -4683,6 +4741,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) if (ctx->Driver.GetIntegerv && (*ctx->Driver.GetIntegerv)(ctx, pname, params)) return; +#endif switch (pname) { case GL_ACCUM_RED_BITS: @@ -6174,6 +6233,25 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[1] = (GLint) ctx->Depth.BoundsMax; break; +#if FEATURE_MESA_program_debug + case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION_I(MESA_program_debug, pname); + *params = (GLint) ctx->FragmentProgram.CallbackEnabled; + break; + case GL_VERTEX_PROGRAM_CALLBACK_MESA: + CHECK_EXTENSION_I(MESA_program_debug, pname); + *params = (GLint) ctx->VertexProgram.CallbackEnabled; + break; + case GL_FRAGMENT_PROGRAM_POSITION_MESA: + CHECK_EXTENSION_I(MESA_program_debug, pname); + *params = (GLint) ctx->FragmentProgram.CurrentPosition; + break; + case GL_VERTEX_PROGRAM_POSITION_MESA: + CHECK_EXTENSION_I(MESA_program_debug, pname); + *params = (GLint) ctx->VertexProgram.CurrentPosition; + break; +#endif + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname); } @@ -6239,6 +6317,36 @@ _mesa_GetPointerv( GLenum pname, GLvoid **params ) case GL_SELECTION_BUFFER_POINTER: *params = ctx->Select.Buffer; break; +#if FEATURE_MESA_program_debug + case GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA: + if (!ctx->Extensions.MESA_program_debug) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetPointerv"); + return; + } + *params = (GLvoid *) ctx->FragmentProgram.Callback; + break; + case GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA: + if (!ctx->Extensions.MESA_program_debug) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetPointerv"); + return; + } + *params = ctx->FragmentProgram.CallbackData; + break; + case GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA: + if (!ctx->Extensions.MESA_program_debug) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetPointerv"); + return; + } + *params = (GLvoid *) ctx->VertexProgram.Callback; + break; + case GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA: + if (!ctx->Extensions.MESA_program_debug) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetPointerv"); + return; + } + *params = ctx->VertexProgram.CallbackData; + break; +#endif default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" ); return; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index bac711d..cb40829 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1501,6 +1501,13 @@ struct vertex_program_state GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4]; GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4]; + +#if FEATURE_MESA_program_debug + GLprogramcallbackMESA Callback; + GLvoid *CallbackData; + GLboolean CallbackEnabled; + GLuint CurrentPosition; +#endif }; @@ -1512,6 +1519,13 @@ struct fragment_program_state GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */ struct fragment_program *Current; /* ptr to currently bound program */ struct fp_machine Machine; /* machine state */ + +#if FEATURE_MESA_program_debug + GLprogramcallbackMESA Callback; + GLvoid *CallbackData; + GLboolean CallbackEnabled; + GLuint CurrentPosition; +#endif }; /*@}*/ @@ -1735,6 +1749,7 @@ struct gl_extensions { GLboolean IBM_rasterpos_clip; GLboolean MESA_pack_invert; GLboolean MESA_packed_depth_stencil; + GLboolean MESA_program_debug; GLboolean MESA_resize_buffers; GLboolean MESA_ycbcr_texture; GLboolean NV_blend_square; diff --git a/src/mesa/main/nvfragparse.c b/src/mesa/main/nvfragparse.c index 38da433..4f1df53 100644 --- a/src/mesa/main/nvfragparse.c +++ b/src/mesa/main/nvfragparse.c @@ -126,6 +126,7 @@ struct parse_state { GLcontext *ctx; const GLubyte *start; /* start of program string */ const GLubyte *pos; /* current position */ + const GLubyte *curLine; struct fragment_program *program; /* current program */ GLuint numParameters; @@ -332,8 +333,9 @@ static GLboolean IsWhitespace(GLubyte b) * \return <= 0 we found an error, else, return number of characters parsed. */ static GLint -GetToken(const GLubyte *str, GLubyte *token) +GetToken(struct parse_state *parseState, GLubyte *token) { + const GLubyte *str = parseState->pos; GLint i = 0, j = 0; token[0] = 0; @@ -345,9 +347,13 @@ GetToken(const GLubyte *str, GLubyte *token) while (str[i] && (str[i] != '\n' && str[i] != '\r')) { i++; } + if (str[i] == '\n' || str[i] == '\r') + parseState->curLine = str + i + 1; } else { /* skip whitespace */ + if (str[i] == '\n' || str[i] == '\r') + parseState->curLine = str + i + 1; i++; } } @@ -393,7 +399,7 @@ static GLboolean Parse_Token(struct parse_state *parseState, GLubyte *token) { GLint i; - i = GetToken(parseState->pos, token); + i = GetToken(parseState, token); if (i <= 0) { parseState->pos += (-i); return GL_FALSE; @@ -410,7 +416,7 @@ static GLboolean Peek_Token(struct parse_state *parseState, GLubyte *token) { GLint i, len; - i = GetToken(parseState->pos, token); + i = GetToken(parseState, token); if (i <= 0) { parseState->pos += (-i); return GL_FALSE; @@ -510,9 +516,13 @@ Parse_String(struct parse_state *parseState, const char *pattern) while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) { parseState->pos += 1; } + if (*parseState->pos == '\n' || *parseState->pos == '\r') + parseState->curLine = parseState->pos + 1; } else { /* skip whitespace */ + if (*parseState->pos == '\n' || *parseState->pos == '\r') + parseState->curLine = parseState->pos + 1; parseState->pos += 1; } } @@ -1337,6 +1347,8 @@ Parse_InstructionSequence(struct parse_state *parseState, } else if (Parse_String(parseState, "END")) { inst->Opcode = FP_OPCODE_END; + inst->StringPos = parseState->curLine - parseState->start; + assert(inst->StringPos >= 0); parseState->numInst++; if (Parse_Token(parseState, token)) { RETURN_ERROR1("Code after END opcode."); @@ -1362,6 +1374,8 @@ Parse_InstructionSequence(struct parse_state *parseState, inst->Precision = instMatch.suffixes & (_R | _H | _X); inst->Saturate = (instMatch.suffixes & (_S)) ? GL_TRUE : GL_FALSE; inst->UpdateCondRegister = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE; + inst->StringPos = parseState->curLine - parseState->start; + assert(inst->StringPos >= 0); /* * parse the input and output operands @@ -1491,6 +1505,7 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, parseState.start = programString; parseState.program = program; parseState.numInst = 0; + parseState.curLine = programString; /* Reset error state */ _mesa_set_program_error(ctx, -1, NULL); @@ -1845,3 +1860,19 @@ _mesa_print_nv_fragment_program(const struct fragment_program *program) } _mesa_printf("END\n"); } + + +const char * +_mesa_nv_fragment_input_register_name(GLuint i) +{ + ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS); + return InputRegisters[i]; +} + + +const char * +_mesa_nv_fragment_output_register_name(GLuint i) +{ + ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS); + return OutputRegisters[i]; +} diff --git a/src/mesa/main/nvfragparse.h b/src/mesa/main/nvfragparse.h index 16f96ce..849a7fb 100644 --- a/src/mesa/main/nvfragparse.h +++ b/src/mesa/main/nvfragparse.h @@ -41,4 +41,12 @@ extern void _mesa_print_nv_fragment_program(const struct fragment_program *program); +extern const char * +_mesa_nv_fragment_input_register_name(GLuint i); + + +extern const char * +_mesa_nv_fragment_output_register_name(GLuint i); + + #endif diff --git a/src/mesa/main/nvfragprog.h b/src/mesa/main/nvfragprog.h index 491fcdd..2f2434b 100644 --- a/src/mesa/main/nvfragprog.h +++ b/src/mesa/main/nvfragprog.h @@ -1,4 +1,3 @@ - /* * Mesa 3-D graphics library * Version: 5.1 @@ -24,8 +23,8 @@ */ -/* Private vertex program types and constants only used by files - * related to vertex programs. +/* Private fragment program types and constants only used by files + * related to fragment programs. */ @@ -166,8 +165,10 @@ struct fp_instruction GLubyte Precision; /* FLOAT32, FLOAT16 or FIXED12 */ GLubyte TexSrcUnit; /* texture unit for TEX, TXD, TXP instructions */ GLubyte TexSrcBit; /* TEXTURE_1D,2D,3D,CUBE,RECT_BIT source target */ +#if FEATURE_MESA_program_debug + GLint StringPos; +#endif }; - #endif diff --git a/src/mesa/main/nvvertparse.c b/src/mesa/main/nvvertparse.c index 2e18c7a..9d0cd5f 100644 --- a/src/mesa/main/nvvertparse.c +++ b/src/mesa/main/nvvertparse.c @@ -262,12 +262,12 @@ Parse_String(struct parse_state *parseState, const char *pattern) /**********************************************************************/ -static const char *InputRegisters[] = { +static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = { "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7", "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL }; -static const char *OutputRegisters[] = { +static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = { "HPOS", "COL0", "COL1", "BFC0", "BFC1", "FOGC", "PSIZ", "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL }; @@ -1472,3 +1472,18 @@ _mesa_print_nv_vertex_program(const struct vertex_program *program) } } + +const char * +_mesa_nv_vertex_input_register_name(GLuint i) +{ + ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS); + return InputRegisters[i]; +} + + +const char * +_mesa_nv_vertex_output_register_name(GLuint i) +{ + ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS); + return OutputRegisters[i]; +} diff --git a/src/mesa/main/nvvertparse.h b/src/mesa/main/nvvertparse.h index 5949b92..205885f 100644 --- a/src/mesa/main/nvvertparse.h +++ b/src/mesa/main/nvvertparse.h @@ -41,5 +41,10 @@ _mesa_print_nv_vertex_instruction(const struct vp_instruction *inst); extern void _mesa_print_nv_vertex_program(const struct vertex_program *program); +extern const char * +_mesa_nv_vertex_input_register_name(GLuint i); + +extern const char * +_mesa_nv_vertex_output_register_name(GLuint i); #endif diff --git a/src/mesa/main/nvvertprog.h b/src/mesa/main/nvvertprog.h index 44207e2..411426e 100644 --- a/src/mesa/main/nvvertprog.h +++ b/src/mesa/main/nvvertprog.h @@ -1,4 +1,3 @@ - /* * Mesa 3-D graphics library * Version: 5.1 @@ -28,6 +27,7 @@ * related to vertex programs. */ + #ifndef NVVERTPROG_H #define NVVERTPROG_H diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index c728aa3..1416e79 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -527,6 +527,14 @@ execute_program( GLcontext *ctx, for (pc = 0; pc < maxInst; pc++) { const struct fp_instruction *inst = program->Instructions + pc; + + if (ctx->FragmentProgram.CallbackEnabled && + ctx->FragmentProgram.Callback) { + ctx->FragmentProgram.CurrentPosition = inst->StringPos; + ctx->FragmentProgram.Callback(program->Base.Target, + ctx->FragmentProgram.CallbackData); + } + switch (inst->Opcode) { case FP_OPCODE_ADD: { @@ -1105,8 +1113,12 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, const struct fragment_program *program, const struct sw_span *span, GLuint col ) { + GLuint inputsRead = program->InputsRead; GLuint j, u; + if (ctx->FragmentProgram.CallbackEnabled) + inputsRead = ~0; + /* Clear temporary registers */ _mesa_bzero(machine->Registers + FP_TEMP_REG_START, MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); @@ -1118,28 +1130,28 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, } /* Load input registers */ - if (program->InputsRead & (1 << FRAG_ATTRIB_WPOS)) { + if (inputsRead & (1 << FRAG_ATTRIB_WPOS)) { GLfloat *wpos = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_WPOS]; wpos[0] = span->x + col; wpos[1] = span->y; wpos[2] = (GLfloat) span->array->z[col] / ctx->DepthMaxF; wpos[3] = span->w + col * span->dwdx; } - if (program->InputsRead & (1 << FRAG_ATTRIB_COL0)) { + if (inputsRead & (1 << FRAG_ATTRIB_COL0)) { GLfloat *col0 = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL0]; col0[0] = CHAN_TO_FLOAT(span->array->rgba[col][RCOMP]); col0[1] = CHAN_TO_FLOAT(span->array->rgba[col][GCOMP]); col0[2] = CHAN_TO_FLOAT(span->array->rgba[col][BCOMP]); col0[3] = CHAN_TO_FLOAT(span->array->rgba[col][ACOMP]); } - if (program->InputsRead & (1 << FRAG_ATTRIB_COL1)) { + if (inputsRead & (1 << FRAG_ATTRIB_COL1)) { GLfloat *col1 = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL1]; col1[0] = CHAN_TO_FLOAT(span->array->spec[col][RCOMP]); col1[1] = CHAN_TO_FLOAT(span->array->spec[col][GCOMP]); col1[2] = CHAN_TO_FLOAT(span->array->spec[col][BCOMP]); col1[3] = CHAN_TO_FLOAT(span->array->spec[col][ACOMP]); } - if (program->InputsRead & (1 << FRAG_ATTRIB_FOGC)) { + if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) { GLfloat *fogc = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_FOGC]; fogc[0] = span->array->fog[col]; fogc[1] = 0.0F; @@ -1147,11 +1159,11 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, fogc[3] = 0.0F; } for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { - if (program->InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { + if (inputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { GLfloat *tex = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_TEX0+u]; - ASSERT(ctx->Texture._EnabledCoordUnits & (1 << u)); + /*ASSERT(ctx->Texture._EnabledCoordUnits & (1 << u));*/ COPY_4V(tex, span->array->texcoords[u][col]); - ASSERT(tex[0] != 0 || tex[1] != 0 || tex[2] != 0); + /*ASSERT(tex[0] != 0 || tex[1] != 0 || tex[2] != 0);*/ } } -- cgit v1.1