From 645e297a0019eb2f7513bd801ffdaac03187f29f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 26 Jan 2010 12:47:51 -0700 Subject: vbo: clamp DrawElements start/end to max possible values Some apps are sloppy with their start/end values. Clamp them to max possible values to prevent problems later. --- src/mesa/vbo/vbo_exec_array.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/mesa/vbo/vbo_exec_array.c') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 2c82f7c9c5..f455382592 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -688,6 +688,16 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, * or we can read/write out of memory in several different places! */ + /* Catch/fix some potential user errors */ + if (type == GL_UNSIGNED_BYTE) { + start = MIN2(start, 0xff); + end = MIN2(end, 0xff); + } + else if (type == GL_UNSIGNED_SHORT) { + start = MIN2(start, 0xffff); + end = MIN2(end, 0xffff); + } + if (end >= ctx->Array.ArrayObj->_MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ warnCount++; -- cgit v1.2.3 From cbecb8fc8e85cfafed7fd8fd0e2dd1143efcf62b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 26 Jan 2010 12:49:44 -0700 Subject: vbo: if 'end' is out of bounds, clamp it If we determine that the 'end' parameter to glDrawElements() is out of bounds, clamp it to the max legal index value. --- src/mesa/vbo/vbo_exec_array.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/mesa/vbo/vbo_exec_array.c') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index f455382592..bd2fccdba1 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -748,6 +748,10 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, */ } #endif + + /* Set 'end' to the max possible legal value */ + assert(ctx->Array.ArrayObj->_MaxElement >= 1); + end = ctx->Array.ArrayObj->_MaxElement - 1; } else if (0) { _mesa_printf("glDraw[Range]Elements{,BaseVertex}" -- cgit v1.2.3 From dd89ac249c56d04bbc23ecd9877426af9f09269c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 27 Jan 2010 17:03:48 -0700 Subject: mesa: fix int/uint comparison warnings Reported by Karl Schultz. --- src/mesa/vbo/vbo_exec_array.c | 10 +++++----- src/mesa/vbo/vbo_split.c | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src/mesa/vbo/vbo_exec_array.c') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index bd2fccdba1..d6452cb664 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -49,7 +49,7 @@ vbo_get_minmax_index(GLcontext *ctx, GLuint *min_index, GLuint *max_index) { GLuint i; - GLsizei count = prim->count; + GLuint count = prim->count; const void *indices; if (_mesa_is_bufferobj(ib->obj)) { @@ -132,7 +132,7 @@ check_array_data(GLcontext *ctx, struct gl_client_array *array, case GL_FLOAT: { GLfloat *f = (GLfloat *) ((GLubyte *) data + array->StrideB * j); - GLuint k; + GLint k; for (k = 0; k < array->Size; k++) { if (IS_INF_OR_NAN(f[k]) || f[k] >= 1.0e20 || f[k] <= -1.0e10) { @@ -542,7 +542,7 @@ dump_element_buffer(GLcontext *ctx, GLenum type) case GL_UNSIGNED_BYTE: { const GLubyte *us = (const GLubyte *) map; - GLuint i; + GLint i; for (i = 0; i < ctx->Array.ElementArrayBufferObj->Size; i++) { _mesa_printf("%02x ", us[i]); if (i % 32 == 31) @@ -554,7 +554,7 @@ dump_element_buffer(GLcontext *ctx, GLenum type) case GL_UNSIGNED_SHORT: { const GLushort *us = (const GLushort *) map; - GLuint i; + GLint i; for (i = 0; i < ctx->Array.ElementArrayBufferObj->Size / 2; i++) { _mesa_printf("%04x ", us[i]); if (i % 16 == 15) @@ -566,7 +566,7 @@ dump_element_buffer(GLcontext *ctx, GLenum type) case GL_UNSIGNED_INT: { const GLuint *us = (const GLuint *) map; - GLuint i; + GLint i; for (i = 0; i < ctx->Array.ElementArrayBufferObj->Size / 4; i++) { _mesa_printf("%08x ", us[i]); if (i % 8 == 7) diff --git a/src/mesa/vbo/vbo_split.c b/src/mesa/vbo/vbo_split.c index c445acca7d..ce40cbbcc3 100644 --- a/src/mesa/vbo/vbo_split.c +++ b/src/mesa/vbo/vbo_split.c @@ -108,12 +108,14 @@ void vbo_split_prims( GLcontext *ctx, vbo_draw_func draw, const struct split_limits *limits ) { - GLuint max_basevertex = prim->basevertex; + GLint max_basevertex = prim->basevertex; GLuint i; for (i = 1; i < nr_prims; i++) max_basevertex = MAX2(max_basevertex, prim[i].basevertex); + /* XXX max_basevertex is computed but not used, why? */ + if (ib) { if (limits->max_indices == 0) { /* Could traverse the indices, re-emitting vertices in turn. -- cgit v1.2.3 From 4886f677ecf121c863f8f65a846284ab9d26cbea Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 29 Jan 2010 08:31:48 -0700 Subject: mesa: Warn when indices are out of bounds, but do not skip the draw in debug builds. The driver (or preferably the hardware) should handle out of bounds indices. If there are problems then it's better to detect those in the debug builds. (cherry picked from commit e3257912e006120f6ab611e77005eed1a464030a) --- src/mesa/vbo/vbo_exec_array.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/mesa/vbo/vbo_exec_array.c') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index d6452cb664..392da43c5e 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -722,8 +722,7 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, #ifdef DEBUG /* 'end' was out of bounds, but now let's check the actual array - * indexes to see if any of them are out of bounds. If so, warn - * and skip the draw to avoid potential segfault, etc. + * indexes to see if any of them are out of bounds. */ { GLuint max = _mesa_max_buffer_index(ctx, count, type, indices, @@ -740,7 +739,6 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, ctx->Array.ElementArrayBufferObj->Name, ctx->Array.ElementArrayBufferObj->Size); } - return; } /* XXX we could also find the min index and compare to 'start' * to see if start is correct. But it's more likely to get the -- cgit v1.2.3 From 5ce9183c1c535d924a79c2b6b280c6a2648cec19 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 29 Jan 2010 08:38:21 -0700 Subject: vbo: fix missing state validation bugs Commit 2708ddfb06a36d8568e2aa130bf1f7d551fcd309 caused a few regressions. We need to check/validate state after calling bind_arrays() because it might set the _NEW_ARRAYS flag if the varying VP inputs change. The symptom of this problem was some attribute arrays being ignored (or interpreted as constant-valued) in glDrawRangeElements or glMultiDrawElements. A follow-on patch will add some additional asserts to try to catch this kind of thing in the future. (cherry picked from commit 3cba779e16935f7c3a0bfd8af48bd5e015068e96) --- src/mesa/vbo/vbo_exec_array.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/mesa/vbo/vbo_exec_array.c') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 392da43c5e..88502f3d35 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -443,6 +443,13 @@ recalculate_input_bindings(GLcontext *ctx) } +/** + * Examine the enabled vertex arrays to set the exec->array.inputs[] values. + * These will point to the arrays to actually use for drawing. Some will + * be user-provided arrays, other will be zero-stride const-valued arrays. + * Note that this might set the _NEW_ARRAY dirty flag so state validation + * must be done after this call. + */ static void bind_arrays(GLcontext *ctx) { @@ -484,9 +491,6 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) FLUSH_CURRENT( ctx, 0 ); - if (ctx->NewState) - _mesa_update_state( ctx ); - if (!_mesa_valid_to_render(ctx, "glDrawArrays")) { return; } @@ -600,18 +604,16 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode, FLUSH_CURRENT( ctx, 0 ); - if (ctx->NewState) - _mesa_update_state( ctx ); - if (!_mesa_valid_to_render(ctx, "glDraw[Range]Elements")) { return; } + bind_arrays( ctx ); + + /* check for dirty state again */ if (ctx->NewState) _mesa_update_state( ctx ); - bind_arrays( ctx ); - ib.count = count; ib.type = type; ib.obj = ctx->Array.ElementArrayBufferObj; @@ -848,16 +850,10 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode, FLUSH_CURRENT( ctx, 0 ); - if (ctx->NewState) - _mesa_update_state( ctx ); - if (!_mesa_valid_to_render(ctx, "glMultiDrawElements")) { return; } - if (ctx->NewState) - _mesa_update_state( ctx ); - prim = _mesa_calloc(primcount * sizeof(*prim)); if (prim == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements"); @@ -869,6 +865,10 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode, */ bind_arrays( ctx ); + /* check for dirty state again */ + if (ctx->NewState) + _mesa_update_state( ctx ); + switch (type) { case GL_UNSIGNED_INT: index_type_size = 4; -- cgit v1.2.3