api_validate.c revision a2b9bad251b058f6255fa037b842c5465c0609a2
1 2/* 3 * Mesa 3-D graphics library 4 * Version: 5.1 5 * 6 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26#include "glheader.h" 27#include "api_validate.h" 28#include "context.h" 29#include "imports.h" 30#include "mtypes.h" 31#include "state.h" 32 33 34GLboolean 35_mesa_validate_DrawElements(GLcontext *ctx, 36 GLenum mode, GLsizei count, GLenum type, 37 const GLvoid *indices) 38{ 39 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 40 41 if (count <= 0) { 42 if (count < 0) 43 _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); 44 return GL_FALSE; 45 } 46 47 if (mode > GL_POLYGON) { 48 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(mode)" ); 49 return GL_FALSE; 50 } 51 52 if (type != GL_UNSIGNED_INT && 53 type != GL_UNSIGNED_BYTE && 54 type != GL_UNSIGNED_SHORT) 55 { 56 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); 57 return GL_FALSE; 58 } 59 60 if (ctx->NewState) 61 _mesa_update_state(ctx); 62 63 /* Always need vertex positions */ 64 if (!ctx->Array.Vertex.Enabled 65 && !(ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled)) 66 return GL_FALSE; 67 68 if (ctx->Const.CheckArrayBounds) { 69 /* find max array index */ 70 GLuint max = 0; 71 GLint i; 72 if (type == GL_UNSIGNED_INT) { 73 for (i = 0; i < count; i++) 74 if (((GLuint *) indices)[i] > max) 75 max = ((GLuint *) indices)[i]; 76 } 77 else if (type == GL_UNSIGNED_SHORT) { 78 for (i = 0; i < count; i++) 79 if (((GLushort *) indices)[i] > max) 80 max = ((GLushort *) indices)[i]; 81 } 82 else { 83 ASSERT(type == GL_UNSIGNED_BYTE); 84 for (i = 0; i < count; i++) 85 if (((GLubyte *) indices)[i] > max) 86 max = ((GLubyte *) indices)[i]; 87 } 88 if (max >= ctx->Array._MaxElement) { 89 /* the max element is out of bounds of one or more enabled arrays */ 90 return GL_FALSE; 91 } 92 } 93 94 return GL_TRUE; 95} 96 97 98GLboolean 99_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, 100 GLuint start, GLuint end, 101 GLsizei count, GLenum type, 102 const GLvoid *indices) 103{ 104 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 105 106 if (count <= 0) { 107 if (count < 0) 108 _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" ); 109 return GL_FALSE; 110 } 111 112 if (mode > GL_POLYGON) { 113 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(mode)" ); 114 return GL_FALSE; 115 } 116 117 if (end < start) { 118 _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(end<start)"); 119 return GL_FALSE; 120 } 121 122 if (type != GL_UNSIGNED_INT && 123 type != GL_UNSIGNED_BYTE && 124 type != GL_UNSIGNED_SHORT) { 125 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(type)" ); 126 return GL_FALSE; 127 } 128 129 if (ctx->NewState) 130 _mesa_update_state(ctx); 131 132 /* Always need vertex positions */ 133 if (!ctx->Array.Vertex.Enabled 134 && !(ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled)) 135 return GL_FALSE; 136 137 if (ctx->Const.CheckArrayBounds) { 138 /* Find max array index. 139 * We don't trust the user's start and end values. 140 */ 141 GLuint max = 0; 142 GLint i; 143 if (type == GL_UNSIGNED_INT) { 144 for (i = 0; i < count; i++) 145 if (((GLuint *) indices)[i] > max) 146 max = ((GLuint *) indices)[i]; 147 } 148 else if (type == GL_UNSIGNED_SHORT) { 149 for (i = 0; i < count; i++) 150 if (((GLushort *) indices)[i] > max) 151 max = ((GLushort *) indices)[i]; 152 } 153 else { 154 ASSERT(type == GL_UNSIGNED_BYTE); 155 for (i = 0; i < count; i++) 156 if (((GLubyte *) indices)[i] > max) 157 max = ((GLubyte *) indices)[i]; 158 } 159 if (max >= ctx->Array._MaxElement) { 160 /* the max element is out of bounds of one or more enabled arrays */ 161 return GL_FALSE; 162 } 163 } 164 165 return GL_TRUE; 166} 167 168 169/** 170 * Called from the tnl module to error check the function parameters and 171 * verify that we really can draw something. 172 */ 173GLboolean 174_mesa_validate_DrawArrays(GLcontext *ctx, 175 GLenum mode, GLint start, GLsizei count) 176{ 177 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 178 179 if (count < 0) { 180 _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); 181 return GL_FALSE; 182 } 183 184 if (mode > GL_POLYGON) { 185 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); 186 return GL_FALSE; 187 } 188 189 if (ctx->NewState) 190 _mesa_update_state(ctx); 191 192 /* Always need vertex positions */ 193 if (!ctx->Array.Vertex.Enabled 194 && !(ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled)) 195 return GL_FALSE; 196 197 if (ctx->Const.CheckArrayBounds) { 198 if (start + count > ctx->Array._MaxElement) 199 return GL_FALSE; 200 } 201 202 return GL_TRUE; 203} 204