@@ -162,4 +162,7 @@ void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec, | |||
void vbo_exec_do_EvalCoord1f( struct vbo_exec_context *exec, | |||
GLfloat u); | |||
extern GLboolean | |||
vbo_validate_shaders(GLcontext *ctx); | |||
#endif |
@@ -477,6 +477,23 @@ static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j ) | |||
} | |||
/** | |||
* Check if programs/shaders are enabled and valid at glBegin time. | |||
*/ | |||
GLboolean | |||
vbo_validate_shaders(GLcontext *ctx) | |||
{ | |||
if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || | |||
(ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { | |||
return GL_FALSE; | |||
} | |||
if (ctx->Shader.CurrentProgram && !ctx->Shader.CurrentProgram->LinkStatus) { | |||
return GL_FALSE; | |||
} | |||
return GL_TRUE; | |||
} | |||
/* Build a list of primitives on the fly. Keep | |||
* ctx->Driver.CurrentExecPrimitive uptodate as well. | |||
*/ | |||
@@ -491,18 +508,16 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) | |||
if (ctx->NewState) { | |||
_mesa_update_state( ctx ); | |||
/* XXX also need to check if shader enabled, but invalid */ | |||
if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || | |||
(ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { | |||
_mesa_error(ctx, GL_INVALID_OPERATION, | |||
"glBegin (invalid vertex/fragment program)"); | |||
return; | |||
} | |||
CALL_Begin(ctx->Exec, (mode)); | |||
return; | |||
} | |||
if (!vbo_validate_shaders(ctx)) { | |||
_mesa_error(ctx, GL_INVALID_OPERATION, | |||
"glBegin (invalid vertex/fragment program)"); | |||
return; | |||
} | |||
/* Heuristic: attempt to isolate attributes occuring outside | |||
* begin/end pairs. | |||
*/ |
@@ -245,6 +245,11 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) | |||
if (ctx->NewState) | |||
_mesa_update_state( ctx ); | |||
if (!vbo_validate_shaders(ctx)) { | |||
_mesa_error(ctx, GL_INVALID_OPERATION, "glDrawArrays(bad shader)"); | |||
return; | |||
} | |||
bind_arrays( ctx ); | |||
prim[0].begin = 1; | |||
@@ -280,6 +285,11 @@ vbo_exec_DrawRangeElements(GLenum mode, | |||
if (ctx->NewState) | |||
_mesa_update_state( ctx ); | |||
if (!vbo_validate_shaders(ctx)) { | |||
_mesa_error(ctx, GL_INVALID_OPERATION, "glDrawRangeElements(bad shader)"); | |||
return; | |||
} | |||
bind_arrays( ctx ); | |||
ib.count = count; | |||
@@ -340,6 +350,11 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *ind | |||
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) | |||
return; | |||
if (!vbo_validate_shaders(ctx)) { | |||
_mesa_error(ctx, GL_INVALID_OPERATION, "glDrawElements(bad shader)"); | |||
return; | |||
} | |||
if (ctx->Array.ElementArrayBufferObj->Name) { | |||
const GLvoid *map = ctx->Driver.MapBuffer(ctx, | |||
GL_ELEMENT_ARRAY_BUFFER_ARB, |