Initial implementation of GL_MESA_program_debug - a vertex/fragment program
debugging extension.
This commit is contained in:
parent
190c11e06d
commit
08ff059f20
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue