blob: 30c6c74173e631e3fd05ce5db0d66fdd6465a2b8 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lang2b5420c2014-11-19 14:20:15 -050013#include "libANGLE/validationES.h"
Jamie Madill73a84962016-02-12 09:27:23 -050014#include "libANGLE/validationES3.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050015#include "libANGLE/Context.h"
16#include "libANGLE/Texture.h"
17#include "libANGLE/Framebuffer.h"
18#include "libANGLE/Renderbuffer.h"
19#include "libANGLE/formatutils.h"
20#include "libANGLE/FramebufferAttachment.h"
Geoff Langd8605522016-04-13 10:19:12 -040021#include "libANGLE/Uniform.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040022
23#include "common/mathutil.h"
24#include "common/utilities.h"
25
26namespace gl
27{
28
Jamie Madillc29968b2016-01-20 11:17:23 -050029namespace
30{
31
32bool IsPartialBlit(gl::Context *context,
33 const FramebufferAttachment *readBuffer,
34 const FramebufferAttachment *writeBuffer,
35 GLint srcX0,
36 GLint srcY0,
37 GLint srcX1,
38 GLint srcY1,
39 GLint dstX0,
40 GLint dstY0,
41 GLint dstX1,
42 GLint dstY1)
43{
44 const Extents &writeSize = writeBuffer->getSize();
45 const Extents &readSize = readBuffer->getSize();
46
47 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
48 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
49 {
50 return true;
51 }
52
Jamie Madilldfde6ab2016-06-09 07:07:18 -070053 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050054 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070055 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050056 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
57 scissor.height < writeSize.height;
58 }
59
60 return false;
61}
62
63} // anonymous namespace
64
Geoff Langb1196682014-07-23 13:47:29 -040065bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -040066 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
67 GLint border, GLenum format, GLenum type, const GLvoid *pixels)
68{
Jamie Madill6f38f822014-06-06 17:12:20 -040069 if (!ValidTexture2DDestinationTarget(context, target))
70 {
Jamie Madill437fa652016-05-03 15:13:24 -040071 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -040072 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -040073 }
74
Austin Kinross08528e12015-10-07 16:24:40 -070075 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040076 {
Jamie Madill437fa652016-05-03 15:13:24 -040077 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -040078 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040079 }
80
Geoff Lange8ebe7f2013-08-05 15:03:13 -040081 if (level < 0 || xoffset < 0 ||
82 std::numeric_limits<GLsizei>::max() - xoffset < width ||
83 std::numeric_limits<GLsizei>::max() - yoffset < height)
84 {
Jamie Madill437fa652016-05-03 15:13:24 -040085 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -040086 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040087 }
88
Geoff Lang005df412013-10-16 14:12:50 -040089 if (!isSubImage && !isCompressed && internalformat != format)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040090 {
Jamie Madill437fa652016-05-03 15:13:24 -040091 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -040092 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040093 }
94
Geoff Langaae65a42014-05-26 12:43:44 -040095 const gl::Caps &caps = context->getCaps();
96
Geoff Langa9be0dc2014-12-17 12:34:40 -050097 if (target == GL_TEXTURE_2D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040098 {
Geoff Langa9be0dc2014-12-17 12:34:40 -050099 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
100 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400101 {
Jamie Madill437fa652016-05-03 15:13:24 -0400102 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500103 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400104 }
Geoff Langa9be0dc2014-12-17 12:34:40 -0500105 }
Geoff Lang691e58c2014-12-19 17:03:25 -0500106 else if (IsCubeMapTextureTarget(target))
Geoff Langa9be0dc2014-12-17 12:34:40 -0500107 {
108 if (!isSubImage && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400109 {
Jamie Madill437fa652016-05-03 15:13:24 -0400110 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500111 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400112 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400113
Geoff Langa9be0dc2014-12-17 12:34:40 -0500114 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
115 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
116 {
Jamie Madill437fa652016-05-03 15:13:24 -0400117 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500118 return false;
119 }
120 }
121 else
122 {
Jamie Madill437fa652016-05-03 15:13:24 -0400123 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400124 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400125 }
126
Geoff Lang691e58c2014-12-19 17:03:25 -0500127 gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400128 if (!texture)
129 {
Jamie Madill437fa652016-05-03 15:13:24 -0400130 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400131 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400132 }
133
Geoff Langa9be0dc2014-12-17 12:34:40 -0500134 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400135 {
Geoff Langa9be0dc2014-12-17 12:34:40 -0500136 if (format != GL_NONE)
137 {
Geoff Lang051dbc72015-01-05 15:48:58 -0500138 if (gl::GetSizedInternalFormat(format, type) != texture->getInternalFormat(target, level))
Geoff Langa9be0dc2014-12-17 12:34:40 -0500139 {
Jamie Madill437fa652016-05-03 15:13:24 -0400140 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500141 return false;
142 }
143 }
144
145 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
146 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
147 {
Jamie Madill437fa652016-05-03 15:13:24 -0400148 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500149 return false;
150 }
151 }
152 else
153 {
Geoff Lang69cce582015-09-17 13:20:36 -0400154 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -0500155 {
Jamie Madill437fa652016-05-03 15:13:24 -0400156 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500157 return false;
158 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400159 }
160
161 // Verify zero border
162 if (border != 0)
163 {
Jamie Madill437fa652016-05-03 15:13:24 -0400164 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400165 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400166 }
167
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400168 if (isCompressed)
169 {
tmartino0ccd5ae2015-10-01 14:33:14 -0400170 GLenum actualInternalFormat =
171 isSubImage ? texture->getInternalFormat(target, level) : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400172 switch (actualInternalFormat)
173 {
174 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
175 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400176 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400177 {
Jamie Madill437fa652016-05-03 15:13:24 -0400178 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400179 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400180 }
181 break;
182 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400183 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400184 {
Jamie Madill437fa652016-05-03 15:13:24 -0400185 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400186 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400187 }
188 break;
189 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langb1196682014-07-23 13:47:29 -0400190 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400191 {
Jamie Madill437fa652016-05-03 15:13:24 -0400192 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400193 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400194 }
195 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400196 case GL_ETC1_RGB8_OES:
197 if (!context->getExtensions().compressedETC1RGB8Texture)
198 {
Jamie Madill437fa652016-05-03 15:13:24 -0400199 context->handleError(Error(GL_INVALID_ENUM));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400200 return false;
201 }
202 break;
Minmin Gonge3939b92015-12-01 15:36:51 -0800203 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
204 if (!context->getExtensions().lossyETCDecode)
205 {
Jamie Madill437fa652016-05-03 15:13:24 -0400206 context->handleError(
Minmin Gonge3939b92015-12-01 15:36:51 -0800207 Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported"));
208 return false;
209 }
210 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400211 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400212 context->handleError(Error(
tmartino0ccd5ae2015-10-01 14:33:14 -0400213 GL_INVALID_ENUM, "internalformat is not a supported compressed internal format"));
214 return false;
215 }
216 if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
217 {
Jamie Madill437fa652016-05-03 15:13:24 -0400218 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400219 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400220 }
221 }
222 else
223 {
224 // validate <type> by itself (used as secondary key below)
225 switch (type)
226 {
227 case GL_UNSIGNED_BYTE:
228 case GL_UNSIGNED_SHORT_5_6_5:
229 case GL_UNSIGNED_SHORT_4_4_4_4:
230 case GL_UNSIGNED_SHORT_5_5_5_1:
231 case GL_UNSIGNED_SHORT:
232 case GL_UNSIGNED_INT:
233 case GL_UNSIGNED_INT_24_8_OES:
234 case GL_HALF_FLOAT_OES:
235 case GL_FLOAT:
236 break;
237 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400238 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400239 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400240 }
241
242 // validate <format> + <type> combinations
243 // - invalid <format> -> sets INVALID_ENUM
244 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
245 switch (format)
246 {
247 case GL_ALPHA:
248 case GL_LUMINANCE:
249 case GL_LUMINANCE_ALPHA:
250 switch (type)
251 {
252 case GL_UNSIGNED_BYTE:
253 case GL_FLOAT:
254 case GL_HALF_FLOAT_OES:
255 break;
Geoff Langb1196682014-07-23 13:47:29 -0400256 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400257 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400258 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400259 }
260 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400261 case GL_RED:
Geoff Langcec35902014-04-16 10:52:36 -0400262 case GL_RG:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400263 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400264 {
Jamie Madill437fa652016-05-03 15:13:24 -0400265 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400266 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400267 }
268 switch (type)
269 {
270 case GL_UNSIGNED_BYTE:
271 case GL_FLOAT:
272 case GL_HALF_FLOAT_OES:
273 break;
274 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400275 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400276 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400277 }
278 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400279 case GL_RGB:
280 switch (type)
281 {
282 case GL_UNSIGNED_BYTE:
283 case GL_UNSIGNED_SHORT_5_6_5:
284 case GL_FLOAT:
285 case GL_HALF_FLOAT_OES:
286 break;
287 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400288 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400289 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400290 }
291 break;
292 case GL_RGBA:
293 switch (type)
294 {
295 case GL_UNSIGNED_BYTE:
296 case GL_UNSIGNED_SHORT_4_4_4_4:
297 case GL_UNSIGNED_SHORT_5_5_5_1:
298 case GL_FLOAT:
299 case GL_HALF_FLOAT_OES:
300 break;
301 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400302 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400303 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400304 }
305 break;
306 case GL_BGRA_EXT:
307 switch (type)
308 {
309 case GL_UNSIGNED_BYTE:
310 break;
311 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400312 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400313 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400314 }
315 break;
Geoff Lang05b05022014-06-11 15:31:45 -0400316 case GL_SRGB_EXT:
317 case GL_SRGB_ALPHA_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400318 if (!context->getExtensions().sRGB)
Geoff Lang05b05022014-06-11 15:31:45 -0400319 {
Jamie Madill437fa652016-05-03 15:13:24 -0400320 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400321 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400322 }
323 switch (type)
324 {
325 case GL_UNSIGNED_BYTE:
326 break;
327 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400328 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400329 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400330 }
331 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400332 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
333 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
334 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
335 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
336 break;
337 case GL_DEPTH_COMPONENT:
338 switch (type)
339 {
340 case GL_UNSIGNED_SHORT:
341 case GL_UNSIGNED_INT:
342 break;
343 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400344 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400345 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400346 }
347 break;
348 case GL_DEPTH_STENCIL_OES:
349 switch (type)
350 {
351 case GL_UNSIGNED_INT_24_8_OES:
352 break;
353 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400354 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400355 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400356 }
357 break;
358 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400359 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400360 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400361 }
362
363 switch (format)
364 {
365 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
366 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400367 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400368 {
Jamie Madill437fa652016-05-03 15:13:24 -0400369 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400370 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400371 }
372 else
373 {
Jamie Madill437fa652016-05-03 15:13:24 -0400374 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400375 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400376 }
377 break;
378 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400379 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400380 {
Jamie Madill437fa652016-05-03 15:13:24 -0400381 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400382 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400383 }
384 else
385 {
Jamie Madill437fa652016-05-03 15:13:24 -0400386 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400387 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400388 }
389 break;
390 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400391 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400392 {
Jamie Madill437fa652016-05-03 15:13:24 -0400393 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400394 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400395 }
396 else
397 {
Jamie Madill437fa652016-05-03 15:13:24 -0400398 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400399 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400400 }
401 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400402 case GL_ETC1_RGB8_OES:
403 if (context->getExtensions().compressedETC1RGB8Texture)
404 {
Jamie Madill437fa652016-05-03 15:13:24 -0400405 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400406 return false;
407 }
408 else
409 {
Jamie Madill437fa652016-05-03 15:13:24 -0400410 context->handleError(Error(GL_INVALID_ENUM));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400411 return false;
412 }
413 break;
Minmin Gonge3939b92015-12-01 15:36:51 -0800414 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
415 if (context->getExtensions().lossyETCDecode)
416 {
Jamie Madill437fa652016-05-03 15:13:24 -0400417 context->handleError(
Minmin Gonge3939b92015-12-01 15:36:51 -0800418 Error(GL_INVALID_OPERATION,
419 "ETC1_RGB8_LOSSY_DECODE_ANGLE can't work with this type."));
420 return false;
421 }
422 else
423 {
Jamie Madill437fa652016-05-03 15:13:24 -0400424 context->handleError(
Minmin Gonge3939b92015-12-01 15:36:51 -0800425 Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
426 return false;
427 }
428 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400429 case GL_DEPTH_COMPONENT:
430 case GL_DEPTH_STENCIL_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400431 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400432 {
Jamie Madill437fa652016-05-03 15:13:24 -0400433 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400434 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400435 }
436 if (target != GL_TEXTURE_2D)
437 {
Jamie Madill437fa652016-05-03 15:13:24 -0400438 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400439 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400440 }
441 // OES_depth_texture supports loading depth data and multiple levels,
442 // but ANGLE_depth_texture does not
443 if (pixels != NULL || level != 0)
444 {
Jamie Madill437fa652016-05-03 15:13:24 -0400445 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400446 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400447 }
448 break;
449 default:
450 break;
451 }
452
453 if (type == GL_FLOAT)
454 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400455 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400456 {
Jamie Madill437fa652016-05-03 15:13:24 -0400457 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400458 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400459 }
460 }
461 else if (type == GL_HALF_FLOAT_OES)
462 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400463 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400464 {
Jamie Madill437fa652016-05-03 15:13:24 -0400465 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400466 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400467 }
468 }
469 }
470
471 return true;
472}
473
Jamie Madillc29968b2016-01-20 11:17:23 -0500474bool ValidateES2CopyTexImageParameters(ValidationContext *context,
475 GLenum target,
476 GLint level,
477 GLenum internalformat,
478 bool isSubImage,
479 GLint xoffset,
480 GLint yoffset,
481 GLint x,
482 GLint y,
483 GLsizei width,
484 GLsizei height,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400485 GLint border)
486{
Jamie Madill560a8d82014-05-21 13:06:20 -0400487 GLenum textureInternalFormat = GL_NONE;
Shannon Woods4dfed832014-03-17 20:03:39 -0400488
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500489 if (!ValidTexture2DDestinationTarget(context, target))
490 {
Jamie Madill437fa652016-05-03 15:13:24 -0400491 context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target"));
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500492 return false;
493 }
494
Jamie Madill560a8d82014-05-21 13:06:20 -0400495 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
496 xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400497 {
Jamie Madill560a8d82014-05-21 13:06:20 -0400498 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400499 }
500
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700501 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400502 GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat();
Jamie Madillbc393df2015-01-29 13:46:07 -0500503 const auto &internalFormatInfo = gl::GetInternalFormatInfo(textureInternalFormat);
504 GLenum textureFormat = internalFormatInfo.format;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400505
506 // [OpenGL ES 2.0.24] table 3.9
507 if (isSubImage)
508 {
509 switch (textureFormat)
510 {
511 case GL_ALPHA:
512 if (colorbufferFormat != GL_ALPHA8_EXT &&
513 colorbufferFormat != GL_RGBA4 &&
514 colorbufferFormat != GL_RGB5_A1 &&
515 colorbufferFormat != GL_RGBA8_OES)
516 {
Jamie Madill437fa652016-05-03 15:13:24 -0400517 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400518 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400519 }
520 break;
521 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400522 if (colorbufferFormat != GL_R8_EXT &&
523 colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 &&
525 colorbufferFormat != GL_RGB8_OES &&
526 colorbufferFormat != GL_RGBA4 &&
527 colorbufferFormat != GL_RGB5_A1 &&
528 colorbufferFormat != GL_RGBA8_OES)
529 {
Jamie Madill437fa652016-05-03 15:13:24 -0400530 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400531 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400532 }
533 break;
534 case GL_RED_EXT:
535 if (colorbufferFormat != GL_R8_EXT &&
536 colorbufferFormat != GL_RG8_EXT &&
537 colorbufferFormat != GL_RGB565 &&
538 colorbufferFormat != GL_RGB8_OES &&
539 colorbufferFormat != GL_RGBA4 &&
540 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500541 colorbufferFormat != GL_RGBA8_OES &&
542 colorbufferFormat != GL_R32F &&
543 colorbufferFormat != GL_RG32F &&
544 colorbufferFormat != GL_RGB32F &&
545 colorbufferFormat != GL_RGBA32F)
Geoff Lang632192d2013-10-04 13:40:46 -0400546 {
Jamie Madill437fa652016-05-03 15:13:24 -0400547 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400548 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400549 }
550 break;
551 case GL_RG_EXT:
552 if (colorbufferFormat != GL_RG8_EXT &&
553 colorbufferFormat != GL_RGB565 &&
554 colorbufferFormat != GL_RGB8_OES &&
555 colorbufferFormat != GL_RGBA4 &&
556 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500557 colorbufferFormat != GL_RGBA8_OES &&
558 colorbufferFormat != GL_RG32F &&
559 colorbufferFormat != GL_RGB32F &&
560 colorbufferFormat != GL_RGBA32F)
Geoff Lang632192d2013-10-04 13:40:46 -0400561 {
Jamie Madill437fa652016-05-03 15:13:24 -0400562 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400563 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400564 }
565 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400566 case GL_RGB:
567 if (colorbufferFormat != GL_RGB565 &&
568 colorbufferFormat != GL_RGB8_OES &&
569 colorbufferFormat != GL_RGBA4 &&
570 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500571 colorbufferFormat != GL_RGBA8_OES &&
572 colorbufferFormat != GL_RGB32F &&
573 colorbufferFormat != GL_RGBA32F)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400574 {
Jamie Madill437fa652016-05-03 15:13:24 -0400575 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400576 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400577 }
578 break;
579 case GL_LUMINANCE_ALPHA:
580 case GL_RGBA:
581 if (colorbufferFormat != GL_RGBA4 &&
582 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500583 colorbufferFormat != GL_RGBA8_OES &&
584 colorbufferFormat != GL_RGBA32F)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400585 {
Jamie Madill437fa652016-05-03 15:13:24 -0400586 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400587 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400588 }
589 break;
590 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
591 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
592 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
593 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Lang6ea6f942015-09-11 13:11:22 -0400594 case GL_ETC1_RGB8_OES:
Minmin Gonge3939b92015-12-01 15:36:51 -0800595 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Jamie Madill437fa652016-05-03 15:13:24 -0400596 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400597 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400598 case GL_DEPTH_COMPONENT:
599 case GL_DEPTH_STENCIL_OES:
Jamie Madill437fa652016-05-03 15:13:24 -0400600 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400601 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400602 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400603 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400604 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400605 }
Jamie Madillbc393df2015-01-29 13:46:07 -0500606
607 if (internalFormatInfo.type == GL_FLOAT &&
608 !context->getExtensions().textureFloat)
609 {
Jamie Madill437fa652016-05-03 15:13:24 -0400610 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillbc393df2015-01-29 13:46:07 -0500611 return false;
612 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400613 }
614 else
615 {
616 switch (internalformat)
617 {
618 case GL_ALPHA:
619 if (colorbufferFormat != GL_ALPHA8_EXT &&
620 colorbufferFormat != GL_RGBA4 &&
621 colorbufferFormat != GL_RGB5_A1 &&
622 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500623 colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400625 {
Jamie Madill437fa652016-05-03 15:13:24 -0400626 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400627 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400628 }
629 break;
630 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400631 if (colorbufferFormat != GL_R8_EXT &&
632 colorbufferFormat != GL_RG8_EXT &&
633 colorbufferFormat != GL_RGB565 &&
634 colorbufferFormat != GL_RGB8_OES &&
635 colorbufferFormat != GL_RGBA4 &&
636 colorbufferFormat != GL_RGB5_A1 &&
637 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500638 colorbufferFormat != GL_RGBA8_OES &&
639 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400640 {
Jamie Madill437fa652016-05-03 15:13:24 -0400641 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400642 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400643 }
644 break;
645 case GL_RED_EXT:
646 if (colorbufferFormat != GL_R8_EXT &&
647 colorbufferFormat != GL_RG8_EXT &&
648 colorbufferFormat != GL_RGB565 &&
649 colorbufferFormat != GL_RGB8_OES &&
650 colorbufferFormat != GL_RGBA4 &&
651 colorbufferFormat != GL_RGB5_A1 &&
652 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500653 colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400655 {
Jamie Madill437fa652016-05-03 15:13:24 -0400656 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400657 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400658 }
659 break;
660 case GL_RG_EXT:
661 if (colorbufferFormat != GL_RG8_EXT &&
662 colorbufferFormat != GL_RGB565 &&
663 colorbufferFormat != GL_RGB8_OES &&
664 colorbufferFormat != GL_RGBA4 &&
665 colorbufferFormat != GL_RGB5_A1 &&
666 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500667 colorbufferFormat != GL_RGBA8_OES &&
668 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400669 {
Jamie Madill437fa652016-05-03 15:13:24 -0400670 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400671 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400672 }
673 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400674 case GL_RGB:
675 if (colorbufferFormat != GL_RGB565 &&
676 colorbufferFormat != GL_RGB8_OES &&
677 colorbufferFormat != GL_RGBA4 &&
678 colorbufferFormat != GL_RGB5_A1 &&
679 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500680 colorbufferFormat != GL_RGBA8_OES &&
681 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400682 {
Jamie Madill437fa652016-05-03 15:13:24 -0400683 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400684 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400685 }
686 break;
687 case GL_LUMINANCE_ALPHA:
688 case GL_RGBA:
689 if (colorbufferFormat != GL_RGBA4 &&
690 colorbufferFormat != GL_RGB5_A1 &&
691 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500692 colorbufferFormat != GL_RGBA8_OES &&
693 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400694 {
Jamie Madill437fa652016-05-03 15:13:24 -0400695 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400696 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400697 }
698 break;
699 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
700 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400701 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400702 {
Jamie Madill437fa652016-05-03 15:13:24 -0400703 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400704 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400705 }
706 else
707 {
Jamie Madill437fa652016-05-03 15:13:24 -0400708 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400709 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400710 }
711 break;
712 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400713 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400714 {
Jamie Madill437fa652016-05-03 15:13:24 -0400715 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400716 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400717 }
718 else
719 {
Jamie Madill437fa652016-05-03 15:13:24 -0400720 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400721 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400722 }
723 break;
724 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400725 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400726 {
Jamie Madill437fa652016-05-03 15:13:24 -0400727 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400728 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400729 }
730 else
731 {
Jamie Madill437fa652016-05-03 15:13:24 -0400732 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400733 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400734 }
735 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400736 case GL_ETC1_RGB8_OES:
737 if (context->getExtensions().compressedETC1RGB8Texture)
738 {
Jamie Madill437fa652016-05-03 15:13:24 -0400739 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400740 return false;
741 }
742 else
743 {
Jamie Madill437fa652016-05-03 15:13:24 -0400744 context->handleError(Error(GL_INVALID_ENUM));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400745 return false;
746 }
747 break;
Minmin Gonge3939b92015-12-01 15:36:51 -0800748 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
749 if (context->getExtensions().lossyETCDecode)
750 {
Jamie Madill437fa652016-05-03 15:13:24 -0400751 context->handleError(Error(GL_INVALID_OPERATION,
Minmin Gonge3939b92015-12-01 15:36:51 -0800752 "ETC1_RGB8_LOSSY_DECODE_ANGLE can't be copied to."));
753 return false;
754 }
755 else
756 {
Jamie Madill437fa652016-05-03 15:13:24 -0400757 context->handleError(
Minmin Gonge3939b92015-12-01 15:36:51 -0800758 Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
759 return false;
760 }
761 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400762 case GL_DEPTH_COMPONENT:
763 case GL_DEPTH_COMPONENT16:
764 case GL_DEPTH_COMPONENT32_OES:
765 case GL_DEPTH_STENCIL_OES:
766 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400767 if (context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400768 {
Jamie Madill437fa652016-05-03 15:13:24 -0400769 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400770 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400771 }
772 else
773 {
Jamie Madill437fa652016-05-03 15:13:24 -0400774 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400775 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400776 }
777 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400778 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400779 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400780 }
781 }
782
Geoff Lang784a8fd2013-09-24 12:33:16 -0400783 // If width or height is zero, it is a no-op. Return false without setting an error.
784 return (width > 0 && height > 0);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400785}
786
Geoff Langb1196682014-07-23 13:47:29 -0400787bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400788 GLsizei width, GLsizei height)
789{
790 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
791 {
Jamie Madill437fa652016-05-03 15:13:24 -0400792 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400793 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400794 }
795
796 if (width < 1 || height < 1 || levels < 1)
797 {
Jamie Madill437fa652016-05-03 15:13:24 -0400798 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400799 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400800 }
801
802 if (target == GL_TEXTURE_CUBE_MAP && width != height)
803 {
Jamie Madill437fa652016-05-03 15:13:24 -0400804 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400805 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400806 }
807
808 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
809 {
Jamie Madill437fa652016-05-03 15:13:24 -0400810 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400811 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400812 }
813
Geoff Lang5d601382014-07-22 15:14:06 -0400814 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
815 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400816 {
Jamie Madill437fa652016-05-03 15:13:24 -0400817 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400818 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400819 }
820
Geoff Langaae65a42014-05-26 12:43:44 -0400821 const gl::Caps &caps = context->getCaps();
822
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400823 switch (target)
824 {
825 case GL_TEXTURE_2D:
Geoff Langaae65a42014-05-26 12:43:44 -0400826 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
827 static_cast<GLuint>(height) > caps.max2DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400828 {
Jamie Madill437fa652016-05-03 15:13:24 -0400829 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400830 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400831 }
832 break;
833 case GL_TEXTURE_CUBE_MAP:
Geoff Langaae65a42014-05-26 12:43:44 -0400834 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
835 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400836 {
Jamie Madill437fa652016-05-03 15:13:24 -0400837 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400838 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400839 }
840 break;
841 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400842 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400843 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400844 }
845
Geoff Langc0b9ef42014-07-02 10:02:37 -0400846 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400847 {
848 if (!gl::isPow2(width) || !gl::isPow2(height))
849 {
Jamie Madill437fa652016-05-03 15:13:24 -0400850 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400851 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400852 }
853 }
854
855 switch (internalformat)
856 {
857 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
858 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400859 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400860 {
Jamie Madill437fa652016-05-03 15:13:24 -0400861 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400862 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400863 }
864 break;
865 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400866 if (!context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400867 {
Jamie Madill437fa652016-05-03 15:13:24 -0400868 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400869 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400870 }
871 break;
872 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400873 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400874 {
Jamie Madill437fa652016-05-03 15:13:24 -0400875 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400876 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400877 }
878 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400879 case GL_ETC1_RGB8_OES:
880 if (!context->getExtensions().compressedETC1RGB8Texture)
881 {
Jamie Madill437fa652016-05-03 15:13:24 -0400882 context->handleError(Error(GL_INVALID_ENUM));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400883 return false;
884 }
885 break;
Minmin Gonge3939b92015-12-01 15:36:51 -0800886 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
887 if (!context->getExtensions().lossyETCDecode)
888 {
Jamie Madill437fa652016-05-03 15:13:24 -0400889 context->handleError(
Minmin Gonge3939b92015-12-01 15:36:51 -0800890 Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
891 return false;
892 }
893 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400894 case GL_RGBA32F_EXT:
895 case GL_RGB32F_EXT:
896 case GL_ALPHA32F_EXT:
897 case GL_LUMINANCE32F_EXT:
898 case GL_LUMINANCE_ALPHA32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400899 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400900 {
Jamie Madill437fa652016-05-03 15:13:24 -0400901 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400902 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400903 }
904 break;
905 case GL_RGBA16F_EXT:
906 case GL_RGB16F_EXT:
907 case GL_ALPHA16F_EXT:
908 case GL_LUMINANCE16F_EXT:
909 case GL_LUMINANCE_ALPHA16F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400910 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400911 {
Jamie Madill437fa652016-05-03 15:13:24 -0400912 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400913 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400914 }
915 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400916 case GL_R8_EXT:
917 case GL_RG8_EXT:
918 case GL_R16F_EXT:
919 case GL_RG16F_EXT:
920 case GL_R32F_EXT:
921 case GL_RG32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400922 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400923 {
Jamie Madill437fa652016-05-03 15:13:24 -0400924 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400925 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400926 }
927 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400928 case GL_DEPTH_COMPONENT16:
929 case GL_DEPTH_COMPONENT32_OES:
930 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400931 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400932 {
Jamie Madill437fa652016-05-03 15:13:24 -0400933 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400934 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400935 }
936 if (target != GL_TEXTURE_2D)
937 {
Jamie Madill437fa652016-05-03 15:13:24 -0400938 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400939 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400940 }
941 // ANGLE_depth_texture only supports 1-level textures
942 if (levels != 1)
943 {
Jamie Madill437fa652016-05-03 15:13:24 -0400944 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400945 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400946 }
947 break;
948 default:
949 break;
950 }
951
Geoff Lang691e58c2014-12-19 17:03:25 -0500952 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400953 if (!texture || texture->id() == 0)
954 {
Jamie Madill437fa652016-05-03 15:13:24 -0400955 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400956 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400957 }
958
Geoff Lang69cce582015-09-17 13:20:36 -0400959 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400960 {
Jamie Madill437fa652016-05-03 15:13:24 -0400961 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400962 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400963 }
964
965 return true;
966}
967
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400968// check for combinations of format and type that are valid for ReadPixels
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700969bool ValidES2ReadFormatType(ValidationContext *context, GLenum format, GLenum type)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400970{
971 switch (format)
972 {
973 case GL_RGBA:
974 switch (type)
975 {
976 case GL_UNSIGNED_BYTE:
977 break;
978 default:
979 return false;
980 }
981 break;
982 case GL_BGRA_EXT:
983 switch (type)
984 {
985 case GL_UNSIGNED_BYTE:
986 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
987 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
988 break;
989 default:
990 return false;
991 }
992 break;
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400993 case GL_RG_EXT:
994 case GL_RED_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400995 if (!context->getExtensions().textureRG)
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400996 {
997 return false;
998 }
999 switch (type)
1000 {
1001 case GL_UNSIGNED_BYTE:
1002 break;
1003 default:
1004 return false;
1005 }
1006 break;
1007
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001008 default:
1009 return false;
1010 }
1011 return true;
1012}
1013
Austin Kinross08332632015-05-05 13:35:47 -07001014bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments,
1015 const GLenum *attachments)
1016{
Jamie Madillc29968b2016-01-20 11:17:23 -05001017 if (!context->getExtensions().discardFramebuffer)
1018 {
Jamie Madill437fa652016-05-03 15:13:24 -04001019 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Jamie Madillc29968b2016-01-20 11:17:23 -05001020 return false;
1021 }
1022
Austin Kinross08332632015-05-05 13:35:47 -07001023 bool defaultFramebuffer = false;
1024
1025 switch (target)
1026 {
1027 case GL_FRAMEBUFFER:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001028 defaultFramebuffer =
1029 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1030 break;
Austin Kinross08332632015-05-05 13:35:47 -07001031 default:
Jamie Madill437fa652016-05-03 15:13:24 -04001032 context->handleError(Error(GL_INVALID_ENUM, "Invalid framebuffer target"));
Austin Kinross08332632015-05-05 13:35:47 -07001033 return false;
1034 }
1035
1036 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer);
1037}
1038
Austin Kinrossbc781f32015-10-26 09:27:38 -07001039bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1040{
1041 if (!context->getExtensions().vertexArrayObject)
1042 {
Jamie Madill437fa652016-05-03 15:13:24 -04001043 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001044 return false;
1045 }
1046
1047 return ValidateBindVertexArrayBase(context, array);
1048}
1049
1050bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n)
1051{
1052 if (!context->getExtensions().vertexArrayObject)
1053 {
Jamie Madill437fa652016-05-03 15:13:24 -04001054 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001055 return false;
1056 }
1057
Olli Etuaho41997e72016-03-10 13:38:39 +02001058 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001059}
1060
1061bool ValidateGenVertexArraysOES(Context *context, GLsizei n)
1062{
1063 if (!context->getExtensions().vertexArrayObject)
1064 {
Jamie Madill437fa652016-05-03 15:13:24 -04001065 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001066 return false;
1067 }
1068
Olli Etuaho41997e72016-03-10 13:38:39 +02001069 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001070}
1071
1072bool ValidateIsVertexArrayOES(Context *context)
1073{
1074 if (!context->getExtensions().vertexArrayObject)
1075 {
Jamie Madill437fa652016-05-03 15:13:24 -04001076 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001077 return false;
1078 }
1079
1080 return true;
1081}
Geoff Langc5629752015-12-07 16:29:04 -05001082
1083bool ValidateProgramBinaryOES(Context *context,
1084 GLuint program,
1085 GLenum binaryFormat,
1086 const void *binary,
1087 GLint length)
1088{
1089 if (!context->getExtensions().getProgramBinary)
1090 {
Jamie Madill437fa652016-05-03 15:13:24 -04001091 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Langc5629752015-12-07 16:29:04 -05001092 return false;
1093 }
1094
1095 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1096}
1097
1098bool ValidateGetProgramBinaryOES(Context *context,
1099 GLuint program,
1100 GLsizei bufSize,
1101 GLsizei *length,
1102 GLenum *binaryFormat,
1103 void *binary)
1104{
1105 if (!context->getExtensions().getProgramBinary)
1106 {
Jamie Madill437fa652016-05-03 15:13:24 -04001107 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Langc5629752015-12-07 16:29:04 -05001108 return false;
1109 }
1110
1111 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1112}
Geoff Lange102fee2015-12-10 11:23:30 -05001113
Geoff Lang70d0f492015-12-10 17:45:46 -05001114static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1115{
1116 switch (source)
1117 {
1118 case GL_DEBUG_SOURCE_API:
1119 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1120 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1121 case GL_DEBUG_SOURCE_OTHER:
1122 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1123 return !mustBeThirdPartyOrApplication;
1124
1125 case GL_DEBUG_SOURCE_THIRD_PARTY:
1126 case GL_DEBUG_SOURCE_APPLICATION:
1127 return true;
1128
1129 default:
1130 return false;
1131 }
1132}
1133
1134static bool ValidDebugType(GLenum type)
1135{
1136 switch (type)
1137 {
1138 case GL_DEBUG_TYPE_ERROR:
1139 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1140 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1141 case GL_DEBUG_TYPE_PERFORMANCE:
1142 case GL_DEBUG_TYPE_PORTABILITY:
1143 case GL_DEBUG_TYPE_OTHER:
1144 case GL_DEBUG_TYPE_MARKER:
1145 case GL_DEBUG_TYPE_PUSH_GROUP:
1146 case GL_DEBUG_TYPE_POP_GROUP:
1147 return true;
1148
1149 default:
1150 return false;
1151 }
1152}
1153
1154static bool ValidDebugSeverity(GLenum severity)
1155{
1156 switch (severity)
1157 {
1158 case GL_DEBUG_SEVERITY_HIGH:
1159 case GL_DEBUG_SEVERITY_MEDIUM:
1160 case GL_DEBUG_SEVERITY_LOW:
1161 case GL_DEBUG_SEVERITY_NOTIFICATION:
1162 return true;
1163
1164 default:
1165 return false;
1166 }
1167}
1168
Geoff Lange102fee2015-12-10 11:23:30 -05001169bool ValidateDebugMessageControlKHR(Context *context,
1170 GLenum source,
1171 GLenum type,
1172 GLenum severity,
1173 GLsizei count,
1174 const GLuint *ids,
1175 GLboolean enabled)
1176{
1177 if (!context->getExtensions().debug)
1178 {
Jamie Madill437fa652016-05-03 15:13:24 -04001179 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001180 return false;
1181 }
1182
Geoff Lang70d0f492015-12-10 17:45:46 -05001183 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1184 {
Jamie Madill437fa652016-05-03 15:13:24 -04001185 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug source."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001186 return false;
1187 }
1188
1189 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1190 {
Jamie Madill437fa652016-05-03 15:13:24 -04001191 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug type."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001192 return false;
1193 }
1194
1195 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1196 {
Jamie Madill437fa652016-05-03 15:13:24 -04001197 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug severity."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001198 return false;
1199 }
1200
1201 if (count > 0)
1202 {
1203 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1204 {
Jamie Madill437fa652016-05-03 15:13:24 -04001205 context->handleError(Error(
Geoff Lang70d0f492015-12-10 17:45:46 -05001206 GL_INVALID_OPERATION,
1207 "If count is greater than zero, source and severity cannot be GL_DONT_CARE."));
1208 return false;
1209 }
1210
1211 if (severity != GL_DONT_CARE)
1212 {
Jamie Madill437fa652016-05-03 15:13:24 -04001213 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001214 Error(GL_INVALID_OPERATION,
1215 "If count is greater than zero, severity must be GL_DONT_CARE."));
1216 return false;
1217 }
1218 }
1219
Geoff Lange102fee2015-12-10 11:23:30 -05001220 return true;
1221}
1222
1223bool ValidateDebugMessageInsertKHR(Context *context,
1224 GLenum source,
1225 GLenum type,
1226 GLuint id,
1227 GLenum severity,
1228 GLsizei length,
1229 const GLchar *buf)
1230{
1231 if (!context->getExtensions().debug)
1232 {
Jamie Madill437fa652016-05-03 15:13:24 -04001233 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001234 return false;
1235 }
1236
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001237 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05001238 {
1239 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
1240 // not generate an error.
1241 return false;
1242 }
1243
1244 if (!ValidDebugSeverity(severity))
1245 {
Jamie Madill437fa652016-05-03 15:13:24 -04001246 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug severity."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001247 return false;
1248 }
1249
1250 if (!ValidDebugType(type))
1251 {
Jamie Madill437fa652016-05-03 15:13:24 -04001252 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug type."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001253 return false;
1254 }
1255
1256 if (!ValidDebugSource(source, true))
1257 {
Jamie Madill437fa652016-05-03 15:13:24 -04001258 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug source."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001259 return false;
1260 }
1261
1262 size_t messageLength = (length < 0) ? strlen(buf) : length;
1263 if (messageLength > context->getExtensions().maxDebugMessageLength)
1264 {
Jamie Madill437fa652016-05-03 15:13:24 -04001265 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001266 Error(GL_INVALID_VALUE, "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH."));
1267 return false;
1268 }
1269
Geoff Lange102fee2015-12-10 11:23:30 -05001270 return true;
1271}
1272
1273bool ValidateDebugMessageCallbackKHR(Context *context,
1274 GLDEBUGPROCKHR callback,
1275 const void *userParam)
1276{
1277 if (!context->getExtensions().debug)
1278 {
Jamie Madill437fa652016-05-03 15:13:24 -04001279 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001280 return false;
1281 }
1282
Geoff Lange102fee2015-12-10 11:23:30 -05001283 return true;
1284}
1285
1286bool ValidateGetDebugMessageLogKHR(Context *context,
1287 GLuint count,
1288 GLsizei bufSize,
1289 GLenum *sources,
1290 GLenum *types,
1291 GLuint *ids,
1292 GLenum *severities,
1293 GLsizei *lengths,
1294 GLchar *messageLog)
1295{
1296 if (!context->getExtensions().debug)
1297 {
Jamie Madill437fa652016-05-03 15:13:24 -04001298 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001299 return false;
1300 }
1301
Geoff Lang70d0f492015-12-10 17:45:46 -05001302 if (bufSize < 0 && messageLog != nullptr)
1303 {
Jamie Madill437fa652016-05-03 15:13:24 -04001304 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001305 Error(GL_INVALID_VALUE, "bufSize must be positive if messageLog is not null."));
1306 return false;
1307 }
1308
Geoff Lange102fee2015-12-10 11:23:30 -05001309 return true;
1310}
1311
1312bool ValidatePushDebugGroupKHR(Context *context,
1313 GLenum source,
1314 GLuint id,
1315 GLsizei length,
1316 const GLchar *message)
1317{
1318 if (!context->getExtensions().debug)
1319 {
Jamie Madill437fa652016-05-03 15:13:24 -04001320 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001321 return false;
1322 }
1323
Geoff Lang70d0f492015-12-10 17:45:46 -05001324 if (!ValidDebugSource(source, true))
1325 {
Jamie Madill437fa652016-05-03 15:13:24 -04001326 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug source."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001327 return false;
1328 }
1329
1330 size_t messageLength = (length < 0) ? strlen(message) : length;
1331 if (messageLength > context->getExtensions().maxDebugMessageLength)
1332 {
Jamie Madill437fa652016-05-03 15:13:24 -04001333 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001334 Error(GL_INVALID_VALUE, "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH."));
1335 return false;
1336 }
1337
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001338 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05001339 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
1340 {
Jamie Madill437fa652016-05-03 15:13:24 -04001341 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001342 Error(GL_STACK_OVERFLOW,
1343 "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups."));
1344 return false;
1345 }
1346
Geoff Lange102fee2015-12-10 11:23:30 -05001347 return true;
1348}
1349
1350bool ValidatePopDebugGroupKHR(Context *context)
1351{
1352 if (!context->getExtensions().debug)
1353 {
Jamie Madill437fa652016-05-03 15:13:24 -04001354 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001355 return false;
1356 }
1357
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001358 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05001359 if (currentStackSize <= 1)
1360 {
Jamie Madill437fa652016-05-03 15:13:24 -04001361 context->handleError(Error(GL_STACK_UNDERFLOW, "Cannot pop the default debug group."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001362 return false;
1363 }
1364
1365 return true;
1366}
1367
1368static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
1369{
1370 switch (identifier)
1371 {
1372 case GL_BUFFER:
1373 if (context->getBuffer(name) == nullptr)
1374 {
Jamie Madill437fa652016-05-03 15:13:24 -04001375 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid buffer."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001376 return false;
1377 }
1378 return true;
1379
1380 case GL_SHADER:
1381 if (context->getShader(name) == nullptr)
1382 {
Jamie Madill437fa652016-05-03 15:13:24 -04001383 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid shader."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001384 return false;
1385 }
1386 return true;
1387
1388 case GL_PROGRAM:
1389 if (context->getProgram(name) == nullptr)
1390 {
Jamie Madill437fa652016-05-03 15:13:24 -04001391 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid program."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001392 return false;
1393 }
1394 return true;
1395
1396 case GL_VERTEX_ARRAY:
1397 if (context->getVertexArray(name) == nullptr)
1398 {
Jamie Madill437fa652016-05-03 15:13:24 -04001399 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid vertex array."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001400 return false;
1401 }
1402 return true;
1403
1404 case GL_QUERY:
1405 if (context->getQuery(name) == nullptr)
1406 {
Jamie Madill437fa652016-05-03 15:13:24 -04001407 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid query."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001408 return false;
1409 }
1410 return true;
1411
1412 case GL_TRANSFORM_FEEDBACK:
1413 if (context->getTransformFeedback(name) == nullptr)
1414 {
Jamie Madill437fa652016-05-03 15:13:24 -04001415 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001416 Error(GL_INVALID_VALUE, "name is not a valid transform feedback."));
1417 return false;
1418 }
1419 return true;
1420
1421 case GL_SAMPLER:
1422 if (context->getSampler(name) == nullptr)
1423 {
Jamie Madill437fa652016-05-03 15:13:24 -04001424 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid sampler."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001425 return false;
1426 }
1427 return true;
1428
1429 case GL_TEXTURE:
1430 if (context->getTexture(name) == nullptr)
1431 {
Jamie Madill437fa652016-05-03 15:13:24 -04001432 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid texture."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001433 return false;
1434 }
1435 return true;
1436
1437 case GL_RENDERBUFFER:
1438 if (context->getRenderbuffer(name) == nullptr)
1439 {
Jamie Madill437fa652016-05-03 15:13:24 -04001440 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid renderbuffer."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001441 return false;
1442 }
1443 return true;
1444
1445 case GL_FRAMEBUFFER:
1446 if (context->getFramebuffer(name) == nullptr)
1447 {
Jamie Madill437fa652016-05-03 15:13:24 -04001448 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid framebuffer."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001449 return false;
1450 }
1451 return true;
1452
1453 default:
Jamie Madill437fa652016-05-03 15:13:24 -04001454 context->handleError(Error(GL_INVALID_ENUM, "Invalid identifier."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001455 return false;
1456 }
1457
Geoff Lange102fee2015-12-10 11:23:30 -05001458 return true;
1459}
1460
1461bool ValidateObjectLabelKHR(Context *context,
1462 GLenum identifier,
1463 GLuint name,
1464 GLsizei length,
1465 const GLchar *label)
1466{
1467 if (!context->getExtensions().debug)
1468 {
Jamie Madill437fa652016-05-03 15:13:24 -04001469 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001470 return false;
1471 }
1472
Geoff Lang70d0f492015-12-10 17:45:46 -05001473 if (!ValidateObjectIdentifierAndName(context, identifier, name))
1474 {
1475 return false;
1476 }
1477
1478 size_t labelLength = (length < 0) ? strlen(label) : length;
1479 if (labelLength > context->getExtensions().maxLabelLength)
1480 {
Jamie Madill437fa652016-05-03 15:13:24 -04001481 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001482 Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH."));
1483 return false;
1484 }
1485
Geoff Lange102fee2015-12-10 11:23:30 -05001486 return true;
1487}
1488
1489bool ValidateGetObjectLabelKHR(Context *context,
1490 GLenum identifier,
1491 GLuint name,
1492 GLsizei bufSize,
1493 GLsizei *length,
1494 GLchar *label)
1495{
1496 if (!context->getExtensions().debug)
1497 {
Jamie Madill437fa652016-05-03 15:13:24 -04001498 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001499 return false;
1500 }
1501
Geoff Lang70d0f492015-12-10 17:45:46 -05001502 if (bufSize < 0)
1503 {
Jamie Madill437fa652016-05-03 15:13:24 -04001504 context->handleError(Error(GL_INVALID_VALUE, "bufSize cannot be negative."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001505 return false;
1506 }
1507
1508 if (!ValidateObjectIdentifierAndName(context, identifier, name))
1509 {
1510 return false;
1511 }
1512
1513 // Can no-op if bufSize is zero.
1514 return bufSize > 0;
1515}
1516
1517static bool ValidateObjectPtrName(Context *context, const void *ptr)
1518{
1519 if (context->getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
1520 {
Jamie Madill437fa652016-05-03 15:13:24 -04001521 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid sync."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001522 return false;
1523 }
1524
Geoff Lange102fee2015-12-10 11:23:30 -05001525 return true;
1526}
1527
1528bool ValidateObjectPtrLabelKHR(Context *context,
1529 const void *ptr,
1530 GLsizei length,
1531 const GLchar *label)
1532{
1533 if (!context->getExtensions().debug)
1534 {
Jamie Madill437fa652016-05-03 15:13:24 -04001535 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001536 return false;
1537 }
1538
Geoff Lang70d0f492015-12-10 17:45:46 -05001539 if (!ValidateObjectPtrName(context, ptr))
1540 {
1541 return false;
1542 }
1543
1544 size_t labelLength = (length < 0) ? strlen(label) : length;
1545 if (labelLength > context->getExtensions().maxLabelLength)
1546 {
Jamie Madill437fa652016-05-03 15:13:24 -04001547 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001548 Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH."));
1549 return false;
1550 }
1551
Geoff Lange102fee2015-12-10 11:23:30 -05001552 return true;
1553}
1554
1555bool ValidateGetObjectPtrLabelKHR(Context *context,
1556 const void *ptr,
1557 GLsizei bufSize,
1558 GLsizei *length,
1559 GLchar *label)
1560{
1561 if (!context->getExtensions().debug)
1562 {
Jamie Madill437fa652016-05-03 15:13:24 -04001563 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001564 return false;
1565 }
1566
Geoff Lang70d0f492015-12-10 17:45:46 -05001567 if (bufSize < 0)
1568 {
Jamie Madill437fa652016-05-03 15:13:24 -04001569 context->handleError(Error(GL_INVALID_VALUE, "bufSize cannot be negative."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001570 return false;
1571 }
1572
1573 if (!ValidateObjectPtrName(context, ptr))
1574 {
1575 return false;
1576 }
1577
1578 // Can no-op if bufSize is zero.
1579 return bufSize > 0;
Geoff Lange102fee2015-12-10 11:23:30 -05001580}
1581
1582bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
1583{
1584 if (!context->getExtensions().debug)
1585 {
Jamie Madill437fa652016-05-03 15:13:24 -04001586 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001587 return false;
1588 }
1589
Geoff Lang70d0f492015-12-10 17:45:46 -05001590 // TODO: represent this in Context::getQueryParameterInfo.
1591 switch (pname)
1592 {
1593 case GL_DEBUG_CALLBACK_FUNCTION:
1594 case GL_DEBUG_CALLBACK_USER_PARAM:
1595 break;
1596
1597 default:
Jamie Madill437fa652016-05-03 15:13:24 -04001598 context->handleError(Error(GL_INVALID_ENUM, "Invalid pname."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001599 return false;
1600 }
1601
Geoff Lange102fee2015-12-10 11:23:30 -05001602 return true;
1603}
Jamie Madillc29968b2016-01-20 11:17:23 -05001604
1605bool ValidateBlitFramebufferANGLE(Context *context,
1606 GLint srcX0,
1607 GLint srcY0,
1608 GLint srcX1,
1609 GLint srcY1,
1610 GLint dstX0,
1611 GLint dstY0,
1612 GLint dstX1,
1613 GLint dstY1,
1614 GLbitfield mask,
1615 GLenum filter)
1616{
1617 if (!context->getExtensions().framebufferBlit)
1618 {
Jamie Madill437fa652016-05-03 15:13:24 -04001619 context->handleError(Error(GL_INVALID_OPERATION, "Blit extension not available."));
Jamie Madillc29968b2016-01-20 11:17:23 -05001620 return false;
1621 }
1622
1623 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
1624 {
1625 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madill437fa652016-05-03 15:13:24 -04001626 context->handleError(Error(
Jamie Madillc29968b2016-01-20 11:17:23 -05001627 GL_INVALID_OPERATION,
1628 "Scaling and flipping in BlitFramebufferANGLE not supported by this implementation."));
1629 return false;
1630 }
1631
1632 if (filter == GL_LINEAR)
1633 {
Jamie Madill437fa652016-05-03 15:13:24 -04001634 context->handleError(Error(GL_INVALID_ENUM, "Linear blit not supported in this extension"));
Jamie Madillc29968b2016-01-20 11:17:23 -05001635 return false;
1636 }
1637
Jamie Madill51f40ec2016-06-15 14:06:00 -04001638 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
1639 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05001640
1641 if (mask & GL_COLOR_BUFFER_BIT)
1642 {
1643 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
1644 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
1645
1646 if (readColorAttachment && drawColorAttachment)
1647 {
1648 if (!(readColorAttachment->type() == GL_TEXTURE &&
1649 readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
1650 readColorAttachment->type() != GL_RENDERBUFFER &&
1651 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
1652 {
Jamie Madill437fa652016-05-03 15:13:24 -04001653 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001654 return false;
1655 }
1656
Geoff Langa15472a2015-08-11 11:48:03 -04001657 for (size_t drawbufferIdx = 0;
1658 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05001659 {
Geoff Langa15472a2015-08-11 11:48:03 -04001660 const FramebufferAttachment *attachment =
1661 drawFramebuffer->getDrawBuffer(drawbufferIdx);
1662 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05001663 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001664 if (!(attachment->type() == GL_TEXTURE &&
1665 attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
1666 attachment->type() != GL_RENDERBUFFER &&
1667 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
1668 {
Jamie Madill437fa652016-05-03 15:13:24 -04001669 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001670 return false;
1671 }
1672
1673 // Return an error if the destination formats do not match
1674 if (attachment->getInternalFormat() != readColorAttachment->getInternalFormat())
1675 {
Jamie Madill437fa652016-05-03 15:13:24 -04001676 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001677 return false;
1678 }
1679 }
1680 }
1681
Jamie Madill51f40ec2016-06-15 14:06:00 -04001682 if (readFramebuffer->getSamples(context->getContextState()) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05001683 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
1684 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
1685 {
Jamie Madill437fa652016-05-03 15:13:24 -04001686 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001687 return false;
1688 }
1689 }
1690 }
1691
1692 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
1693 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1694 for (size_t i = 0; i < 2; i++)
1695 {
1696 if (mask & masks[i])
1697 {
1698 const FramebufferAttachment *readBuffer =
1699 readFramebuffer->getAttachment(attachments[i]);
1700 const FramebufferAttachment *drawBuffer =
1701 drawFramebuffer->getAttachment(attachments[i]);
1702
1703 if (readBuffer && drawBuffer)
1704 {
1705 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
1706 dstX0, dstY0, dstX1, dstY1))
1707 {
1708 // only whole-buffer copies are permitted
1709 ERR(
1710 "Only whole-buffer depth and stencil blits are supported by this "
1711 "implementation.");
Jamie Madill437fa652016-05-03 15:13:24 -04001712 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001713 return false;
1714 }
1715
1716 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
1717 {
Jamie Madill437fa652016-05-03 15:13:24 -04001718 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001719 return false;
1720 }
1721 }
1722 }
1723 }
1724
1725 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
1726 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001727}
Jamie Madillc29968b2016-01-20 11:17:23 -05001728
1729bool ValidateClear(ValidationContext *context, GLbitfield mask)
1730{
Jamie Madill51f40ec2016-06-15 14:06:00 -04001731 auto fbo = context->getGLState().getDrawFramebuffer();
1732 if (fbo->checkStatus(context->getContextState()) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05001733 {
Jamie Madill437fa652016-05-03 15:13:24 -04001734 context->handleError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001735 return false;
1736 }
1737
1738 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
1739 {
Jamie Madill437fa652016-05-03 15:13:24 -04001740 context->handleError(Error(GL_INVALID_VALUE));
Jamie Madillc29968b2016-01-20 11:17:23 -05001741 return false;
1742 }
1743
1744 return true;
1745}
1746
1747bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
1748{
1749 if (!context->getExtensions().drawBuffers)
1750 {
Jamie Madill437fa652016-05-03 15:13:24 -04001751 context->handleError(Error(GL_INVALID_OPERATION, "Extension not supported."));
Jamie Madillc29968b2016-01-20 11:17:23 -05001752 return false;
1753 }
1754
1755 return ValidateDrawBuffersBase(context, n, bufs);
1756}
1757
Jamie Madill73a84962016-02-12 09:27:23 -05001758bool ValidateTexImage2D(Context *context,
1759 GLenum target,
1760 GLint level,
1761 GLint internalformat,
1762 GLsizei width,
1763 GLsizei height,
1764 GLint border,
1765 GLenum format,
1766 GLenum type,
1767 const GLvoid *pixels)
1768{
1769 if (context->getClientVersion() < 3)
1770 {
1771 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
1772 0, 0, width, height, border, format, type, pixels);
1773 }
1774
1775 ASSERT(context->getClientVersion() >= 3);
1776 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
1777 0, 0, width, height, 1, border, format, type, pixels);
1778}
1779
1780bool ValidateTexSubImage2D(Context *context,
1781 GLenum target,
1782 GLint level,
1783 GLint xoffset,
1784 GLint yoffset,
1785 GLsizei width,
1786 GLsizei height,
1787 GLenum format,
1788 GLenum type,
1789 const GLvoid *pixels)
1790{
1791
1792 if (context->getClientVersion() < 3)
1793 {
1794 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
1795 yoffset, width, height, 0, format, type, pixels);
1796 }
1797
1798 ASSERT(context->getClientVersion() >= 3);
1799 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
1800 yoffset, 0, width, height, 1, 0, format, type, pixels);
1801}
1802
1803bool ValidateCompressedTexImage2D(Context *context,
1804 GLenum target,
1805 GLint level,
1806 GLenum internalformat,
1807 GLsizei width,
1808 GLsizei height,
1809 GLint border,
1810 GLsizei imageSize,
1811 const GLvoid *data)
1812{
1813 if (context->getClientVersion() < 3)
1814 {
1815 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
1816 0, width, height, border, GL_NONE, GL_NONE, data))
1817 {
1818 return false;
1819 }
1820 }
1821 else
1822 {
1823 ASSERT(context->getClientVersion() >= 3);
1824 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
1825 0, 0, width, height, 1, border, GL_NONE, GL_NONE,
1826 data))
1827 {
1828 return false;
1829 }
1830 }
1831
1832 const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
Jamie Madill513558d2016-06-02 13:04:11 -04001833 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001834 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04001835 if (blockSizeOrErr.isError())
1836 {
1837 context->handleError(blockSizeOrErr.getError());
1838 return false;
1839 }
1840
1841 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05001842 {
Jamie Madill437fa652016-05-03 15:13:24 -04001843 context->handleError(Error(GL_INVALID_VALUE));
Jamie Madill73a84962016-02-12 09:27:23 -05001844 return false;
1845 }
1846
1847 return true;
1848}
1849
1850bool ValidateCompressedTexSubImage2D(Context *context,
1851 GLenum target,
1852 GLint level,
1853 GLint xoffset,
1854 GLint yoffset,
1855 GLsizei width,
1856 GLsizei height,
1857 GLenum format,
1858 GLsizei imageSize,
1859 const GLvoid *data)
1860{
1861 if (context->getClientVersion() < 3)
1862 {
1863 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
1864 yoffset, width, height, 0, GL_NONE, GL_NONE, data))
1865 {
1866 return false;
1867 }
1868 }
1869 else
1870 {
1871 ASSERT(context->getClientVersion() >= 3);
1872 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
1873 yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE,
1874 data))
1875 {
1876 return false;
1877 }
1878 }
1879
1880 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Jamie Madill513558d2016-06-02 13:04:11 -04001881 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001882 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04001883 if (blockSizeOrErr.isError())
1884 {
1885 context->handleError(blockSizeOrErr.getError());
1886 return false;
1887 }
1888
1889 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05001890 {
Jamie Madill437fa652016-05-03 15:13:24 -04001891 context->handleError(Error(GL_INVALID_VALUE));
Jamie Madill73a84962016-02-12 09:27:23 -05001892 return false;
1893 }
1894
1895 return true;
1896}
1897
Olli Etuaho4f667482016-03-30 15:56:35 +03001898bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params)
1899{
1900 if (!context->getExtensions().mapBuffer)
1901 {
Jamie Madill437fa652016-05-03 15:13:24 -04001902 context->handleError(Error(GL_INVALID_OPERATION, "Map buffer extension not available."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001903 return false;
1904 }
1905
1906 return ValidateGetBufferPointervBase(context, target, pname, params);
1907}
1908
1909bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access)
1910{
1911 if (!context->getExtensions().mapBuffer)
1912 {
Jamie Madill437fa652016-05-03 15:13:24 -04001913 context->handleError(Error(GL_INVALID_OPERATION, "Map buffer extension not available."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001914 return false;
1915 }
1916
1917 if (!ValidBufferTarget(context, target))
1918 {
Jamie Madill437fa652016-05-03 15:13:24 -04001919 context->handleError(Error(GL_INVALID_ENUM, "Invalid buffer target."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001920 return false;
1921 }
1922
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001923 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03001924
1925 if (buffer == nullptr)
1926 {
Jamie Madill437fa652016-05-03 15:13:24 -04001927 context->handleError(Error(GL_INVALID_OPERATION, "Attempted to map buffer object zero."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001928 return false;
1929 }
1930
1931 if (access != GL_WRITE_ONLY_OES)
1932 {
Jamie Madill437fa652016-05-03 15:13:24 -04001933 context->handleError(Error(GL_INVALID_ENUM, "Non-write buffer mapping not supported."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001934 return false;
1935 }
1936
1937 if (buffer->isMapped())
1938 {
Jamie Madill437fa652016-05-03 15:13:24 -04001939 context->handleError(Error(GL_INVALID_OPERATION, "Buffer is already mapped."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001940 return false;
1941 }
1942
1943 return true;
1944}
1945
1946bool ValidateUnmapBufferOES(Context *context, GLenum target)
1947{
1948 if (!context->getExtensions().mapBuffer)
1949 {
Jamie Madill437fa652016-05-03 15:13:24 -04001950 context->handleError(Error(GL_INVALID_OPERATION, "Map buffer extension not available."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001951 return false;
1952 }
1953
1954 return ValidateUnmapBufferBase(context, target);
1955}
1956
1957bool ValidateMapBufferRangeEXT(Context *context,
1958 GLenum target,
1959 GLintptr offset,
1960 GLsizeiptr length,
1961 GLbitfield access)
1962{
1963 if (!context->getExtensions().mapBufferRange)
1964 {
Jamie Madill437fa652016-05-03 15:13:24 -04001965 context->handleError(
Olli Etuaho4f667482016-03-30 15:56:35 +03001966 Error(GL_INVALID_OPERATION, "Map buffer range extension not available."));
1967 return false;
1968 }
1969
1970 return ValidateMapBufferRangeBase(context, target, offset, length, access);
1971}
1972
1973bool ValidateFlushMappedBufferRangeEXT(Context *context,
1974 GLenum target,
1975 GLintptr offset,
1976 GLsizeiptr length)
1977{
1978 if (!context->getExtensions().mapBufferRange)
1979 {
Jamie Madill437fa652016-05-03 15:13:24 -04001980 context->handleError(
Olli Etuaho4f667482016-03-30 15:56:35 +03001981 Error(GL_INVALID_OPERATION, "Map buffer range extension not available."));
1982 return false;
1983 }
1984
1985 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
1986}
1987
Ian Ewell54f87462016-03-10 13:47:21 -05001988bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
1989{
1990 Texture *textureObject = context->getTexture(texture);
1991 if (textureObject && textureObject->getTarget() != target && texture != 0)
1992 {
Jamie Madill437fa652016-05-03 15:13:24 -04001993 context->handleError(Error(GL_INVALID_OPERATION, "Invalid texture"));
Ian Ewell54f87462016-03-10 13:47:21 -05001994 return false;
1995 }
1996
1997 switch (target)
1998 {
1999 case GL_TEXTURE_2D:
2000 case GL_TEXTURE_CUBE_MAP:
2001 break;
2002
2003 case GL_TEXTURE_3D:
2004 case GL_TEXTURE_2D_ARRAY:
2005 if (context->getClientVersion() < 3)
2006 {
Jamie Madill437fa652016-05-03 15:13:24 -04002007 context->handleError(Error(GL_INVALID_ENUM, "GLES 3.0 disabled"));
Ian Ewell54f87462016-03-10 13:47:21 -05002008 return false;
2009 }
2010 break;
2011 case GL_TEXTURE_EXTERNAL_OES:
Geoff Langb66a9092016-05-16 15:59:14 -04002012 if (!context->getExtensions().eglImageExternal &&
2013 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05002014 {
Jamie Madill437fa652016-05-03 15:13:24 -04002015 context->handleError(
Ian Ewell54f87462016-03-10 13:47:21 -05002016 Error(GL_INVALID_ENUM, "External texture extension not enabled"));
2017 return false;
2018 }
2019 break;
2020 default:
Jamie Madill437fa652016-05-03 15:13:24 -04002021 context->handleError(Error(GL_INVALID_ENUM, "Invalid target"));
Ian Ewell54f87462016-03-10 13:47:21 -05002022 return false;
2023 }
2024
2025 return true;
2026}
2027
Geoff Langd8605522016-04-13 10:19:12 -04002028bool ValidateBindUniformLocationCHROMIUM(Context *context,
2029 GLuint program,
2030 GLint location,
2031 const GLchar *name)
2032{
2033 if (!context->getExtensions().bindUniformLocation)
2034 {
Jamie Madill437fa652016-05-03 15:13:24 -04002035 context->handleError(
Geoff Langd8605522016-04-13 10:19:12 -04002036 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_bind_uniform_location is not available."));
2037 return false;
2038 }
2039
2040 Program *programObject = GetValidProgram(context, program);
2041 if (!programObject)
2042 {
2043 return false;
2044 }
2045
2046 if (location < 0)
2047 {
Jamie Madill437fa652016-05-03 15:13:24 -04002048 context->handleError(Error(GL_INVALID_VALUE, "Location cannot be less than 0."));
Geoff Langd8605522016-04-13 10:19:12 -04002049 return false;
2050 }
2051
2052 const Caps &caps = context->getCaps();
2053 if (static_cast<size_t>(location) >=
2054 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
2055 {
Jamie Madill437fa652016-05-03 15:13:24 -04002056 context->handleError(Error(GL_INVALID_VALUE,
Geoff Langd8605522016-04-13 10:19:12 -04002057 "Location must be less than (MAX_VERTEX_UNIFORM_VECTORS + "
2058 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4"));
2059 return false;
2060 }
2061
2062 if (strncmp(name, "gl_", 3) == 0)
2063 {
Jamie Madill437fa652016-05-03 15:13:24 -04002064 context->handleError(
Geoff Langd8605522016-04-13 10:19:12 -04002065 Error(GL_INVALID_OPERATION, "Name cannot start with the reserved \"gl_\" prefix."));
2066 return false;
2067 }
2068
2069 return true;
2070}
2071
Jamie Madille2e406c2016-06-02 13:04:10 -04002072bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03002073{
2074 if (!context->getExtensions().framebufferMixedSamples)
2075 {
2076 context->handleError(
2077 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_framebuffer_mixed_samples is not available."));
2078 return false;
2079 }
2080 switch (components)
2081 {
2082 case GL_RGB:
2083 case GL_RGBA:
2084 case GL_ALPHA:
2085 case GL_NONE:
2086 break;
2087 default:
2088 context->handleError(
Jamie Madille2e406c2016-06-02 13:04:10 -04002089 Error(GL_INVALID_ENUM,
2090 "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE."));
Sami Väisänena797e062016-05-12 15:23:40 +03002091 return false;
2092 }
2093
2094 return true;
2095}
2096
Sami Väisänene45e53b2016-05-25 10:36:04 +03002097// CHROMIUM_path_rendering
2098
2099bool ValidateMatrix(Context *context, GLenum matrixMode, const GLfloat *matrix)
2100{
2101 if (!context->getExtensions().pathRendering)
2102 {
2103 context->handleError(
2104 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2105 return false;
2106 }
2107 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
2108 {
2109 context->handleError(Error(GL_INVALID_ENUM, "Invalid matrix mode."));
2110 return false;
2111 }
2112 if (matrix == nullptr)
2113 {
2114 context->handleError(Error(GL_INVALID_OPERATION, "Invalid matrix."));
2115 return false;
2116 }
2117 return true;
2118}
2119
2120bool ValidateMatrixMode(Context *context, GLenum matrixMode)
2121{
2122 if (!context->getExtensions().pathRendering)
2123 {
2124 context->handleError(
2125 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2126 return false;
2127 }
2128 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
2129 {
2130 context->handleError(Error(GL_INVALID_ENUM, "Invalid matrix mode."));
2131 return false;
2132 }
2133 return true;
2134}
2135
2136bool ValidateGenPaths(Context *context, GLsizei range)
2137{
2138 if (!context->getExtensions().pathRendering)
2139 {
2140 context->handleError(
2141 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2142 return false;
2143 }
2144
2145 // range = 0 is undefined in NV_path_rendering.
2146 // we add stricter semantic check here and require a non zero positive range.
2147 if (range <= 0)
2148 {
2149 context->handleError(Error(GL_INVALID_VALUE, "Invalid range."));
2150 return false;
2151 }
2152
2153 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
2154 {
2155 context->handleError(Error(GL_INVALID_OPERATION, "Range overflow."));
2156 return false;
2157 }
2158
2159 return true;
2160}
2161
2162bool ValidateDeletePaths(Context *context, GLuint path, GLsizei range)
2163{
2164 if (!context->getExtensions().pathRendering)
2165 {
2166 context->handleError(
2167 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2168 return false;
2169 }
2170
2171 // range = 0 is undefined in NV_path_rendering.
2172 // we add stricter semantic check here and require a non zero positive range.
2173 if (range <= 0)
2174 {
2175 context->handleError(Error(GL_INVALID_VALUE, "Invalid range."));
2176 return false;
2177 }
2178
2179 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
2180 checkedRange += range;
2181
2182 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
2183 {
2184 context->handleError(Error(GL_INVALID_OPERATION, "Range overflow."));
2185 return false;
2186 }
2187 return true;
2188}
2189
2190bool ValidatePathCommands(Context *context,
2191 GLuint path,
2192 GLsizei numCommands,
2193 const GLubyte *commands,
2194 GLsizei numCoords,
2195 GLenum coordType,
2196 const void *coords)
2197{
2198 if (!context->getExtensions().pathRendering)
2199 {
2200 context->handleError(
2201 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2202 return false;
2203 }
2204 if (!context->hasPath(path))
2205 {
2206 context->handleError(Error(GL_INVALID_OPERATION, "No such path object."));
2207 return false;
2208 }
2209
2210 if (numCommands < 0)
2211 {
2212 context->handleError(Error(GL_INVALID_VALUE, "Invalid number of commands."));
2213 return false;
2214 }
2215 else if (numCommands > 0)
2216 {
2217 if (!commands)
2218 {
2219 context->handleError(Error(GL_INVALID_VALUE, "No commands array given."));
2220 return false;
2221 }
2222 }
2223
2224 if (numCoords < 0)
2225 {
2226 context->handleError(Error(GL_INVALID_VALUE, "Invalid number of coordinates."));
2227 return false;
2228 }
2229 else if (numCoords > 0)
2230 {
2231 if (!coords)
2232 {
2233 context->handleError(Error(GL_INVALID_VALUE, "No coordinate array given."));
2234 return false;
2235 }
2236 }
2237
2238 std::uint32_t coordTypeSize = 0;
2239 switch (coordType)
2240 {
2241 case GL_BYTE:
2242 coordTypeSize = sizeof(GLbyte);
2243 break;
2244
2245 case GL_UNSIGNED_BYTE:
2246 coordTypeSize = sizeof(GLubyte);
2247 break;
2248
2249 case GL_SHORT:
2250 coordTypeSize = sizeof(GLshort);
2251 break;
2252
2253 case GL_UNSIGNED_SHORT:
2254 coordTypeSize = sizeof(GLushort);
2255 break;
2256
2257 case GL_FLOAT:
2258 coordTypeSize = sizeof(GLfloat);
2259 break;
2260
2261 default:
2262 context->handleError(Error(GL_INVALID_ENUM, "Invalid coordinate type."));
2263 return false;
2264 }
2265
2266 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
2267 checkedSize += (coordTypeSize * numCoords);
2268 if (!checkedSize.IsValid())
2269 {
2270 context->handleError(Error(GL_INVALID_OPERATION, "Coord size overflow."));
2271 return false;
2272 }
2273
2274 // early return skips command data validation when it doesn't exist.
2275 if (!commands)
2276 return true;
2277
2278 GLsizei expectedNumCoords = 0;
2279 for (GLsizei i = 0; i < numCommands; ++i)
2280 {
2281 switch (commands[i])
2282 {
2283 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
2284 break;
2285 case GL_MOVE_TO_CHROMIUM:
2286 case GL_LINE_TO_CHROMIUM:
2287 expectedNumCoords += 2;
2288 break;
2289 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
2290 expectedNumCoords += 4;
2291 break;
2292 case GL_CUBIC_CURVE_TO_CHROMIUM:
2293 expectedNumCoords += 6;
2294 break;
2295 case GL_CONIC_CURVE_TO_CHROMIUM:
2296 expectedNumCoords += 5;
2297 break;
2298 default:
2299 context->handleError(Error(GL_INVALID_ENUM, "Invalid command."));
2300 return false;
2301 }
2302 }
2303 if (expectedNumCoords != numCoords)
2304 {
2305 context->handleError(Error(GL_INVALID_VALUE, "Invalid number of coordinates."));
2306 return false;
2307 }
2308
2309 return true;
2310}
2311
2312bool ValidateSetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat value)
2313{
2314 if (!context->getExtensions().pathRendering)
2315 {
2316 context->handleError(
2317 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2318 return false;
2319 }
2320 if (!context->hasPath(path))
2321 {
2322 context->handleError(Error(GL_INVALID_OPERATION, "No such path object."));
2323 return false;
2324 }
2325
2326 switch (pname)
2327 {
2328 case GL_PATH_STROKE_WIDTH_CHROMIUM:
2329 if (value < 0.0f)
2330 {
2331 context->handleError(Error(GL_INVALID_VALUE, "Invalid stroke width."));
2332 return false;
2333 }
2334 break;
2335 case GL_PATH_END_CAPS_CHROMIUM:
2336 switch (static_cast<GLenum>(value))
2337 {
2338 case GL_FLAT_CHROMIUM:
2339 case GL_SQUARE_CHROMIUM:
2340 case GL_ROUND_CHROMIUM:
2341 break;
2342 default:
2343 context->handleError(Error(GL_INVALID_ENUM, "Invalid end caps."));
2344 return false;
2345 }
2346 break;
2347 case GL_PATH_JOIN_STYLE_CHROMIUM:
2348 switch (static_cast<GLenum>(value))
2349 {
2350 case GL_MITER_REVERT_CHROMIUM:
2351 case GL_BEVEL_CHROMIUM:
2352 case GL_ROUND_CHROMIUM:
2353 break;
2354 default:
2355 context->handleError(Error(GL_INVALID_ENUM, "Invalid join style."));
2356 return false;
2357 }
2358 case GL_PATH_MITER_LIMIT_CHROMIUM:
2359 if (value < 0.0f)
2360 {
2361 context->handleError(Error(GL_INVALID_VALUE, "Invalid miter limit."));
2362 return false;
2363 }
2364 break;
2365
2366 case GL_PATH_STROKE_BOUND_CHROMIUM:
2367 // no errors, only clamping.
2368 break;
2369
2370 default:
2371 context->handleError(Error(GL_INVALID_ENUM, "Invalid path parameter."));
2372 return false;
2373 }
2374 return true;
2375}
2376
2377bool ValidateGetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat *value)
2378{
2379 if (!context->getExtensions().pathRendering)
2380 {
2381 context->handleError(
2382 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2383 return false;
2384 }
2385
2386 if (!context->hasPath(path))
2387 {
2388 context->handleError(Error(GL_INVALID_OPERATION, "No such path object."));
2389 return false;
2390 }
2391 if (!value)
2392 {
2393 context->handleError(Error(GL_INVALID_VALUE, "No value array."));
2394 return false;
2395 }
2396
2397 switch (pname)
2398 {
2399 case GL_PATH_STROKE_WIDTH_CHROMIUM:
2400 case GL_PATH_END_CAPS_CHROMIUM:
2401 case GL_PATH_JOIN_STYLE_CHROMIUM:
2402 case GL_PATH_MITER_LIMIT_CHROMIUM:
2403 case GL_PATH_STROKE_BOUND_CHROMIUM:
2404 break;
2405
2406 default:
2407 context->handleError(Error(GL_INVALID_ENUM, "Invalid path parameter."));
2408 return false;
2409 }
2410
2411 return true;
2412}
2413
2414bool ValidatePathStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
2415{
2416 if (!context->getExtensions().pathRendering)
2417 {
2418 context->handleError(
2419 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2420 return false;
2421 }
2422
2423 switch (func)
2424 {
2425 case GL_NEVER:
2426 case GL_ALWAYS:
2427 case GL_LESS:
2428 case GL_LEQUAL:
2429 case GL_EQUAL:
2430 case GL_GEQUAL:
2431 case GL_GREATER:
2432 case GL_NOTEQUAL:
2433 break;
2434 default:
2435 context->handleError(Error(GL_INVALID_ENUM, "Invalid stencil function."));
2436 return false;
2437 }
2438
2439 return true;
2440}
2441
2442// Note that the spec specifies that for the path drawing commands
2443// if the path object is not an existing path object the command
2444// does nothing and no error is generated.
2445// However if the path object exists but has not been specified any
2446// commands then an error is generated.
2447
2448bool ValidateStencilFillPath(Context *context, GLuint path, GLenum fillMode, GLuint mask)
2449{
2450 if (!context->getExtensions().pathRendering)
2451 {
2452 context->handleError(
2453 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2454 return false;
2455 }
2456 if (context->hasPath(path) && !context->hasPathData(path))
2457 {
2458 context->handleError(Error(GL_INVALID_OPERATION, "No such path object."));
2459 return false;
2460 }
2461
2462 switch (fillMode)
2463 {
2464 case GL_COUNT_UP_CHROMIUM:
2465 case GL_COUNT_DOWN_CHROMIUM:
2466 break;
2467 default:
2468 context->handleError(Error(GL_INVALID_ENUM, "Invalid fill mode."));
2469 return false;
2470 }
2471
2472 if (!isPow2(mask + 1))
2473 {
2474 context->handleError(Error(GL_INVALID_VALUE, "Invalid stencil bit mask."));
2475 return false;
2476 }
2477
2478 return true;
2479}
2480
2481bool ValidateStencilStrokePath(Context *context, GLuint path, GLint reference, GLuint mask)
2482{
2483 if (!context->getExtensions().pathRendering)
2484 {
2485 context->handleError(
2486 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2487 return false;
2488 }
2489 if (context->hasPath(path) && !context->hasPathData(path))
2490 {
2491 context->handleError(Error(GL_INVALID_OPERATION, "No such path or path has no data."));
2492 return false;
2493 }
2494
2495 return true;
2496}
2497
2498bool ValidateCoverPath(Context *context, GLuint path, GLenum coverMode)
2499{
2500 if (!context->getExtensions().pathRendering)
2501 {
2502 context->handleError(
2503 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2504 return false;
2505 }
2506 if (context->hasPath(path) && !context->hasPathData(path))
2507 {
2508 context->handleError(Error(GL_INVALID_OPERATION, "No such path object."));
2509 return false;
2510 }
2511
2512 switch (coverMode)
2513 {
2514 case GL_CONVEX_HULL_CHROMIUM:
2515 case GL_BOUNDING_BOX_CHROMIUM:
2516 break;
2517 default:
2518 context->handleError(Error(GL_INVALID_ENUM, "Invalid cover mode."));
2519 return false;
2520 }
2521 return true;
2522}
2523
2524bool ValidateStencilThenCoverFillPath(Context *context,
2525 GLuint path,
2526 GLenum fillMode,
2527 GLuint mask,
2528 GLenum coverMode)
2529{
2530 return ValidateStencilFillPath(context, path, fillMode, mask) &&
2531 ValidateCoverPath(context, path, coverMode);
2532}
2533
2534bool ValidateStencilThenCoverStrokePath(Context *context,
2535 GLuint path,
2536 GLint reference,
2537 GLuint mask,
2538 GLenum coverMode)
2539{
2540 return ValidateStencilStrokePath(context, path, reference, mask) &&
2541 ValidateCoverPath(context, path, coverMode);
2542}
2543
2544bool ValidateIsPath(Context *context)
2545{
2546 if (!context->getExtensions().pathRendering)
2547 {
2548 context->handleError(
2549 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available."));
2550 return false;
2551 }
2552 return true;
2553}
2554
Jamie Madillc29968b2016-01-20 11:17:23 -05002555} // namespace gl