Fix some problems with glDrawElements and vertex buffer objects.
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 4 Dec 2003 03:16:27 +0000 (03:16 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 4 Dec 2003 03:16:27 +0000 (03:16 +0000)
src/mesa/main/api_validate.c
src/mesa/main/varray.c
src/mesa/tnl/t_array_api.c

index 53783b10e13b88d27f50f178c26e70a4a1214f97..004a7595a0230c25af0e47a7bee5f786fc135867 100644 (file)
@@ -65,6 +65,43 @@ _mesa_validate_DrawElements(GLcontext *ctx,
        && !(ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled))
       return GL_FALSE;
 
+   /* Vertex buffer object tests */
+   if (ctx->Array.ElementArrayBufferObj->Name) {
+      GLuint indexBytes;
+
+      /* use indices in the buffer object */
+      if (!ctx->Array.ElementArrayBufferObj->Data) {
+         _mesa_warning(ctx, "DrawElements with empty vertex elements buffer!");
+         return GL_FALSE;
+      }
+
+      /* make sure count doesn't go outside buffer bounds */
+      if (type == GL_UNSIGNED_INT) {
+         indexBytes = count * sizeof(GLuint);
+      }
+      else if (type == GL_UNSIGNED_BYTE) {
+         indexBytes = count * sizeof(GLubyte);
+      }
+      else {
+         ASSERT(type == GL_UNSIGNED_SHORT);
+         indexBytes = count * sizeof(GLushort);
+      }
+
+      if ((GLubyte *) indices + indexBytes >
+          ctx->Array.ElementArrayBufferObj->Data +
+          ctx->Array.ElementArrayBufferObj->Size) {
+         _mesa_warning(ctx, "glDrawElements index out of buffer bounds");
+         return GL_FALSE;
+      }
+
+      /* Actual address is the sum of pointers.  Indices may be used below. */
+      if (ctx->Const.CheckArrayBounds) {
+         indices = (const GLvoid *)
+            ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data,
+                         (const GLubyte *) indices);
+      }
+   }
+
    if (ctx->Const.CheckArrayBounds) {
       /* find max array index */
       GLuint max = 0;
index ddd04b4c81cdf66da834b36dafff9ce35619c7ca..8141cf92817d2f91c35028ed646d4659de6aee50 100644 (file)
@@ -879,12 +879,6 @@ _mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (ctx->Array.ElementArrayBufferObj->Name) {
-      /* use indices in the buffer object */
-      ASSERT(ctx->Array.ElementArrayBufferObj->Data);
-      indices = (const GLvoid **) ctx->Array.ElementArrayBufferObj->Data;
-   }
-
    for (i = 0; i < primcount; i++) {
       if (count[i] > 0) {
          (ctx->Exec->DrawElements)(mode, count[i], type, indices[i]);
@@ -906,8 +900,8 @@ _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
 
    for ( i = 0 ; i < primcount ; i++ ) {
       if ( count[i] > 0 ) {
-        (ctx->Exec->DrawArrays)( *(GLenum *) ((char *) mode + (i * modestride)),
-                                 first[i], count[i] );
+         GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
+        (ctx->Exec->DrawArrays)( m, first[i], count[i] );
       }
    }
 }
@@ -928,8 +922,8 @@ _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
 
    for ( i = 0 ; i < primcount ; i++ ) {
       if ( count[i] > 0 ) {
-        (ctx->Exec->DrawElements)( *(GLenum *) ((char *) mode + (i * modestride)),
-                                   count[i], type, indices[i] );
+         GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
+        (ctx->Exec->DrawElements)( m, count[i], type, indices[i] );
       }
    }
 }
index 2b10a9d1c2cfa1cea4a9cc67cb55c300017b7c6e..802133dc2d895997b2e3c3427e3450159ac8e0bd 100644 (file)
@@ -309,7 +309,10 @@ _tnl_DrawRangeElements(GLenum mode,
                        "DrawRangeElements with empty vertex elements buffer!");
          return;
       }
-      indices = (GLvoid *) ctx->Array.ElementArrayBufferObj->Data;
+      /* actual address is the sum of pointers */
+      indices = (const GLvoid *)
+         ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data,
+                      (const GLubyte *) indices);
    }
 
    /* Check arguments, etc.
@@ -376,20 +379,17 @@ _tnl_DrawElements(GLenum mode, GLsizei count, GLenum type,
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(NULL, "_tnl_DrawElements %d\n", count); 
 
-   if (ctx->Array.ElementArrayBufferObj->Name) {
-      /* use indices in the buffer object */
-      if (!ctx->Array.ElementArrayBufferObj->Data) {
-         _mesa_warning(ctx, "DrawElements with empty vertex elements buffer!");
-         return;
-      }
-      indices = (const GLvoid *) ctx->Array.ElementArrayBufferObj->Data;
-   }
-
-   /* Check arguments, etc.
-    */
+   /* Check arguments, etc. */
    if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
       return;
 
+   if (ctx->Array.ElementArrayBufferObj->Name) {
+      /* actual address is the sum of pointers */
+      indices = (const GLvoid *)
+         ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data,
+                      (const GLubyte *) indices);
+   }
+
    ui_indices = (GLuint *)_ac_import_elements( ctx, GL_UNSIGNED_INT,
                                               count, type, indices );