From 2655d437569c5bce7c56782792cbd4460b9f758b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 21 Sep 2009 14:23:07 -0600 Subject: mesa: refine the error checking vbo_exec_DrawRangeElements() If the 'end' index is out of bounds issue a warning as before. But instead of just no-op'ing the draw call, examine the actual array indices to see if they're OK. If the max array index is out of bounds, issue another warning and no-op the draw call. Otherwise, draw normally. This is a debug build-only feature since it could impact performance. This "fixes" the missing torus in the OGL Distilled / Picking demo. --- src/mesa/vbo/vbo_exec_array.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 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 12911f5750..3f0656a816 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -677,9 +677,10 @@ vbo_exec_DrawRangeElements(GLenum mode, /* the max element is out of bounds of one or more enabled arrays */ _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, " "type 0x%x, indices=%p)\n" - "\tindex=%u is out of bounds (max=%u) " - "Element Buffer %u (size %d)", - start, end, count, type, indices, end, + "\tend is out of bounds (max=%u) " + "Element Buffer %u (size %d)\n" + "\tThis should probably be fixed in the application.", + start, end, count, type, indices, ctx->Array.ArrayObj->_MaxElement - 1, ctx->Array.ElementArrayBufferObj->Name, ctx->Array.ElementArrayBufferObj->Size); @@ -689,7 +690,33 @@ vbo_exec_DrawRangeElements(GLenum mode, if (0) _mesa_print_arrays(ctx); - return; + +#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. + */ + { + GLuint max = _mesa_max_buffer_index(ctx, count, type, indices, + ctx->Array.ElementArrayBufferObj); + if (max >= ctx->Array.ArrayObj->_MaxElement) { + _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, " + "count %d, type 0x%x, indices=%p)\n" + "\tindex=%u is out of bounds (max=%u) " + "Element Buffer %u (size %d)\n" + "\tSkipping the glDrawRangeElements() call", + start, end, count, type, indices, max, + ctx->Array.ArrayObj->_MaxElement - 1, + 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 + * upper bound wrong. + */ + } +#endif } else if (0) { _mesa_printf("glDraw[Range]Elements" -- cgit v1.2.3 From 40603526f478a59b89a4c0a07c75a97dfe56b8c3 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 21 Sep 2009 14:23:07 -0600 Subject: mesa: refine the error checking vbo_exec_DrawRangeElements() If the 'end' index is out of bounds issue a warning as before. But instead of just no-op'ing the draw call, examine the actual array indices to see if they're OK. If the max array index is out of bounds, issue another warning and no-op the draw call. Otherwise, draw normally. This is a debug build-only feature since it could impact performance. This "fixes" the missing torus in the OGL Distilled / Picking demo. --- src/mesa/vbo/vbo_exec_array.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 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 b9550d6106..7eca7f5057 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -680,11 +680,12 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, if (end >= ctx->Array.ArrayObj->_MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ - _mesa_warning(ctx, "glDraw[Range]Elements{,BaseVertex}(start %u, end %u, " - "count %d, type 0x%x, indices=%p, base=%d)\n" - "\tindex=%u is out of bounds (max=%u) " - "Element Buffer %u (size %d)", - start, end, count, type, indices, end, basevertex, + _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, " + "type 0x%x, indices=%p)\n" + "\tend is out of bounds (max=%u) " + "Element Buffer %u (size %d)\n" + "\tThis should probably be fixed in the application.", + start, end, count, type, indices, ctx->Array.ArrayObj->_MaxElement - 1, ctx->Array.ElementArrayBufferObj->Name, ctx->Array.ElementArrayBufferObj->Size); @@ -694,7 +695,33 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, if (0) _mesa_print_arrays(ctx); - return; + +#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. + */ + { + GLuint max = _mesa_max_buffer_index(ctx, count, type, indices, + ctx->Array.ElementArrayBufferObj); + if (max >= ctx->Array.ArrayObj->_MaxElement) { + _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, " + "count %d, type 0x%x, indices=%p)\n" + "\tindex=%u is out of bounds (max=%u) " + "Element Buffer %u (size %d)\n" + "\tSkipping the glDrawRangeElements() call", + start, end, count, type, indices, max, + ctx->Array.ArrayObj->_MaxElement - 1, + 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 + * upper bound wrong. + */ + } +#endif } else if (0) { _mesa_printf("glDraw[Range]Elements{,BaseVertex}" -- cgit v1.2.3 From 9a3333f43600ed4b9a17e49f79004f0c8d289378 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 21 Sep 2009 16:51:34 -0600 Subject: vbo: restore some lost warning output --- src/mesa/vbo/vbo_exec_array.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 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 7eca7f5057..ee37eeb937 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -681,11 +681,11 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, if (end >= ctx->Array.ArrayObj->_MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, " - "type 0x%x, indices=%p)\n" + "type 0x%x, indices %p, base %d)\n" "\tend is out of bounds (max=%u) " "Element Buffer %u (size %d)\n" "\tThis should probably be fixed in the application.", - start, end, count, type, indices, + start, end, count, type, indices, basevertex, ctx->Array.ArrayObj->_MaxElement - 1, ctx->Array.ElementArrayBufferObj->Name, ctx->Array.ElementArrayBufferObj->Size); @@ -706,11 +706,12 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, ctx->Array.ElementArrayBufferObj); if (max >= ctx->Array.ArrayObj->_MaxElement) { _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, " - "count %d, type 0x%x, indices=%p)\n" + "count %d, type 0x%x, indices %p, base %p)\n" "\tindex=%u is out of bounds (max=%u) " "Element Buffer %u (size %d)\n" "\tSkipping the glDrawRangeElements() call", - start, end, count, type, indices, max, + start, end, count, type, indices, basevertex, + max, ctx->Array.ArrayObj->_MaxElement - 1, ctx->Array.ElementArrayBufferObj->Name, ctx->Array.ElementArrayBufferObj->Size); -- cgit v1.2.3 From 94a020cfe6cb1da04695897eed38b530af31f524 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 21 Sep 2009 16:54:35 -0600 Subject: vbo: added comment about max array index --- src/mesa/vbo/vbo_exec_array.c | 6 ++++++ 1 file changed, 6 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 ee37eeb937..668dc6eb24 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -678,6 +678,12 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, type, indices, basevertex )) return; + /* NOTE: It's important that 'end' is a reasonable value. + * in _tnl_draw_prims(), we use end to determine how many vertices + * to transform. If it's too large, we can unnecessarily split prims + * or we can read/write out of memory in several different places! + */ + if (end >= ctx->Array.ArrayObj->_MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, " -- cgit v1.2.3 From 1a816117258e594a073f6925edfcd2387071904d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Sep 2009 12:35:51 -0600 Subject: vbo: limit number of warnings to 10 Otherwise some apps will emit tons of warnings. --- src/mesa/vbo/vbo_exec_array.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 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 3f0656a816..39c2957631 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -667,6 +667,7 @@ vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) { + static GLuint warnCount = 0; GET_CURRENT_CONTEXT(ctx); if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, @@ -675,15 +676,19 @@ vbo_exec_DrawRangeElements(GLenum mode, if (end >= ctx->Array.ArrayObj->_MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ - _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, " - "type 0x%x, indices=%p)\n" - "\tend is out of bounds (max=%u) " - "Element Buffer %u (size %d)\n" - "\tThis should probably be fixed in the application.", - start, end, count, type, indices, - ctx->Array.ArrayObj->_MaxElement - 1, - ctx->Array.ElementArrayBufferObj->Name, - ctx->Array.ElementArrayBufferObj->Size); + warnCount++; + + if (warnCount < 10) { + _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, " + "type 0x%x, indices=%p)\n" + "\tend is out of bounds (max=%u) " + "Element Buffer %u (size %d)\n" + "\tThis should probably be fixed in the application.", + start, end, count, type, indices, + ctx->Array.ArrayObj->_MaxElement - 1, + ctx->Array.ElementArrayBufferObj->Name, + ctx->Array.ElementArrayBufferObj->Size); + } if (0) dump_element_buffer(ctx, type); @@ -700,15 +705,17 @@ vbo_exec_DrawRangeElements(GLenum mode, GLuint max = _mesa_max_buffer_index(ctx, count, type, indices, ctx->Array.ElementArrayBufferObj); if (max >= ctx->Array.ArrayObj->_MaxElement) { - _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, " - "count %d, type 0x%x, indices=%p)\n" - "\tindex=%u is out of bounds (max=%u) " - "Element Buffer %u (size %d)\n" - "\tSkipping the glDrawRangeElements() call", - start, end, count, type, indices, max, - ctx->Array.ArrayObj->_MaxElement - 1, - ctx->Array.ElementArrayBufferObj->Name, - ctx->Array.ElementArrayBufferObj->Size); + if (warnCount < 10) { + _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, " + "count %d, type 0x%x, indices=%p)\n" + "\tindex=%u is out of bounds (max=%u) " + "Element Buffer %u (size %d)\n" + "\tSkipping the glDrawRangeElements() call", + start, end, count, type, indices, max, + ctx->Array.ArrayObj->_MaxElement - 1, + ctx->Array.ElementArrayBufferObj->Name, + ctx->Array.ElementArrayBufferObj->Size); + } return; } /* XXX we could also find the min index and compare to 'start' -- cgit v1.2.3