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