summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/api_validate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/api_validate.c')
-rw-r--r--src/mesa/main/api_validate.c108
1 files changed, 41 insertions, 67 deletions
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index 2df4f173893..4a1448deee6 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -29,7 +29,7 @@
#include "imports.h"
#include "mtypes.h"
#include "state.h"
-
+#include "vbo/vbo.h"
/**
@@ -52,51 +52,6 @@ index_bytes(GLenum type, GLsizei count)
/**
- * Find the max index in the given element/index buffer
- */
-static GLuint
-max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
- const void *indices,
- struct gl_buffer_object *elementBuf)
-{
- const GLubyte *map = NULL;
- GLuint max = 0;
- GLuint i;
-
- if (_mesa_is_bufferobj(elementBuf)) {
- /* elements are in a user-defined buffer object. need to map it */
- map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER,
- GL_READ_ONLY, elementBuf);
- /* Actual address is the sum of pointers */
- indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices);
- }
-
- if (type == GL_UNSIGNED_INT) {
- for (i = 0; i < count; i++)
- if (((GLuint *) indices)[i] > max)
- max = ((GLuint *) indices)[i];
- }
- else if (type == GL_UNSIGNED_SHORT) {
- for (i = 0; i < count; i++)
- if (((GLushort *) indices)[i] > max)
- max = ((GLushort *) indices)[i];
- }
- else {
- ASSERT(type == GL_UNSIGNED_BYTE);
- for (i = 0; i < count; i++)
- if (((GLubyte *) indices)[i] > max)
- max = ((GLubyte *) indices)[i];
- }
-
- if (map) {
- ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuf);
- }
-
- return max;
-}
-
-
-/**
* Check if OK to draw arrays/elements.
*/
static GLboolean
@@ -124,6 +79,40 @@ check_valid_to_render(GLcontext *ctx, const char *function)
return GL_TRUE;
}
+static GLboolean
+check_index_bounds(GLcontext *ctx, GLsizei count, GLenum type,
+ const GLvoid *indices, GLint basevertex)
+{
+ struct _mesa_prim prim;
+ struct _mesa_index_buffer ib;
+ GLuint min, max;
+
+ /* Only the X Server needs to do this -- otherwise, accessing outside
+ * array/BO bounds allows application termination.
+ */
+ if (!ctx->Const.CheckArrayBounds)
+ return GL_TRUE;
+
+ memset(&prim, 0, sizeof(prim));
+ prim.count = count;
+
+ memset(&ib, 0, sizeof(ib));
+ ib.type = type;
+ ib.ptr = indices;
+ ib.obj = ctx->Array.ElementArrayBufferObj;
+
+ vbo_get_minmax_index(ctx, &prim, &ib, &min, &max);
+
+ if (min + basevertex < 0 ||
+ max + basevertex > ctx->Array.ArrayObj->_MaxElement) {
+ /* the max element is out of bounds of one or more enabled arrays */
+ _mesa_warning(ctx, "glDrawElements() index=%u is "
+ "out of bounds (max=%u)", max, ctx->Array.ArrayObj->_MaxElement);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
/**
* Error checking for glDrawElements(). Includes parameter checking
@@ -133,7 +122,7 @@ check_valid_to_render(GLcontext *ctx, const char *function)
GLboolean
_mesa_validate_DrawElements(GLcontext *ctx,
GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices)
+ const GLvoid *indices, GLint basevertex)
{
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
@@ -177,17 +166,8 @@ _mesa_validate_DrawElements(GLcontext *ctx,
return GL_FALSE;
}
- if (ctx->Const.CheckArrayBounds) {
- /* find max array index */
- GLuint max = max_buffer_index(ctx, count, type, indices,
- ctx->Array.ElementArrayBufferObj);
- if (max >= ctx->Array.ArrayObj->_MaxElement) {
- /* the max element is out of bounds of one or more enabled arrays */
- _mesa_warning(ctx, "glDrawElements() index=%u is "
- "out of bounds (max=%u)", max, ctx->Array.ArrayObj->_MaxElement);
- return GL_FALSE;
- }
- }
+ if (!check_index_bounds(ctx, count, type, indices, basevertex))
+ return GL_FALSE;
return GL_TRUE;
}
@@ -202,7 +182,7 @@ GLboolean
_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
GLuint start, GLuint end,
GLsizei count, GLenum type,
- const GLvoid *indices)
+ const GLvoid *indices, GLint basevertex)
{
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
@@ -250,14 +230,8 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
return GL_FALSE;
}
- if (ctx->Const.CheckArrayBounds) {
- GLuint max = max_buffer_index(ctx, count, type, indices,
- ctx->Array.ElementArrayBufferObj);
- if (max >= ctx->Array.ArrayObj->_MaxElement) {
- /* the max element is out of bounds of one or more enabled arrays */
- return GL_FALSE;
- }
- }
+ if (!check_index_bounds(ctx, count, type, indices, basevertex))
+ return GL_FALSE;
return GL_TRUE;
}