mesa: Fix glBegin-time test for invalid programs/shaders.
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 11 Apr 2008 16:14:17 +0000 (10:14 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 11 Apr 2008 16:14:17 +0000 (10:14 -0600)
Cherry-picked from master.

src/mesa/vbo/vbo_exec.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_exec_array.c

index b7e8c9fe79f3bc8ee70fd5b3ddcc067705588485..ddbcbe11814c201027a56751f1aa1c84ec431ba1 100644 (file)
@@ -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
index b7f4d8a3075ffd82b3b6fe31f97533b87e74f2e6..98580170e3235682f4cc201769988beaf8aee8e6 100644 (file)
@@ -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.
        */
index 77f3cf1455bc04a46f2c7d755cc1156ca85aada1..a52521db642d476515d92142ec8c0e10a06d505d 100644 (file)
@@ -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,