Initial implementation of GL_MESA_program_debug - a vertex/fragment program

debugging extension.
This commit is contained in:
Brian Paul 2003-07-21 04:22:40 +00:00
parent 190c11e06d
commit 08ff059f20
16 changed files with 461 additions and 20 deletions

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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 );

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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];
}

View File

@ -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

View File

@ -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

View File

@ -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];
}

View File

@ -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

View File

@ -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

View File

@ -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);*/
}
}