api_validate.c revision a48b0a5ce7fc17eab4daa375fb95768fa2f50825
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" 318446d1bab15ef82b35b8980a0a56072ace6feb04Brian Paul#include "state.h" 32cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 3358e991705392a2e17a1c8b034f4083a0adaf1943Keith Whitwell 34bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul 35bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul/** 36bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul * \return number of bytes in array [count] of type. 37bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul */ 38bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paulstatic GLsizei 39bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paulindex_bytes(GLenum type, GLsizei count) 40bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul{ 41bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul if (type == GL_UNSIGNED_INT) { 42bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul return count * sizeof(GLuint); 43bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul } 44bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul else if (type == GL_UNSIGNED_BYTE) { 45bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul return count * sizeof(GLubyte); 46bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul } 47bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul else { 48bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul ASSERT(type == GL_UNSIGNED_SHORT); 49bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul return count * sizeof(GLushort); 50bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul } 51bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul} 52bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul 53bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul 54d8c6719f95b1543296ac954f95d13b048ae48634Brian/** 55d8c6719f95b1543296ac954f95d13b048ae48634Brian * Find the max index in the given element/index buffer 56d8c6719f95b1543296ac954f95d13b048ae48634Brian */ 57d8c6719f95b1543296ac954f95d13b048ae48634Brianstatic GLuint 58d8c6719f95b1543296ac954f95d13b048ae48634Brianmax_buffer_index(GLcontext *ctx, GLuint count, GLenum type, 59d8c6719f95b1543296ac954f95d13b048ae48634Brian const void *indices, 60d8c6719f95b1543296ac954f95d13b048ae48634Brian struct gl_buffer_object *elementBuf) 61d8c6719f95b1543296ac954f95d13b048ae48634Brian{ 62d8c6719f95b1543296ac954f95d13b048ae48634Brian const GLubyte *map = NULL; 63d8c6719f95b1543296ac954f95d13b048ae48634Brian GLuint max = 0; 6437f2117cd132527ebf89f9294b2f35db87326460José Fonseca GLuint i; 65d8c6719f95b1543296ac954f95d13b048ae48634Brian 66434ec3ada841915a00ffc23f699401eb3e7b37eeBrian Paul if (_mesa_is_bufferobj(elementBuf)) { 67d8c6719f95b1543296ac954f95d13b048ae48634Brian /* elements are in a user-defined buffer object. need to map it */ 6888af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, 6988af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul GL_READ_ONLY, elementBuf); 70d8c6719f95b1543296ac954f95d13b048ae48634Brian /* Actual address is the sum of pointers */ 71d8c6719f95b1543296ac954f95d13b048ae48634Brian indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices); 72d8c6719f95b1543296ac954f95d13b048ae48634Brian } 73d8c6719f95b1543296ac954f95d13b048ae48634Brian 74d8c6719f95b1543296ac954f95d13b048ae48634Brian if (type == GL_UNSIGNED_INT) { 75d8c6719f95b1543296ac954f95d13b048ae48634Brian for (i = 0; i < count; i++) 76d8c6719f95b1543296ac954f95d13b048ae48634Brian if (((GLuint *) indices)[i] > max) 77d8c6719f95b1543296ac954f95d13b048ae48634Brian max = ((GLuint *) indices)[i]; 78d8c6719f95b1543296ac954f95d13b048ae48634Brian } 79d8c6719f95b1543296ac954f95d13b048ae48634Brian else if (type == GL_UNSIGNED_SHORT) { 80d8c6719f95b1543296ac954f95d13b048ae48634Brian for (i = 0; i < count; i++) 81d8c6719f95b1543296ac954f95d13b048ae48634Brian if (((GLushort *) indices)[i] > max) 82d8c6719f95b1543296ac954f95d13b048ae48634Brian max = ((GLushort *) indices)[i]; 83d8c6719f95b1543296ac954f95d13b048ae48634Brian } 84d8c6719f95b1543296ac954f95d13b048ae48634Brian else { 85d8c6719f95b1543296ac954f95d13b048ae48634Brian ASSERT(type == GL_UNSIGNED_BYTE); 86d8c6719f95b1543296ac954f95d13b048ae48634Brian for (i = 0; i < count; i++) 87d8c6719f95b1543296ac954f95d13b048ae48634Brian if (((GLubyte *) indices)[i] > max) 88d8c6719f95b1543296ac954f95d13b048ae48634Brian max = ((GLubyte *) indices)[i]; 89d8c6719f95b1543296ac954f95d13b048ae48634Brian } 90d8c6719f95b1543296ac954f95d13b048ae48634Brian 91d8c6719f95b1543296ac954f95d13b048ae48634Brian if (map) { 9288af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuf); 93d8c6719f95b1543296ac954f95d13b048ae48634Brian } 94d8c6719f95b1543296ac954f95d13b048ae48634Brian 95d8c6719f95b1543296ac954f95d13b048ae48634Brian return max; 96d8c6719f95b1543296ac954f95d13b048ae48634Brian} 97d8c6719f95b1543296ac954f95d13b048ae48634Brian 9888af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul 9988af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul/** 10088af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * Check if OK to render by examining framebuffer status and vertex arrays. 10188af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul */ 102263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihanestatic GLboolean 103a48b0a5ce7fc17eab4daa375fb95768fa2f50825Brian Paulcheck_valid_to_render(GLcontext *ctx, const char *function) 104263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane{ 105263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 106263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 107a48b0a5ce7fc17eab4daa375fb95768fa2f50825Brian Paul "%s(incomplete framebuffer)", function); 108263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane return GL_FALSE; 109263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane } 110263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane 11197dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul#if FEATURE_es2_glsl 11297dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul /* For ES2, we can draw if any vertex array is enabled (and we should 11397dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul * always have a vertex program/shader). 11497dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul */ 11597dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul if (ctx->Array.ArrayObj->_Enabled == 0x0 || !ctx->VertexProgram._Current) 11697dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul return GL_FALSE; 11797dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul#else 11897dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul /* For regular OpenGL, only draw if we have vertex positions (regardless 11997dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul * of whether or not we have a vertex program/shader). 12097dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul */ 12197dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul if (!ctx->Array.ArrayObj->Vertex.Enabled && 122263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane !ctx->Array.ArrayObj->VertexAttrib[0].Enabled) 123263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane return GL_FALSE; 12497dd2ddbd97ba95e8bc8ab572ec05e8081556e1eBrian Paul#endif 125263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane 126263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane return GL_TRUE; 127263b96e160606975285154c4b8b610fcb8f4c930Alan Hourihane} 128d8c6719f95b1543296ac954f95d13b048ae48634Brian 12988af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul 13088af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul/** 13188af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * Error checking for glDrawElements(). Includes parameter checking 13288af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * and VBO bounds checking. 13388af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * \return GL_TRUE if OK to render, GL_FALSE if error found 13488af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul */ 135cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith WhitwellGLboolean 136cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell_mesa_validate_DrawElements(GLcontext *ctx, 13722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes GLenum mode, GLsizei count, GLenum type, 138cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell const GLvoid *indices) 139cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{ 14022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 141cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 142cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (count <= 0) { 143cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (count < 0) 14408836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); 145cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 146cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 147cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 148464bc3b6747108dd32e4a9fcfe6549a9d4a52a95Brian Paul if (mode > GL_POLYGON) { 149a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(mode)" ); 150cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 151cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 152cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 15322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes if (type != GL_UNSIGNED_INT && 15422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes type != GL_UNSIGNED_BYTE && 155cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell type != GL_UNSIGNED_SHORT) 156cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell { 15708836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); 158cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 159cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 160cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 161cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (ctx->NewState) 162a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_update_state(ctx); 163a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul 164a48b0a5ce7fc17eab4daa375fb95768fa2f50825Brian Paul if (!check_valid_to_render(ctx, "glDrawElements")) 165a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul return GL_FALSE; 166a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul 16703e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul /* Vertex buffer object tests */ 168434ec3ada841915a00ffc23f699401eb3e7b37eeBrian Paul if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) { 16903e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul /* use indices in the buffer object */ 170d8c6719f95b1543296ac954f95d13b048ae48634Brian /* make sure count doesn't go outside buffer bounds */ 171bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { 17203e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); 17303e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul return GL_FALSE; 17403e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul } 17503e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul } 17637ece4df7c654b30b6720044b35a83694d7e5bb3Brian else { 17737ece4df7c654b30b6720044b35a83694d7e5bb3Brian /* not using a VBO */ 17837ece4df7c654b30b6720044b35a83694d7e5bb3Brian if (!indices) 17937ece4df7c654b30b6720044b35a83694d7e5bb3Brian return GL_FALSE; 18037ece4df7c654b30b6720044b35a83694d7e5bb3Brian } 18103e29a5f77c13b7b888bd8443cb2752850e47d6aBrian Paul 182a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul if (ctx->Const.CheckArrayBounds) { 183a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul /* find max array index */ 184d8c6719f95b1543296ac954f95d13b048ae48634Brian GLuint max = max_buffer_index(ctx, count, type, indices, 185d8c6719f95b1543296ac954f95d13b048ae48634Brian ctx->Array.ElementArrayBufferObj); 186a185bcbdec856cc98c26098e4e447a683eed14d1Brian Paul if (max >= ctx->Array.ArrayObj->_MaxElement) { 187a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul /* the max element is out of bounds of one or more enabled arrays */ 18887fbc9a14ed2bdd24d84c38431abbf7b0c275998Brian Paul _mesa_warning(ctx, "glDrawElements() index=%u is " 189a185bcbdec856cc98c26098e4e447a683eed14d1Brian Paul "out of bounds (max=%u)", max, ctx->Array.ArrayObj->_MaxElement); 190a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul return GL_FALSE; 191a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul } 192a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul } 193cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 194cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_TRUE; 195cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell} 196cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 19788af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul 19888af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul/** 19988af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * Error checking for glDrawRangeElements(). Includes parameter checking 20088af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * and VBO bounds checking. 20188af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * \return GL_TRUE if OK to render, GL_FALSE if error found 20288af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul */ 203cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith WhitwellGLboolean 20422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, 20522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes GLuint start, GLuint end, 20622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes GLsizei count, GLenum type, 207cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell const GLvoid *indices) 208cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{ 20922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 210cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 211cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (count <= 0) { 212cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (count < 0) 213a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" ); 214cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 215cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 216cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 217464bc3b6747108dd32e4a9fcfe6549a9d4a52a95Brian Paul if (mode > GL_POLYGON) { 218a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(mode)" ); 219cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 220cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 221cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 222cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (end < start) { 22308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(end<start)"); 224cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 225cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 226cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 22722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes if (type != GL_UNSIGNED_INT && 22822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes type != GL_UNSIGNED_BYTE && 22961bac6014aa15e0bec134e290aebac18f9815299Brian Paul type != GL_UNSIGNED_SHORT) { 230a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(type)" ); 231cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 232cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 233cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 234cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (ctx->NewState) 235a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_update_state(ctx); 236a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul 237a48b0a5ce7fc17eab4daa375fb95768fa2f50825Brian Paul if (!check_valid_to_render(ctx, "glDrawRangeElements")) 238a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul return GL_FALSE; 239a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul 24037ece4df7c654b30b6720044b35a83694d7e5bb3Brian /* Vertex buffer object tests */ 241434ec3ada841915a00ffc23f699401eb3e7b37eeBrian Paul if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) { 242d8c6719f95b1543296ac954f95d13b048ae48634Brian /* use indices in the buffer object */ 243d8c6719f95b1543296ac954f95d13b048ae48634Brian /* make sure count doesn't go outside buffer bounds */ 244bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93Brian Paul if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { 245ef5935bc94a1439eb8f1731732a3eabd0e360407Brian _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds"); 246d8c6719f95b1543296ac954f95d13b048ae48634Brian return GL_FALSE; 247d8c6719f95b1543296ac954f95d13b048ae48634Brian } 24837ece4df7c654b30b6720044b35a83694d7e5bb3Brian } 24937ece4df7c654b30b6720044b35a83694d7e5bb3Brian else { 250d8c6719f95b1543296ac954f95d13b048ae48634Brian /* not using a VBO */ 25137ece4df7c654b30b6720044b35a83694d7e5bb3Brian if (!indices) 25237ece4df7c654b30b6720044b35a83694d7e5bb3Brian return GL_FALSE; 25337ece4df7c654b30b6720044b35a83694d7e5bb3Brian } 25437ece4df7c654b30b6720044b35a83694d7e5bb3Brian 255a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul if (ctx->Const.CheckArrayBounds) { 256d8c6719f95b1543296ac954f95d13b048ae48634Brian GLuint max = max_buffer_index(ctx, count, type, indices, 257d8c6719f95b1543296ac954f95d13b048ae48634Brian ctx->Array.ElementArrayBufferObj); 258a185bcbdec856cc98c26098e4e447a683eed14d1Brian Paul if (max >= ctx->Array.ArrayObj->_MaxElement) { 259a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul /* the max element is out of bounds of one or more enabled arrays */ 260c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul return GL_FALSE; 261a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul } 262c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul } 263a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul 264c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul return GL_TRUE; 265c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul} 266c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul 267cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 268c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul/** 269c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul * Called from the tnl module to error check the function parameters and 270c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul * verify that we really can draw something. 27188af3f8783452dcf50a9e2e82076f52b2044f643Brian Paul * \return GL_TRUE if OK to render, GL_FALSE if error found 272c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul */ 273cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith WhitwellGLboolean 27422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes_mesa_validate_DrawArrays(GLcontext *ctx, 275cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell GLenum mode, GLint start, GLsizei count) 276cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{ 27722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 278cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 2795cb203433ab5c4e54a7386a816263a237c716aa2Brian if (count <= 0) { 2805cb203433ab5c4e54a7386a816263a237c716aa2Brian if (count < 0) 2815cb203433ab5c4e54a7386a816263a237c716aa2Brian _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); 282cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 283cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 284cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 285464bc3b6747108dd32e4a9fcfe6549a9d4a52a95Brian Paul if (mode > GL_POLYGON) { 28608836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); 287cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return GL_FALSE; 288cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell } 289cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 290cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (ctx->NewState) 291a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul _mesa_update_state(ctx); 292c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul 293a48b0a5ce7fc17eab4daa375fb95768fa2f50825Brian Paul if (!check_valid_to_render(ctx, "glDrawArrays")) 294c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul return GL_FALSE; 295c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul 296a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul if (ctx->Const.CheckArrayBounds) { 297a185bcbdec856cc98c26098e4e447a683eed14d1Brian Paul if (start + count > (GLint) ctx->Array.ArrayObj->_MaxElement) 298c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul return GL_FALSE; 299a2b9bad251b058f6255fa037b842c5465c0609a2Brian Paul } 300c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul 301c5b1e81de48de5d8830bf5d92ff767ad1985e46eBrian Paul return GL_TRUE; 302cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell} 303