api_validate.c revision c5b1e81de48de5d8830bf5d92ff767ad1985e46e
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 "image.h" /* for _mesa_sizeof_type() */ 30#include "imports.h" 31#include "mtypes.h" 32#include "state.h" 33 34 35GLboolean 36_mesa_validate_DrawElements(GLcontext *ctx, 37 GLenum mode, GLsizei count, GLenum type, 38 const GLvoid *indices) 39{ 40 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 41 42 if (count <= 0) { 43 if (count < 0) 44 _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); 45 return GL_FALSE; 46 } 47 48 if (mode > GL_POLYGON) { 49 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); 50 return GL_FALSE; 51 } 52 53 if (type != GL_UNSIGNED_INT && 54 type != GL_UNSIGNED_BYTE && 55 type != GL_UNSIGNED_SHORT) 56 { 57 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); 58 return GL_FALSE; 59 } 60 61 if (ctx->NewState) 62 _mesa_update_state( ctx ); 63 64 if (ctx->Array.Vertex.Enabled 65 || (ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled)) 66 return GL_TRUE; 67 else 68 return GL_FALSE; 69 70 return GL_TRUE; 71} 72 73 74GLboolean 75_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, 76 GLuint start, GLuint end, 77 GLsizei count, GLenum type, 78 const GLvoid *indices) 79{ 80 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 81 82 if (count <= 0) { 83 if (count < 0) 84 _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); 85 return GL_FALSE; 86 } 87 88 if (mode > GL_POLYGON) { 89 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); 90 return GL_FALSE; 91 } 92 93 if (end < start) { 94 _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(end<start)"); 95 return GL_FALSE; 96 } 97 98 if (type != GL_UNSIGNED_INT && 99 type != GL_UNSIGNED_BYTE && 100 type != GL_UNSIGNED_SHORT) { 101 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); 102 return GL_FALSE; 103 } 104 105 if (ctx->NewState) 106 _mesa_update_state( ctx ); 107 108 if (ctx->Array.Vertex.Enabled 109 || (ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled)) 110 return GL_TRUE; 111 else 112 return GL_FALSE; 113} 114 115 116/** 117 * Helper routine for validating vertex array data to be sure the given 118 * element lies within the legal range (i.e. vertex buffer object). 119 */ 120static INLINE GLboolean 121validate(GLcontext *ctx, GLint attribArray, 122 const struct gl_client_array *array, GLint element) 123{ 124 if (ctx->VertexProgram.Enabled 125 && attribArray >= 0 126 && ctx->Array.VertexAttrib[attribArray].Enabled) { 127 if (element >= ctx->Array.VertexAttrib[attribArray]._MaxElement) 128 return GL_FALSE; 129 } 130 else if (array && array->Enabled) { 131 if (element >= array->_MaxElement) 132 return GL_FALSE; 133 } 134 return GL_TRUE; 135} 136 137 138/** 139 * Called from the tnl module to error check the function parameters and 140 * verify that we really can draw something. 141 */ 142GLboolean 143_mesa_validate_DrawArrays(GLcontext *ctx, 144 GLenum mode, GLint start, GLsizei count) 145{ 146 GLint i; 147 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 148 149 if (count < 0) { 150 _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); 151 return GL_FALSE; 152 } 153 154 if (mode > GL_POLYGON) { 155 _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); 156 return GL_FALSE; 157 } 158 159 if (ctx->NewState) 160 _mesa_update_state( ctx ); 161 162 /* Either the conventional vertex position array, or the 0th 163 * generic vertex attribute array is required to be enabled. 164 */ 165 if (ctx->VertexProgram.Enabled 166 && ctx->Array.VertexAttrib[VERT_ATTRIB_POS].Enabled) { 167 if (start + count >= ctx->Array.VertexAttrib[VERT_ATTRIB_POS]._MaxElement) 168 return GL_FALSE; 169 } 170 else if (ctx->Array.Vertex.Enabled) { 171 if (start + count >= ctx->Array.Vertex._MaxElement) 172 return GL_FALSE; 173 } 174 else { 175 /* no vertex position array! */ 176 return GL_FALSE; 177 } 178 179 /* 180 * OK, now check all the other enabled arrays to be sure the elements 181 * are in bounds. 182 */ 183 if (!validate(ctx, VERT_ATTRIB_WEIGHT, NULL, start + count)) 184 return GL_FALSE; 185 186 if (!validate(ctx, VERT_ATTRIB_NORMAL, &ctx->Array.Normal, start + count)) 187 return GL_FALSE; 188 189 if (!validate(ctx, VERT_ATTRIB_COLOR0, &ctx->Array.Color, start + count)) 190 return GL_FALSE; 191 192 if (!validate(ctx, VERT_ATTRIB_COLOR1, &ctx->Array.SecondaryColor, start + count)) 193 return GL_FALSE; 194 195 if (!validate(ctx, VERT_ATTRIB_FOG, &ctx->Array.FogCoord, start + count)) 196 return GL_FALSE; 197 198 if (!validate(ctx, VERT_ATTRIB_SIX, NULL, start + count)) 199 return GL_FALSE; 200 201 if (!validate(ctx, VERT_ATTRIB_SEVEN, &ctx->Array.FogCoord, start + count)) 202 return GL_FALSE; 203 204 for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) 205 if (!validate(ctx, VERT_ATTRIB_TEX0 + i, &ctx->Array.TexCoord[i], start + count)) 206 return GL_FALSE; 207 208 if (!validate(ctx, -1, &ctx->Array.Index, start + count)) 209 return GL_FALSE; 210 211 if (!validate(ctx, -1, &ctx->Array.EdgeFlag, start + count)) 212 return GL_FALSE; 213 214 return GL_TRUE; 215} 216