api_validate.c revision e9968ebfa40b4740601c1596950ebd3f168664b0
1cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/* 2cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Mesa 3-D graphics library 3a3c3bc9ece7e7c55c8832dbc8c50ab1c34f5bfe9Brian * Version: 7.1 4cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * 537ece4df7c654b30b6720044b35a83694d7e5bb3Brian * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * 7cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 8cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * copy of this software and associated documentation files (the "Software"), 9cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * to deal in the Software without restriction, including without limitation 10cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 12cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Software is furnished to do so, subject to the following conditions: 13cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * 14cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * The above copyright notice and this permission notice shall be included 15cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * in all copies or substantial portions of the Software. 16cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * 17cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */ 24cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 25cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "glheader.h" 268446d1bab15ef82b35b8980a0a56072ace6feb04Brian Paul#include "api_validate.h" 27434ec3ada841915a00ffc23f699401eb3e7b37eeBrian Paul#include "bufferobj.h" 28cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "context.h" 293c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h" 30cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "mtypes.h" 3192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt#include "vbo/vbo.h" 3258e991705392a2e17a1c8b034f4083a0adaf1943Keith Whitwell 33bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul 34bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul/** 35bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul * \return number of bytes in array [count] of type. 36bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul */ 37bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paulstatic GLsizei 38bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paulindex_bytes(GLenum type, GLsizei count) 39bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul{ 40bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul if (type == GL_UNSIGNED_INT) { 41bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul return count * sizeof(GLuint); 42bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul } 43bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul else if (type == GL_UNSIGNED_BYTE) { 44bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul return count * sizeof(GLubyte); 45bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul } 46bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul else { 47bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul ASSERT(type == GL_UNSIGNED_SHORT); 48bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul return count * sizeof(GLushort); 49bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul } 50bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul} 51bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul 52bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul 53d8c6719f95b1543296ac954f95d13b048ae48634Brian/** 54e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul * Find the max index in the given element/index buffer 55e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul */ 56e5d29ebb5e5dd923c9c60972170d072120007aabBrian PaulGLuint 57e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul_mesa_max_buffer_index(GLcontext *ctx, GLuint count, GLenum type, 58e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul const void *indices, 59e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul struct gl_buffer_object *elementBuf) 60e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul{ 61e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul const GLubyte *map = NULL; 62e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul GLuint max = 0; 63e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul GLuint i; 64e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul 65e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul if (_mesa_is_bufferobj(elementBuf)) { 66e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul /* elements are in a user-defined buffer object. need to map it */ 67e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, 68e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul GL_READ_ONLY, elementBuf); 69e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul /* Actual address is the sum of pointers */ 70e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices); 71e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul } 72e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul 73e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul if (type == GL_UNSIGNED_INT) { 74e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul for (i = 0; i < count; i++) 75e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul if (((GLuint *) indices)[i] > max) 76e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul max = ((GLuint *) indices)[i]; 77e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul } 78e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul else if (type == GL_UNSIGNED_SHORT) { 79e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul for (i = 0; i < count; i++) 80e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul if (((GLushort *) indices)[i] > max) 81e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul max = ((GLushort *) indices)[i]; 82e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul } 83e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul else { 84e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul ASSERT(type == GL_UNSIGNED_BYTE); 85e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul for (i = 0; i < count; i++) 86e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul if (((GLubyte *) indices)[i] > max) 87e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul max = ((GLubyte *) indices)[i]; 88e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul } 89e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul 90e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul if (map) { 91e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuf); 92e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul } 93e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul 94e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul return max; 95e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul} 96e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul 97e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul 98e5d29ebb5e5dd923c9c60972170d072120007aabBrian Paul/** 99b6e5600bd460245afef605dbfbcf6650ff677dcbBrian Paul * Check if OK to draw arrays/elements. 10088af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul */ 101263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihanestatic GLboolean 102a48b0a5ce7fc17eab4daa375fb95768fa2f50825Brian Paulcheck_valid_to_render(GLcontext *ctx, const char *function) 103263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane{ 104b6e5600bd460245afef605dbfbcf6650ff677dcbBrian Paul if (!_mesa_valid_to_render(ctx, function)) { 105263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane return GL_FALSE; 106263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane } 107263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane 10897dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul#if FEATURE_es2_glsl 10997dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul /* For ES2, we can draw if any vertex array is enabled (and we should 11097dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul * always have a vertex program/shader). 11197dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul */ 11297dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul if (ctx->Array.ArrayObj->_Enabled == 0x0 || !ctx->VertexProgram._Current) 11397dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul return GL_FALSE; 11497dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul#else 11597dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul /* For regular OpenGL, only draw if we have vertex positions (regardless 11697dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul * of whether or not we have a vertex program/shader). 11797dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul */ 11897dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul if (!ctx->Array.ArrayObj->Vertex.Enabled && 119263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane !ctx->Array.ArrayObj->VertexAttrib[0].Enabled) 120263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane return GL_FALSE; 12197dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul#endif 122263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane 123263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane return GL_TRUE; 124263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane} 125d8c6719f95b1543296ac954f95d13b048ae48634Brian 126e9968ebfa40b4740601c1596950ebd3f168664b0Brian Paul 127e9968ebfa40b4740601c1596950ebd3f168664b0Brian Paul/** 128e9968ebfa40b4740601c1596950ebd3f168664b0Brian Paul * Do bounds checking on array element indexes. Check that the vertices 129e9968ebfa40b4740601c1596950ebd3f168664b0Brian Paul * pointed to by the indices don't lie outside buffer object bounds. 130e9968ebfa40b4740601c1596950ebd3f168664b0Brian Paul * \return GL_TRUE if OK, GL_FALSE if any indexed vertex goes is out of bounds 131e9968ebfa40b4740601c1596950ebd3f168664b0Brian Paul */ 13292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic GLboolean 13392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtcheck_index_bounds(GLcontext *ctx, GLsizei count, GLenum type, 13492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt const GLvoid *indices, GLint basevertex) 13592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{ 13692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt struct _mesa_prim prim; 13792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt struct _mesa_index_buffer ib; 13892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt GLuint min, max; 13992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt 14092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt /* Only the X Server needs to do this -- otherwise, accessing outside 14192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt * array/BO bounds allows application termination. 14292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt */ 14392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt if (!ctx->Const.CheckArrayBounds) 14492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt return GL_TRUE; 14592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt 14692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt memset(&prim, 0, sizeof(prim)); 14792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt prim.count = count; 14892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt 14992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt memset(&ib, 0, sizeof(ib)); 15092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt ib.type = type; 15192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt ib.ptr = indices; 15292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt ib.obj = ctx->Array.ElementArrayBufferObj; 15392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt 15492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt vbo_get_minmax_index(ctx, &prim, &ib, &min, &max); 15592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt 156391b396f3fb300a912e6d9bfbf26f49cc30e52dfMichel Dänzer if ((int)(min + basevertex) < 0 || 15792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt max + basevertex > ctx->Array.ArrayObj->_MaxElement) { 15892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt /* the max element is out of bounds of one or more enabled arrays */ 159e9968ebfa40b4740601c1596950ebd3f168664b0Brian Paul _mesa_warning(ctx, "glDrawElements() index=%u is out of bounds (max=%u)", 160e9968ebfa40b4740601c1596950ebd3f168664b0Brian Paul max, ctx->Array.ArrayObj->_MaxElement); 16192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt return GL_FALSE; 16292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt } 16392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt 16492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt return GL_TRUE; 16592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt} 16688af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul 167e9968ebfa40b4740601c1596950ebd3f168664b0Brian Paul 16888af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul/** 16988af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * Error checking for glDrawElements(). Includes parameter checking 17088af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * and VBO bounds checking. 17188af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * \return GL_TRUE if OK to render, GL_FALSE if error found 17288af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul */ 173cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith WhitwellGLboolean 174cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell_mesa_validate_DrawElements(GLcontext *ctx, 17522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes GLenum mode, GLsizei count, GLenum type, 17692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt const GLvoid *indices, GLint basevertex) 177cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{ 17822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 179cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 180cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (count <= 0) { 181cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (count < 0) 18208836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); 183cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 184cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 185cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 186464bc3b6747108dd32e4a9fcfe6549a9d4a52a95Brian Paul if (mode > GL_POLYGON) { 187a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(mode)" ); 188cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 189cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 190cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 19122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes if (type != GL_UNSIGNED_INT && 19222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes type != GL_UNSIGNED_BYTE && 193cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell type != GL_UNSIGNED_SHORT) 194cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell { 19508836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); 196cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 197cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 198cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 199a48b0a5ce7fc17eab4daa375fb95768fa2f50825Brian Paul if (!check_valid_to_render(ctx, "glDrawElements")) 200a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul return GL_FALSE; 201a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul 20203e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul /* Vertex buffer object tests */ 203434ec3ada841915a00ffc23f699401eb3e7b37eeBrian Paul if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) { 20403e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul /* use indices in the buffer object */ 205d8c6719f95b1543296ac954f95d13b048ae48634Brian /* make sure count doesn't go outside buffer bounds */ 206bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { 20703e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); 20803e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul return GL_FALSE; 20903e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul } 21003e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul } 21137ece4df7c654b30b6720044b35a83694d7e5bb3Brian else { 21237ece4df7c654b30b6720044b35a83694d7e5bb3Brian /* not using a VBO */ 21337ece4df7c654b30b6720044b35a83694d7e5bb3Brian if (!indices) 21437ece4df7c654b30b6720044b35a83694d7e5bb3Brian return GL_FALSE; 21537ece4df7c654b30b6720044b35a83694d7e5bb3Brian } 21603e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul 21792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt if (!check_index_bounds(ctx, count, type, indices, basevertex)) 21892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt return GL_FALSE; 219cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 220cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_TRUE; 221cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell} 222cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 22388af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul 22488af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul/** 22588af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * Error checking for glDrawRangeElements(). Includes parameter checking 22688af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * and VBO bounds checking. 22788af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * \return GL_TRUE if OK to render, GL_FALSE if error found 22888af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul */ 229cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith WhitwellGLboolean 23022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, 23122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes GLuint start, GLuint end, 23222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes GLsizei count, GLenum type, 23392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt const GLvoid *indices, GLint basevertex) 234cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{ 23522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 236cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 237cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (count <= 0) { 238cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (count < 0) 239a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" ); 240cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 241cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 242cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 243464bc3b6747108dd32e4a9fcfe6549a9d4a52a95Brian Paul if (mode > GL_POLYGON) { 244a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(mode)" ); 245cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 246cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 247cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 248cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (end < start) { 24908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(end<start)"); 250cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 251cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 252cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 25322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes if (type != GL_UNSIGNED_INT && 25422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes type != GL_UNSIGNED_BYTE && 25561bac6014aa15e0bec134e290aebac18f9815299Brian Paul type != GL_UNSIGNED_SHORT) { 256a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(type)" ); 257cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 258cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 259cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 260a48b0a5ce7fc17eab4daa375fb95768fa2f50825Brian Paul if (!check_valid_to_render(ctx, "glDrawRangeElements")) 261a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul return GL_FALSE; 262a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul 26337ece4df7c654b30b6720044b35a83694d7e5bb3Brian /* Vertex buffer object tests */ 264434ec3ada841915a00ffc23f699401eb3e7b37eeBrian Paul if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) { 265d8c6719f95b1543296ac954f95d13b048ae48634Brian /* use indices in the buffer object */ 266d8c6719f95b1543296ac954f95d13b048ae48634Brian /* make sure count doesn't go outside buffer bounds */ 267bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { 268ef5935bc94a1439eb8f1731732a3eabd0e360407Brian _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds"); 269d8c6719f95b1543296ac954f95d13b048ae48634Brian return GL_FALSE; 270d8c6719f95b1543296ac954f95d13b048ae48634Brian } 27137ece4df7c654b30b6720044b35a83694d7e5bb3Brian } 27237ece4df7c654b30b6720044b35a83694d7e5bb3Brian else { 273d8c6719f95b1543296ac954f95d13b048ae48634Brian /* not using a VBO */ 27437ece4df7c654b30b6720044b35a83694d7e5bb3Brian if (!indices) 27537ece4df7c654b30b6720044b35a83694d7e5bb3Brian return GL_FALSE; 27637ece4df7c654b30b6720044b35a83694d7e5bb3Brian } 27737ece4df7c654b30b6720044b35a83694d7e5bb3Brian 27892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt if (!check_index_bounds(ctx, count, type, indices, basevertex)) 27992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt return GL_FALSE; 280a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul 281c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul return GL_TRUE; 282c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul} 283c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul 284cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 285c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul/** 286c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul * Called from the tnl module to error check the function parameters and 287c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul * verify that we really can draw something. 28888af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * \return GL_TRUE if OK to render, GL_FALSE if error found 289c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul */ 290cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith WhitwellGLboolean 29122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes_mesa_validate_DrawArrays(GLcontext *ctx, 292cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell GLenum mode, GLint start, GLsizei count) 293cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{ 29422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 295cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 2965cb203433ab5c4e54a7386a816263a237c716aa2Brian if (count <= 0) { 2975cb203433ab5c4e54a7386a816263a237c716aa2Brian if (count < 0) 2985cb203433ab5c4e54a7386a816263a237c716aa2Brian _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); 299cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 300cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 301cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 302464bc3b6747108dd32e4a9fcfe6549a9d4a52a95Brian Paul if (mode > GL_POLYGON) { 30308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); 304cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 305cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 306cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 307a48b0a5ce7fc17eab4daa375fb95768fa2f50825Brian Paul if (!check_valid_to_render(ctx, "glDrawArrays")) 308c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul return GL_FALSE; 309c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul 310a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul if (ctx->Const.CheckArrayBounds) { 311a185bcbdec856cc98c26098e4e447a683eed14d1Brian Paul if (start + count > (GLint) ctx->Array.ArrayObj->_MaxElement) 312c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul return GL_FALSE; 313a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul } 314c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul 315c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul return GL_TRUE; 316cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell} 317