blob: 6e38100185dd52da382939de672fe9eca1121ef2 [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"
10#include "libANGLE/validationES.h"
Jamie Madill73a84962016-02-12 09:27:23 -050011#include "libANGLE/validationES3.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050012#include "libANGLE/Context.h"
13#include "libANGLE/Texture.h"
14#include "libANGLE/Framebuffer.h"
15#include "libANGLE/Renderbuffer.h"
16#include "libANGLE/formatutils.h"
17#include "libANGLE/FramebufferAttachment.h"
Geoff Langd8605522016-04-13 10:19:12 -040018#include "libANGLE/Uniform.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040019
20#include "common/mathutil.h"
21#include "common/utilities.h"
22
23namespace gl
24{
25
Jamie Madillc29968b2016-01-20 11:17:23 -050026namespace
27{
28
29bool IsPartialBlit(gl::Context *context,
30 const FramebufferAttachment *readBuffer,
31 const FramebufferAttachment *writeBuffer,
32 GLint srcX0,
33 GLint srcY0,
34 GLint srcX1,
35 GLint srcY1,
36 GLint dstX0,
37 GLint dstY0,
38 GLint dstX1,
39 GLint dstY1)
40{
41 const Extents &writeSize = writeBuffer->getSize();
42 const Extents &readSize = readBuffer->getSize();
43
44 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
45 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
46 {
47 return true;
48 }
49
50 if (context->getState().isScissorTestEnabled())
51 {
52 const Rectangle &scissor = context->getState().getScissor();
53 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
54 scissor.height < writeSize.height;
55 }
56
57 return false;
58}
59
60} // anonymous namespace
61
Geoff Langb1196682014-07-23 13:47:29 -040062bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
Geoff Lange8ebe7f2013-08-05 15:03:13 -040063 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
64 GLint border, GLenum format, GLenum type, const GLvoid *pixels)
65{
Jamie Madill6f38f822014-06-06 17:12:20 -040066 if (!ValidTexture2DDestinationTarget(context, target))
67 {
Jamie Madill437fa652016-05-03 15:13:24 -040068 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -040069 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -040070 }
71
Austin Kinross08528e12015-10-07 16:24:40 -070072 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040073 {
Jamie Madill437fa652016-05-03 15:13:24 -040074 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -040075 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040076 }
77
Geoff Lange8ebe7f2013-08-05 15:03:13 -040078 if (level < 0 || xoffset < 0 ||
79 std::numeric_limits<GLsizei>::max() - xoffset < width ||
80 std::numeric_limits<GLsizei>::max() - yoffset < height)
81 {
Jamie Madill437fa652016-05-03 15:13:24 -040082 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -040083 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040084 }
85
Geoff Lang005df412013-10-16 14:12:50 -040086 if (!isSubImage && !isCompressed && internalformat != format)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040087 {
Jamie Madill437fa652016-05-03 15:13:24 -040088 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -040089 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040090 }
91
Geoff Langaae65a42014-05-26 12:43:44 -040092 const gl::Caps &caps = context->getCaps();
93
Geoff Langa9be0dc2014-12-17 12:34:40 -050094 if (target == GL_TEXTURE_2D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -040095 {
Geoff Langa9be0dc2014-12-17 12:34:40 -050096 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
97 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -040098 {
Jamie Madill437fa652016-05-03 15:13:24 -040099 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500100 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400101 }
Geoff Langa9be0dc2014-12-17 12:34:40 -0500102 }
Geoff Lang691e58c2014-12-19 17:03:25 -0500103 else if (IsCubeMapTextureTarget(target))
Geoff Langa9be0dc2014-12-17 12:34:40 -0500104 {
105 if (!isSubImage && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400106 {
Jamie Madill437fa652016-05-03 15:13:24 -0400107 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500108 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400109 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400110
Geoff Langa9be0dc2014-12-17 12:34:40 -0500111 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
112 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
113 {
Jamie Madill437fa652016-05-03 15:13:24 -0400114 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500115 return false;
116 }
117 }
118 else
119 {
Jamie Madill437fa652016-05-03 15:13:24 -0400120 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400121 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400122 }
123
Geoff Lang691e58c2014-12-19 17:03:25 -0500124 gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400125 if (!texture)
126 {
Jamie Madill437fa652016-05-03 15:13:24 -0400127 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400128 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400129 }
130
Geoff Langa9be0dc2014-12-17 12:34:40 -0500131 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400132 {
Geoff Langa9be0dc2014-12-17 12:34:40 -0500133 if (format != GL_NONE)
134 {
Geoff Lang051dbc72015-01-05 15:48:58 -0500135 if (gl::GetSizedInternalFormat(format, type) != texture->getInternalFormat(target, level))
Geoff Langa9be0dc2014-12-17 12:34:40 -0500136 {
Jamie Madill437fa652016-05-03 15:13:24 -0400137 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500138 return false;
139 }
140 }
141
142 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
143 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
144 {
Jamie Madill437fa652016-05-03 15:13:24 -0400145 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500146 return false;
147 }
148 }
149 else
150 {
Geoff Lang69cce582015-09-17 13:20:36 -0400151 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -0500152 {
Jamie Madill437fa652016-05-03 15:13:24 -0400153 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langa9be0dc2014-12-17 12:34:40 -0500154 return false;
155 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400156 }
157
158 // Verify zero border
159 if (border != 0)
160 {
Jamie Madill437fa652016-05-03 15:13:24 -0400161 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400162 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400163 }
164
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400165 if (isCompressed)
166 {
tmartino0ccd5ae2015-10-01 14:33:14 -0400167 GLenum actualInternalFormat =
168 isSubImage ? texture->getInternalFormat(target, level) : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400169 switch (actualInternalFormat)
170 {
171 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
172 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400173 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400174 {
Jamie Madill437fa652016-05-03 15:13:24 -0400175 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400176 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400177 }
178 break;
179 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400180 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400181 {
Jamie Madill437fa652016-05-03 15:13:24 -0400182 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400183 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400184 }
185 break;
186 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langb1196682014-07-23 13:47:29 -0400187 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400188 {
Jamie Madill437fa652016-05-03 15:13:24 -0400189 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400190 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400191 }
192 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400193 case GL_ETC1_RGB8_OES:
194 if (!context->getExtensions().compressedETC1RGB8Texture)
195 {
Jamie Madill437fa652016-05-03 15:13:24 -0400196 context->handleError(Error(GL_INVALID_ENUM));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400197 return false;
198 }
199 break;
Minmin Gonge3939b92015-12-01 15:36:51 -0800200 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
201 if (!context->getExtensions().lossyETCDecode)
202 {
Jamie Madill437fa652016-05-03 15:13:24 -0400203 context->handleError(
Minmin Gonge3939b92015-12-01 15:36:51 -0800204 Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported"));
205 return false;
206 }
207 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400208 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400209 context->handleError(Error(
tmartino0ccd5ae2015-10-01 14:33:14 -0400210 GL_INVALID_ENUM, "internalformat is not a supported compressed internal format"));
211 return false;
212 }
213 if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
214 {
Jamie Madill437fa652016-05-03 15:13:24 -0400215 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400216 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400217 }
218 }
219 else
220 {
221 // validate <type> by itself (used as secondary key below)
222 switch (type)
223 {
224 case GL_UNSIGNED_BYTE:
225 case GL_UNSIGNED_SHORT_5_6_5:
226 case GL_UNSIGNED_SHORT_4_4_4_4:
227 case GL_UNSIGNED_SHORT_5_5_5_1:
228 case GL_UNSIGNED_SHORT:
229 case GL_UNSIGNED_INT:
230 case GL_UNSIGNED_INT_24_8_OES:
231 case GL_HALF_FLOAT_OES:
232 case GL_FLOAT:
233 break;
234 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400235 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400236 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400237 }
238
239 // validate <format> + <type> combinations
240 // - invalid <format> -> sets INVALID_ENUM
241 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
242 switch (format)
243 {
244 case GL_ALPHA:
245 case GL_LUMINANCE:
246 case GL_LUMINANCE_ALPHA:
247 switch (type)
248 {
249 case GL_UNSIGNED_BYTE:
250 case GL_FLOAT:
251 case GL_HALF_FLOAT_OES:
252 break;
Geoff Langb1196682014-07-23 13:47:29 -0400253 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400254 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400255 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400256 }
257 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400258 case GL_RED:
Geoff Langcec35902014-04-16 10:52:36 -0400259 case GL_RG:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400260 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400261 {
Jamie Madill437fa652016-05-03 15:13:24 -0400262 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400263 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400264 }
265 switch (type)
266 {
267 case GL_UNSIGNED_BYTE:
268 case GL_FLOAT:
269 case GL_HALF_FLOAT_OES:
270 break;
271 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400272 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400273 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400274 }
275 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400276 case GL_RGB:
277 switch (type)
278 {
279 case GL_UNSIGNED_BYTE:
280 case GL_UNSIGNED_SHORT_5_6_5:
281 case GL_FLOAT:
282 case GL_HALF_FLOAT_OES:
283 break;
284 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400285 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400286 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400287 }
288 break;
289 case GL_RGBA:
290 switch (type)
291 {
292 case GL_UNSIGNED_BYTE:
293 case GL_UNSIGNED_SHORT_4_4_4_4:
294 case GL_UNSIGNED_SHORT_5_5_5_1:
295 case GL_FLOAT:
296 case GL_HALF_FLOAT_OES:
297 break;
298 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400299 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400300 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400301 }
302 break;
303 case GL_BGRA_EXT:
304 switch (type)
305 {
306 case GL_UNSIGNED_BYTE:
307 break;
308 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400309 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400310 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400311 }
312 break;
Geoff Lang05b05022014-06-11 15:31:45 -0400313 case GL_SRGB_EXT:
314 case GL_SRGB_ALPHA_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400315 if (!context->getExtensions().sRGB)
Geoff Lang05b05022014-06-11 15:31:45 -0400316 {
Jamie Madill437fa652016-05-03 15:13:24 -0400317 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400318 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400319 }
320 switch (type)
321 {
322 case GL_UNSIGNED_BYTE:
323 break;
324 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400325 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400326 return false;
Geoff Lang05b05022014-06-11 15:31:45 -0400327 }
328 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400329 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
330 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
331 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
332 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
333 break;
334 case GL_DEPTH_COMPONENT:
335 switch (type)
336 {
337 case GL_UNSIGNED_SHORT:
338 case GL_UNSIGNED_INT:
339 break;
340 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400341 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400342 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400343 }
344 break;
345 case GL_DEPTH_STENCIL_OES:
346 switch (type)
347 {
348 case GL_UNSIGNED_INT_24_8_OES:
349 break;
350 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400351 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400352 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400353 }
354 break;
355 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400356 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400357 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400358 }
359
360 switch (format)
361 {
362 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
363 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400364 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400365 {
Jamie Madill437fa652016-05-03 15:13:24 -0400366 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400367 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400368 }
369 else
370 {
Jamie Madill437fa652016-05-03 15:13:24 -0400371 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400372 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400373 }
374 break;
375 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400376 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400377 {
Jamie Madill437fa652016-05-03 15:13:24 -0400378 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400379 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400380 }
381 else
382 {
Jamie Madill437fa652016-05-03 15:13:24 -0400383 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400384 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400385 }
386 break;
387 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400388 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400389 {
Jamie Madill437fa652016-05-03 15:13:24 -0400390 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400391 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400392 }
393 else
394 {
Jamie Madill437fa652016-05-03 15:13:24 -0400395 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400396 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400397 }
398 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400399 case GL_ETC1_RGB8_OES:
400 if (context->getExtensions().compressedETC1RGB8Texture)
401 {
Jamie Madill437fa652016-05-03 15:13:24 -0400402 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400403 return false;
404 }
405 else
406 {
Jamie Madill437fa652016-05-03 15:13:24 -0400407 context->handleError(Error(GL_INVALID_ENUM));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400408 return false;
409 }
410 break;
Minmin Gonge3939b92015-12-01 15:36:51 -0800411 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
412 if (context->getExtensions().lossyETCDecode)
413 {
Jamie Madill437fa652016-05-03 15:13:24 -0400414 context->handleError(
Minmin Gonge3939b92015-12-01 15:36:51 -0800415 Error(GL_INVALID_OPERATION,
416 "ETC1_RGB8_LOSSY_DECODE_ANGLE can't work with this type."));
417 return false;
418 }
419 else
420 {
Jamie Madill437fa652016-05-03 15:13:24 -0400421 context->handleError(
Minmin Gonge3939b92015-12-01 15:36:51 -0800422 Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
423 return false;
424 }
425 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400426 case GL_DEPTH_COMPONENT:
427 case GL_DEPTH_STENCIL_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400428 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400429 {
Jamie Madill437fa652016-05-03 15:13:24 -0400430 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400431 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400432 }
433 if (target != GL_TEXTURE_2D)
434 {
Jamie Madill437fa652016-05-03 15:13:24 -0400435 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400436 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400437 }
438 // OES_depth_texture supports loading depth data and multiple levels,
439 // but ANGLE_depth_texture does not
440 if (pixels != NULL || level != 0)
441 {
Jamie Madill437fa652016-05-03 15:13:24 -0400442 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400443 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400444 }
445 break;
446 default:
447 break;
448 }
449
450 if (type == GL_FLOAT)
451 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400452 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400453 {
Jamie Madill437fa652016-05-03 15:13:24 -0400454 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400455 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400456 }
457 }
458 else if (type == GL_HALF_FLOAT_OES)
459 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400460 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400461 {
Jamie Madill437fa652016-05-03 15:13:24 -0400462 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400463 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400464 }
465 }
466 }
467
468 return true;
469}
470
Jamie Madillc29968b2016-01-20 11:17:23 -0500471bool ValidateES2CopyTexImageParameters(ValidationContext *context,
472 GLenum target,
473 GLint level,
474 GLenum internalformat,
475 bool isSubImage,
476 GLint xoffset,
477 GLint yoffset,
478 GLint x,
479 GLint y,
480 GLsizei width,
481 GLsizei height,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400482 GLint border)
483{
Jamie Madill560a8d82014-05-21 13:06:20 -0400484 GLenum textureInternalFormat = GL_NONE;
Shannon Woods4dfed832014-03-17 20:03:39 -0400485
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500486 if (!ValidTexture2DDestinationTarget(context, target))
487 {
Jamie Madill437fa652016-05-03 15:13:24 -0400488 context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target"));
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500489 return false;
490 }
491
Jamie Madill560a8d82014-05-21 13:06:20 -0400492 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
493 xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400494 {
Jamie Madill560a8d82014-05-21 13:06:20 -0400495 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400496 }
497
Jamie Madillc29968b2016-01-20 11:17:23 -0500498 const gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400499 GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat();
Jamie Madillbc393df2015-01-29 13:46:07 -0500500 const auto &internalFormatInfo = gl::GetInternalFormatInfo(textureInternalFormat);
501 GLenum textureFormat = internalFormatInfo.format;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400502
503 // [OpenGL ES 2.0.24] table 3.9
504 if (isSubImage)
505 {
506 switch (textureFormat)
507 {
508 case GL_ALPHA:
509 if (colorbufferFormat != GL_ALPHA8_EXT &&
510 colorbufferFormat != GL_RGBA4 &&
511 colorbufferFormat != GL_RGB5_A1 &&
512 colorbufferFormat != GL_RGBA8_OES)
513 {
Jamie Madill437fa652016-05-03 15:13:24 -0400514 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400515 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400516 }
517 break;
518 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400519 if (colorbufferFormat != GL_R8_EXT &&
520 colorbufferFormat != GL_RG8_EXT &&
521 colorbufferFormat != GL_RGB565 &&
522 colorbufferFormat != GL_RGB8_OES &&
523 colorbufferFormat != GL_RGBA4 &&
524 colorbufferFormat != GL_RGB5_A1 &&
525 colorbufferFormat != GL_RGBA8_OES)
526 {
Jamie Madill437fa652016-05-03 15:13:24 -0400527 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400528 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400529 }
530 break;
531 case GL_RED_EXT:
532 if (colorbufferFormat != GL_R8_EXT &&
533 colorbufferFormat != GL_RG8_EXT &&
534 colorbufferFormat != GL_RGB565 &&
535 colorbufferFormat != GL_RGB8_OES &&
536 colorbufferFormat != GL_RGBA4 &&
537 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500538 colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_R32F &&
540 colorbufferFormat != GL_RG32F &&
541 colorbufferFormat != GL_RGB32F &&
542 colorbufferFormat != GL_RGBA32F)
Geoff Lang632192d2013-10-04 13:40:46 -0400543 {
Jamie Madill437fa652016-05-03 15:13:24 -0400544 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400545 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400546 }
547 break;
548 case GL_RG_EXT:
549 if (colorbufferFormat != GL_RG8_EXT &&
550 colorbufferFormat != GL_RGB565 &&
551 colorbufferFormat != GL_RGB8_OES &&
552 colorbufferFormat != GL_RGBA4 &&
553 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500554 colorbufferFormat != GL_RGBA8_OES &&
555 colorbufferFormat != GL_RG32F &&
556 colorbufferFormat != GL_RGB32F &&
557 colorbufferFormat != GL_RGBA32F)
Geoff Lang632192d2013-10-04 13:40:46 -0400558 {
Jamie Madill437fa652016-05-03 15:13:24 -0400559 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400560 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400561 }
562 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400563 case GL_RGB:
564 if (colorbufferFormat != GL_RGB565 &&
565 colorbufferFormat != GL_RGB8_OES &&
566 colorbufferFormat != GL_RGBA4 &&
567 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500568 colorbufferFormat != GL_RGBA8_OES &&
569 colorbufferFormat != GL_RGB32F &&
570 colorbufferFormat != GL_RGBA32F)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400571 {
Jamie Madill437fa652016-05-03 15:13:24 -0400572 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400573 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400574 }
575 break;
576 case GL_LUMINANCE_ALPHA:
577 case GL_RGBA:
578 if (colorbufferFormat != GL_RGBA4 &&
579 colorbufferFormat != GL_RGB5_A1 &&
Jamie Madillbc393df2015-01-29 13:46:07 -0500580 colorbufferFormat != GL_RGBA8_OES &&
581 colorbufferFormat != GL_RGBA32F)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400582 {
Jamie Madill437fa652016-05-03 15:13:24 -0400583 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400584 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400585 }
586 break;
587 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
588 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
589 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
590 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Lang6ea6f942015-09-11 13:11:22 -0400591 case GL_ETC1_RGB8_OES:
Minmin Gonge3939b92015-12-01 15:36:51 -0800592 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Jamie Madill437fa652016-05-03 15:13:24 -0400593 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400594 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400595 case GL_DEPTH_COMPONENT:
596 case GL_DEPTH_STENCIL_OES:
Jamie Madill437fa652016-05-03 15:13:24 -0400597 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400598 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400599 default:
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 }
Jamie Madillbc393df2015-01-29 13:46:07 -0500603
604 if (internalFormatInfo.type == GL_FLOAT &&
605 !context->getExtensions().textureFloat)
606 {
Jamie Madill437fa652016-05-03 15:13:24 -0400607 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillbc393df2015-01-29 13:46:07 -0500608 return false;
609 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400610 }
611 else
612 {
613 switch (internalformat)
614 {
615 case GL_ALPHA:
616 if (colorbufferFormat != GL_ALPHA8_EXT &&
617 colorbufferFormat != GL_RGBA4 &&
618 colorbufferFormat != GL_RGB5_A1 &&
619 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500620 colorbufferFormat != GL_RGBA8_OES &&
621 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400622 {
Jamie Madill437fa652016-05-03 15:13:24 -0400623 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400624 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400625 }
626 break;
627 case GL_LUMINANCE:
Geoff Lang632192d2013-10-04 13:40:46 -0400628 if (colorbufferFormat != GL_R8_EXT &&
629 colorbufferFormat != GL_RG8_EXT &&
630 colorbufferFormat != GL_RGB565 &&
631 colorbufferFormat != GL_RGB8_OES &&
632 colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 &&
634 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500635 colorbufferFormat != GL_RGBA8_OES &&
636 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400637 {
Jamie Madill437fa652016-05-03 15:13:24 -0400638 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400639 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400640 }
641 break;
642 case GL_RED_EXT:
643 if (colorbufferFormat != GL_R8_EXT &&
644 colorbufferFormat != GL_RG8_EXT &&
645 colorbufferFormat != GL_RGB565 &&
646 colorbufferFormat != GL_RGB8_OES &&
647 colorbufferFormat != GL_RGBA4 &&
648 colorbufferFormat != GL_RGB5_A1 &&
649 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500650 colorbufferFormat != GL_RGBA8_OES &&
651 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400652 {
Jamie Madill437fa652016-05-03 15:13:24 -0400653 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400654 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400655 }
656 break;
657 case GL_RG_EXT:
658 if (colorbufferFormat != GL_RG8_EXT &&
659 colorbufferFormat != GL_RGB565 &&
660 colorbufferFormat != GL_RGB8_OES &&
661 colorbufferFormat != GL_RGBA4 &&
662 colorbufferFormat != GL_RGB5_A1 &&
663 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500664 colorbufferFormat != GL_RGBA8_OES &&
665 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lang632192d2013-10-04 13:40:46 -0400666 {
Jamie Madill437fa652016-05-03 15:13:24 -0400667 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400668 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400669 }
670 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400671 case GL_RGB:
672 if (colorbufferFormat != GL_RGB565 &&
673 colorbufferFormat != GL_RGB8_OES &&
674 colorbufferFormat != GL_RGBA4 &&
675 colorbufferFormat != GL_RGB5_A1 &&
676 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500677 colorbufferFormat != GL_RGBA8_OES &&
678 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400679 {
Jamie Madill437fa652016-05-03 15:13:24 -0400680 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400681 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400682 }
683 break;
684 case GL_LUMINANCE_ALPHA:
685 case GL_RGBA:
686 if (colorbufferFormat != GL_RGBA4 &&
687 colorbufferFormat != GL_RGB5_A1 &&
688 colorbufferFormat != GL_BGRA8_EXT &&
Jamie Madill054369e2015-01-07 10:57:08 -0500689 colorbufferFormat != GL_RGBA8_OES &&
690 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400691 {
Jamie Madill437fa652016-05-03 15:13:24 -0400692 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400693 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400694 }
695 break;
696 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
697 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400698 if (context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400699 {
Jamie Madill437fa652016-05-03 15:13:24 -0400700 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400701 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400702 }
703 else
704 {
Jamie Madill437fa652016-05-03 15:13:24 -0400705 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400706 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400707 }
708 break;
709 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400710 if (context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400711 {
Jamie Madill437fa652016-05-03 15:13:24 -0400712 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400713 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400714 }
715 else
716 {
Jamie Madill437fa652016-05-03 15:13:24 -0400717 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400718 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400719 }
720 break;
721 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400722 if (context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400723 {
Jamie Madill437fa652016-05-03 15:13:24 -0400724 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400725 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400726 }
727 else
728 {
Jamie Madill437fa652016-05-03 15:13:24 -0400729 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400730 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400731 }
732 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400733 case GL_ETC1_RGB8_OES:
734 if (context->getExtensions().compressedETC1RGB8Texture)
735 {
Jamie Madill437fa652016-05-03 15:13:24 -0400736 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400737 return false;
738 }
739 else
740 {
Jamie Madill437fa652016-05-03 15:13:24 -0400741 context->handleError(Error(GL_INVALID_ENUM));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400742 return false;
743 }
744 break;
Minmin Gonge3939b92015-12-01 15:36:51 -0800745 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
746 if (context->getExtensions().lossyETCDecode)
747 {
Jamie Madill437fa652016-05-03 15:13:24 -0400748 context->handleError(Error(GL_INVALID_OPERATION,
Minmin Gonge3939b92015-12-01 15:36:51 -0800749 "ETC1_RGB8_LOSSY_DECODE_ANGLE can't be copied to."));
750 return false;
751 }
752 else
753 {
Jamie Madill437fa652016-05-03 15:13:24 -0400754 context->handleError(
Minmin Gonge3939b92015-12-01 15:36:51 -0800755 Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
756 return false;
757 }
758 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400759 case GL_DEPTH_COMPONENT:
760 case GL_DEPTH_COMPONENT16:
761 case GL_DEPTH_COMPONENT32_OES:
762 case GL_DEPTH_STENCIL_OES:
763 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400764 if (context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400765 {
Jamie Madill437fa652016-05-03 15:13:24 -0400766 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400767 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400768 }
769 else
770 {
Jamie Madill437fa652016-05-03 15:13:24 -0400771 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400772 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400773 }
774 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400775 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400776 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400777 }
778 }
779
Geoff Lang784a8fd2013-09-24 12:33:16 -0400780 // If width or height is zero, it is a no-op. Return false without setting an error.
781 return (width > 0 && height > 0);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400782}
783
Geoff Langb1196682014-07-23 13:47:29 -0400784bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400785 GLsizei width, GLsizei height)
786{
787 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
788 {
Jamie Madill437fa652016-05-03 15:13:24 -0400789 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400790 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400791 }
792
793 if (width < 1 || height < 1 || levels < 1)
794 {
Jamie Madill437fa652016-05-03 15:13:24 -0400795 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400796 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400797 }
798
799 if (target == GL_TEXTURE_CUBE_MAP && width != height)
800 {
Jamie Madill437fa652016-05-03 15:13:24 -0400801 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400802 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400803 }
804
805 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
806 {
Jamie Madill437fa652016-05-03 15:13:24 -0400807 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400808 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400809 }
810
Geoff Lang5d601382014-07-22 15:14:06 -0400811 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
812 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400813 {
Jamie Madill437fa652016-05-03 15:13:24 -0400814 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400815 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400816 }
817
Geoff Langaae65a42014-05-26 12:43:44 -0400818 const gl::Caps &caps = context->getCaps();
819
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400820 switch (target)
821 {
822 case GL_TEXTURE_2D:
Geoff Langaae65a42014-05-26 12:43:44 -0400823 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
824 static_cast<GLuint>(height) > caps.max2DTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400825 {
Jamie Madill437fa652016-05-03 15:13:24 -0400826 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400827 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400828 }
829 break;
830 case GL_TEXTURE_CUBE_MAP:
Geoff Langaae65a42014-05-26 12:43:44 -0400831 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
832 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400833 {
Jamie Madill437fa652016-05-03 15:13:24 -0400834 context->handleError(Error(GL_INVALID_VALUE));
Geoff Langb1196682014-07-23 13:47:29 -0400835 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400836 }
837 break;
838 default:
Jamie Madill437fa652016-05-03 15:13:24 -0400839 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400840 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400841 }
842
Geoff Langc0b9ef42014-07-02 10:02:37 -0400843 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400844 {
845 if (!gl::isPow2(width) || !gl::isPow2(height))
846 {
Jamie Madill437fa652016-05-03 15:13:24 -0400847 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400848 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400849 }
850 }
851
852 switch (internalformat)
853 {
854 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
855 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400856 if (!context->getExtensions().textureCompressionDXT1)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400857 {
Jamie Madill437fa652016-05-03 15:13:24 -0400858 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400859 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400860 }
861 break;
862 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400863 if (!context->getExtensions().textureCompressionDXT3)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400864 {
Jamie Madill437fa652016-05-03 15:13:24 -0400865 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400866 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400867 }
868 break;
869 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400870 if (!context->getExtensions().textureCompressionDXT5)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400871 {
Jamie Madill437fa652016-05-03 15:13:24 -0400872 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400873 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400874 }
875 break;
Geoff Lang6ea6f942015-09-11 13:11:22 -0400876 case GL_ETC1_RGB8_OES:
877 if (!context->getExtensions().compressedETC1RGB8Texture)
878 {
Jamie Madill437fa652016-05-03 15:13:24 -0400879 context->handleError(Error(GL_INVALID_ENUM));
Geoff Lang6ea6f942015-09-11 13:11:22 -0400880 return false;
881 }
882 break;
Minmin Gonge3939b92015-12-01 15:36:51 -0800883 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
884 if (!context->getExtensions().lossyETCDecode)
885 {
Jamie Madill437fa652016-05-03 15:13:24 -0400886 context->handleError(
Minmin Gonge3939b92015-12-01 15:36:51 -0800887 Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported."));
888 return false;
889 }
890 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400891 case GL_RGBA32F_EXT:
892 case GL_RGB32F_EXT:
893 case GL_ALPHA32F_EXT:
894 case GL_LUMINANCE32F_EXT:
895 case GL_LUMINANCE_ALPHA32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400896 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400897 {
Jamie Madill437fa652016-05-03 15:13:24 -0400898 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400899 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400900 }
901 break;
902 case GL_RGBA16F_EXT:
903 case GL_RGB16F_EXT:
904 case GL_ALPHA16F_EXT:
905 case GL_LUMINANCE16F_EXT:
906 case GL_LUMINANCE_ALPHA16F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400907 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400908 {
Jamie Madill437fa652016-05-03 15:13:24 -0400909 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400910 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400911 }
912 break;
Geoff Lang632192d2013-10-04 13:40:46 -0400913 case GL_R8_EXT:
914 case GL_RG8_EXT:
915 case GL_R16F_EXT:
916 case GL_RG16F_EXT:
917 case GL_R32F_EXT:
918 case GL_RG32F_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400919 if (!context->getExtensions().textureRG)
Geoff Lang632192d2013-10-04 13:40:46 -0400920 {
Jamie Madill437fa652016-05-03 15:13:24 -0400921 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400922 return false;
Geoff Lang632192d2013-10-04 13:40:46 -0400923 }
924 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400925 case GL_DEPTH_COMPONENT16:
926 case GL_DEPTH_COMPONENT32_OES:
927 case GL_DEPTH24_STENCIL8_OES:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400928 if (!context->getExtensions().depthTextures)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400929 {
Jamie Madill437fa652016-05-03 15:13:24 -0400930 context->handleError(Error(GL_INVALID_ENUM));
Geoff Langb1196682014-07-23 13:47:29 -0400931 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400932 }
933 if (target != GL_TEXTURE_2D)
934 {
Jamie Madill437fa652016-05-03 15:13:24 -0400935 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400936 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400937 }
938 // ANGLE_depth_texture only supports 1-level textures
939 if (levels != 1)
940 {
Jamie Madill437fa652016-05-03 15:13:24 -0400941 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400942 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400943 }
944 break;
945 default:
946 break;
947 }
948
Geoff Lang691e58c2014-12-19 17:03:25 -0500949 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400950 if (!texture || texture->id() == 0)
951 {
Jamie Madill437fa652016-05-03 15:13:24 -0400952 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400953 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400954 }
955
Geoff Lang69cce582015-09-17 13:20:36 -0400956 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400957 {
Jamie Madill437fa652016-05-03 15:13:24 -0400958 context->handleError(Error(GL_INVALID_OPERATION));
Geoff Langb1196682014-07-23 13:47:29 -0400959 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400960 }
961
962 return true;
963}
964
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400965// check for combinations of format and type that are valid for ReadPixels
Geoff Langb1196682014-07-23 13:47:29 -0400966bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400967{
968 switch (format)
969 {
970 case GL_RGBA:
971 switch (type)
972 {
973 case GL_UNSIGNED_BYTE:
974 break;
975 default:
976 return false;
977 }
978 break;
979 case GL_BGRA_EXT:
980 switch (type)
981 {
982 case GL_UNSIGNED_BYTE:
983 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
984 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
985 break;
986 default:
987 return false;
988 }
989 break;
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400990 case GL_RG_EXT:
991 case GL_RED_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400992 if (!context->getExtensions().textureRG)
Geoff Langbdc9b2f2014-04-16 14:41:54 -0400993 {
994 return false;
995 }
996 switch (type)
997 {
998 case GL_UNSIGNED_BYTE:
999 break;
1000 default:
1001 return false;
1002 }
1003 break;
1004
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001005 default:
1006 return false;
1007 }
1008 return true;
1009}
1010
Austin Kinross08332632015-05-05 13:35:47 -07001011bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments,
1012 const GLenum *attachments)
1013{
Jamie Madillc29968b2016-01-20 11:17:23 -05001014 if (!context->getExtensions().discardFramebuffer)
1015 {
Jamie Madill437fa652016-05-03 15:13:24 -04001016 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Jamie Madillc29968b2016-01-20 11:17:23 -05001017 return false;
1018 }
1019
Austin Kinross08332632015-05-05 13:35:47 -07001020 bool defaultFramebuffer = false;
1021
1022 switch (target)
1023 {
1024 case GL_FRAMEBUFFER:
1025 defaultFramebuffer = (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1026 break;
1027 default:
Jamie Madill437fa652016-05-03 15:13:24 -04001028 context->handleError(Error(GL_INVALID_ENUM, "Invalid framebuffer target"));
Austin Kinross08332632015-05-05 13:35:47 -07001029 return false;
1030 }
1031
1032 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer);
1033}
1034
Austin Kinrossbc781f32015-10-26 09:27:38 -07001035bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1036{
1037 if (!context->getExtensions().vertexArrayObject)
1038 {
Jamie Madill437fa652016-05-03 15:13:24 -04001039 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001040 return false;
1041 }
1042
1043 return ValidateBindVertexArrayBase(context, array);
1044}
1045
1046bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n)
1047{
1048 if (!context->getExtensions().vertexArrayObject)
1049 {
Jamie Madill437fa652016-05-03 15:13:24 -04001050 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001051 return false;
1052 }
1053
Olli Etuaho41997e72016-03-10 13:38:39 +02001054 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001055}
1056
1057bool ValidateGenVertexArraysOES(Context *context, GLsizei n)
1058{
1059 if (!context->getExtensions().vertexArrayObject)
1060 {
Jamie Madill437fa652016-05-03 15:13:24 -04001061 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001062 return false;
1063 }
1064
Olli Etuaho41997e72016-03-10 13:38:39 +02001065 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001066}
1067
1068bool ValidateIsVertexArrayOES(Context *context)
1069{
1070 if (!context->getExtensions().vertexArrayObject)
1071 {
Jamie Madill437fa652016-05-03 15:13:24 -04001072 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001073 return false;
1074 }
1075
1076 return true;
1077}
Geoff Langc5629752015-12-07 16:29:04 -05001078
1079bool ValidateProgramBinaryOES(Context *context,
1080 GLuint program,
1081 GLenum binaryFormat,
1082 const void *binary,
1083 GLint length)
1084{
1085 if (!context->getExtensions().getProgramBinary)
1086 {
Jamie Madill437fa652016-05-03 15:13:24 -04001087 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Langc5629752015-12-07 16:29:04 -05001088 return false;
1089 }
1090
1091 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1092}
1093
1094bool ValidateGetProgramBinaryOES(Context *context,
1095 GLuint program,
1096 GLsizei bufSize,
1097 GLsizei *length,
1098 GLenum *binaryFormat,
1099 void *binary)
1100{
1101 if (!context->getExtensions().getProgramBinary)
1102 {
Jamie Madill437fa652016-05-03 15:13:24 -04001103 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Langc5629752015-12-07 16:29:04 -05001104 return false;
1105 }
1106
1107 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1108}
Geoff Lange102fee2015-12-10 11:23:30 -05001109
Geoff Lang70d0f492015-12-10 17:45:46 -05001110static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1111{
1112 switch (source)
1113 {
1114 case GL_DEBUG_SOURCE_API:
1115 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1116 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1117 case GL_DEBUG_SOURCE_OTHER:
1118 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1119 return !mustBeThirdPartyOrApplication;
1120
1121 case GL_DEBUG_SOURCE_THIRD_PARTY:
1122 case GL_DEBUG_SOURCE_APPLICATION:
1123 return true;
1124
1125 default:
1126 return false;
1127 }
1128}
1129
1130static bool ValidDebugType(GLenum type)
1131{
1132 switch (type)
1133 {
1134 case GL_DEBUG_TYPE_ERROR:
1135 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1136 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1137 case GL_DEBUG_TYPE_PERFORMANCE:
1138 case GL_DEBUG_TYPE_PORTABILITY:
1139 case GL_DEBUG_TYPE_OTHER:
1140 case GL_DEBUG_TYPE_MARKER:
1141 case GL_DEBUG_TYPE_PUSH_GROUP:
1142 case GL_DEBUG_TYPE_POP_GROUP:
1143 return true;
1144
1145 default:
1146 return false;
1147 }
1148}
1149
1150static bool ValidDebugSeverity(GLenum severity)
1151{
1152 switch (severity)
1153 {
1154 case GL_DEBUG_SEVERITY_HIGH:
1155 case GL_DEBUG_SEVERITY_MEDIUM:
1156 case GL_DEBUG_SEVERITY_LOW:
1157 case GL_DEBUG_SEVERITY_NOTIFICATION:
1158 return true;
1159
1160 default:
1161 return false;
1162 }
1163}
1164
Geoff Lange102fee2015-12-10 11:23:30 -05001165bool ValidateDebugMessageControlKHR(Context *context,
1166 GLenum source,
1167 GLenum type,
1168 GLenum severity,
1169 GLsizei count,
1170 const GLuint *ids,
1171 GLboolean enabled)
1172{
1173 if (!context->getExtensions().debug)
1174 {
Jamie Madill437fa652016-05-03 15:13:24 -04001175 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001176 return false;
1177 }
1178
Geoff Lang70d0f492015-12-10 17:45:46 -05001179 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1180 {
Jamie Madill437fa652016-05-03 15:13:24 -04001181 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug source."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001182 return false;
1183 }
1184
1185 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1186 {
Jamie Madill437fa652016-05-03 15:13:24 -04001187 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug type."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001188 return false;
1189 }
1190
1191 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1192 {
Jamie Madill437fa652016-05-03 15:13:24 -04001193 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug severity."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001194 return false;
1195 }
1196
1197 if (count > 0)
1198 {
1199 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1200 {
Jamie Madill437fa652016-05-03 15:13:24 -04001201 context->handleError(Error(
Geoff Lang70d0f492015-12-10 17:45:46 -05001202 GL_INVALID_OPERATION,
1203 "If count is greater than zero, source and severity cannot be GL_DONT_CARE."));
1204 return false;
1205 }
1206
1207 if (severity != GL_DONT_CARE)
1208 {
Jamie Madill437fa652016-05-03 15:13:24 -04001209 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001210 Error(GL_INVALID_OPERATION,
1211 "If count is greater than zero, severity must be GL_DONT_CARE."));
1212 return false;
1213 }
1214 }
1215
Geoff Lange102fee2015-12-10 11:23:30 -05001216 return true;
1217}
1218
1219bool ValidateDebugMessageInsertKHR(Context *context,
1220 GLenum source,
1221 GLenum type,
1222 GLuint id,
1223 GLenum severity,
1224 GLsizei length,
1225 const GLchar *buf)
1226{
1227 if (!context->getExtensions().debug)
1228 {
Jamie Madill437fa652016-05-03 15:13:24 -04001229 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001230 return false;
1231 }
1232
Geoff Lang70d0f492015-12-10 17:45:46 -05001233 if (!context->getState().getDebug().isOutputEnabled())
1234 {
1235 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
1236 // not generate an error.
1237 return false;
1238 }
1239
1240 if (!ValidDebugSeverity(severity))
1241 {
Jamie Madill437fa652016-05-03 15:13:24 -04001242 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug severity."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001243 return false;
1244 }
1245
1246 if (!ValidDebugType(type))
1247 {
Jamie Madill437fa652016-05-03 15:13:24 -04001248 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug type."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001249 return false;
1250 }
1251
1252 if (!ValidDebugSource(source, true))
1253 {
Jamie Madill437fa652016-05-03 15:13:24 -04001254 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug source."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001255 return false;
1256 }
1257
1258 size_t messageLength = (length < 0) ? strlen(buf) : length;
1259 if (messageLength > context->getExtensions().maxDebugMessageLength)
1260 {
Jamie Madill437fa652016-05-03 15:13:24 -04001261 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001262 Error(GL_INVALID_VALUE, "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH."));
1263 return false;
1264 }
1265
Geoff Lange102fee2015-12-10 11:23:30 -05001266 return true;
1267}
1268
1269bool ValidateDebugMessageCallbackKHR(Context *context,
1270 GLDEBUGPROCKHR callback,
1271 const void *userParam)
1272{
1273 if (!context->getExtensions().debug)
1274 {
Jamie Madill437fa652016-05-03 15:13:24 -04001275 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001276 return false;
1277 }
1278
Geoff Lange102fee2015-12-10 11:23:30 -05001279 return true;
1280}
1281
1282bool ValidateGetDebugMessageLogKHR(Context *context,
1283 GLuint count,
1284 GLsizei bufSize,
1285 GLenum *sources,
1286 GLenum *types,
1287 GLuint *ids,
1288 GLenum *severities,
1289 GLsizei *lengths,
1290 GLchar *messageLog)
1291{
1292 if (!context->getExtensions().debug)
1293 {
Jamie Madill437fa652016-05-03 15:13:24 -04001294 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001295 return false;
1296 }
1297
Geoff Lang70d0f492015-12-10 17:45:46 -05001298 if (bufSize < 0 && messageLog != nullptr)
1299 {
Jamie Madill437fa652016-05-03 15:13:24 -04001300 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001301 Error(GL_INVALID_VALUE, "bufSize must be positive if messageLog is not null."));
1302 return false;
1303 }
1304
Geoff Lange102fee2015-12-10 11:23:30 -05001305 return true;
1306}
1307
1308bool ValidatePushDebugGroupKHR(Context *context,
1309 GLenum source,
1310 GLuint id,
1311 GLsizei length,
1312 const GLchar *message)
1313{
1314 if (!context->getExtensions().debug)
1315 {
Jamie Madill437fa652016-05-03 15:13:24 -04001316 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001317 return false;
1318 }
1319
Geoff Lang70d0f492015-12-10 17:45:46 -05001320 if (!ValidDebugSource(source, true))
1321 {
Jamie Madill437fa652016-05-03 15:13:24 -04001322 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug source."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001323 return false;
1324 }
1325
1326 size_t messageLength = (length < 0) ? strlen(message) : length;
1327 if (messageLength > context->getExtensions().maxDebugMessageLength)
1328 {
Jamie Madill437fa652016-05-03 15:13:24 -04001329 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001330 Error(GL_INVALID_VALUE, "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH."));
1331 return false;
1332 }
1333
1334 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
1335 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
1336 {
Jamie Madill437fa652016-05-03 15:13:24 -04001337 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001338 Error(GL_STACK_OVERFLOW,
1339 "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups."));
1340 return false;
1341 }
1342
Geoff Lange102fee2015-12-10 11:23:30 -05001343 return true;
1344}
1345
1346bool ValidatePopDebugGroupKHR(Context *context)
1347{
1348 if (!context->getExtensions().debug)
1349 {
Jamie Madill437fa652016-05-03 15:13:24 -04001350 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001351 return false;
1352 }
1353
Geoff Lang70d0f492015-12-10 17:45:46 -05001354 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
1355 if (currentStackSize <= 1)
1356 {
Jamie Madill437fa652016-05-03 15:13:24 -04001357 context->handleError(Error(GL_STACK_UNDERFLOW, "Cannot pop the default debug group."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001358 return false;
1359 }
1360
1361 return true;
1362}
1363
1364static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
1365{
1366 switch (identifier)
1367 {
1368 case GL_BUFFER:
1369 if (context->getBuffer(name) == nullptr)
1370 {
Jamie Madill437fa652016-05-03 15:13:24 -04001371 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid buffer."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001372 return false;
1373 }
1374 return true;
1375
1376 case GL_SHADER:
1377 if (context->getShader(name) == nullptr)
1378 {
Jamie Madill437fa652016-05-03 15:13:24 -04001379 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid shader."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001380 return false;
1381 }
1382 return true;
1383
1384 case GL_PROGRAM:
1385 if (context->getProgram(name) == nullptr)
1386 {
Jamie Madill437fa652016-05-03 15:13:24 -04001387 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid program."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001388 return false;
1389 }
1390 return true;
1391
1392 case GL_VERTEX_ARRAY:
1393 if (context->getVertexArray(name) == nullptr)
1394 {
Jamie Madill437fa652016-05-03 15:13:24 -04001395 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid vertex array."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001396 return false;
1397 }
1398 return true;
1399
1400 case GL_QUERY:
1401 if (context->getQuery(name) == nullptr)
1402 {
Jamie Madill437fa652016-05-03 15:13:24 -04001403 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid query."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001404 return false;
1405 }
1406 return true;
1407
1408 case GL_TRANSFORM_FEEDBACK:
1409 if (context->getTransformFeedback(name) == nullptr)
1410 {
Jamie Madill437fa652016-05-03 15:13:24 -04001411 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001412 Error(GL_INVALID_VALUE, "name is not a valid transform feedback."));
1413 return false;
1414 }
1415 return true;
1416
1417 case GL_SAMPLER:
1418 if (context->getSampler(name) == nullptr)
1419 {
Jamie Madill437fa652016-05-03 15:13:24 -04001420 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid sampler."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001421 return false;
1422 }
1423 return true;
1424
1425 case GL_TEXTURE:
1426 if (context->getTexture(name) == nullptr)
1427 {
Jamie Madill437fa652016-05-03 15:13:24 -04001428 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid texture."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001429 return false;
1430 }
1431 return true;
1432
1433 case GL_RENDERBUFFER:
1434 if (context->getRenderbuffer(name) == nullptr)
1435 {
Jamie Madill437fa652016-05-03 15:13:24 -04001436 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid renderbuffer."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001437 return false;
1438 }
1439 return true;
1440
1441 case GL_FRAMEBUFFER:
1442 if (context->getFramebuffer(name) == nullptr)
1443 {
Jamie Madill437fa652016-05-03 15:13:24 -04001444 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid framebuffer."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001445 return false;
1446 }
1447 return true;
1448
1449 default:
Jamie Madill437fa652016-05-03 15:13:24 -04001450 context->handleError(Error(GL_INVALID_ENUM, "Invalid identifier."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001451 return false;
1452 }
1453
Geoff Lange102fee2015-12-10 11:23:30 -05001454 return true;
1455}
1456
1457bool ValidateObjectLabelKHR(Context *context,
1458 GLenum identifier,
1459 GLuint name,
1460 GLsizei length,
1461 const GLchar *label)
1462{
1463 if (!context->getExtensions().debug)
1464 {
Jamie Madill437fa652016-05-03 15:13:24 -04001465 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001466 return false;
1467 }
1468
Geoff Lang70d0f492015-12-10 17:45:46 -05001469 if (!ValidateObjectIdentifierAndName(context, identifier, name))
1470 {
1471 return false;
1472 }
1473
1474 size_t labelLength = (length < 0) ? strlen(label) : length;
1475 if (labelLength > context->getExtensions().maxLabelLength)
1476 {
Jamie Madill437fa652016-05-03 15:13:24 -04001477 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001478 Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH."));
1479 return false;
1480 }
1481
Geoff Lange102fee2015-12-10 11:23:30 -05001482 return true;
1483}
1484
1485bool ValidateGetObjectLabelKHR(Context *context,
1486 GLenum identifier,
1487 GLuint name,
1488 GLsizei bufSize,
1489 GLsizei *length,
1490 GLchar *label)
1491{
1492 if (!context->getExtensions().debug)
1493 {
Jamie Madill437fa652016-05-03 15:13:24 -04001494 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001495 return false;
1496 }
1497
Geoff Lang70d0f492015-12-10 17:45:46 -05001498 if (bufSize < 0)
1499 {
Jamie Madill437fa652016-05-03 15:13:24 -04001500 context->handleError(Error(GL_INVALID_VALUE, "bufSize cannot be negative."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001501 return false;
1502 }
1503
1504 if (!ValidateObjectIdentifierAndName(context, identifier, name))
1505 {
1506 return false;
1507 }
1508
1509 // Can no-op if bufSize is zero.
1510 return bufSize > 0;
1511}
1512
1513static bool ValidateObjectPtrName(Context *context, const void *ptr)
1514{
1515 if (context->getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
1516 {
Jamie Madill437fa652016-05-03 15:13:24 -04001517 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid sync."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001518 return false;
1519 }
1520
Geoff Lange102fee2015-12-10 11:23:30 -05001521 return true;
1522}
1523
1524bool ValidateObjectPtrLabelKHR(Context *context,
1525 const void *ptr,
1526 GLsizei length,
1527 const GLchar *label)
1528{
1529 if (!context->getExtensions().debug)
1530 {
Jamie Madill437fa652016-05-03 15:13:24 -04001531 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001532 return false;
1533 }
1534
Geoff Lang70d0f492015-12-10 17:45:46 -05001535 if (!ValidateObjectPtrName(context, ptr))
1536 {
1537 return false;
1538 }
1539
1540 size_t labelLength = (length < 0) ? strlen(label) : length;
1541 if (labelLength > context->getExtensions().maxLabelLength)
1542 {
Jamie Madill437fa652016-05-03 15:13:24 -04001543 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001544 Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH."));
1545 return false;
1546 }
1547
Geoff Lange102fee2015-12-10 11:23:30 -05001548 return true;
1549}
1550
1551bool ValidateGetObjectPtrLabelKHR(Context *context,
1552 const void *ptr,
1553 GLsizei bufSize,
1554 GLsizei *length,
1555 GLchar *label)
1556{
1557 if (!context->getExtensions().debug)
1558 {
Jamie Madill437fa652016-05-03 15:13:24 -04001559 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001560 return false;
1561 }
1562
Geoff Lang70d0f492015-12-10 17:45:46 -05001563 if (bufSize < 0)
1564 {
Jamie Madill437fa652016-05-03 15:13:24 -04001565 context->handleError(Error(GL_INVALID_VALUE, "bufSize cannot be negative."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001566 return false;
1567 }
1568
1569 if (!ValidateObjectPtrName(context, ptr))
1570 {
1571 return false;
1572 }
1573
1574 // Can no-op if bufSize is zero.
1575 return bufSize > 0;
Geoff Lange102fee2015-12-10 11:23:30 -05001576}
1577
1578bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
1579{
1580 if (!context->getExtensions().debug)
1581 {
Jamie Madill437fa652016-05-03 15:13:24 -04001582 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001583 return false;
1584 }
1585
Geoff Lang70d0f492015-12-10 17:45:46 -05001586 // TODO: represent this in Context::getQueryParameterInfo.
1587 switch (pname)
1588 {
1589 case GL_DEBUG_CALLBACK_FUNCTION:
1590 case GL_DEBUG_CALLBACK_USER_PARAM:
1591 break;
1592
1593 default:
Jamie Madill437fa652016-05-03 15:13:24 -04001594 context->handleError(Error(GL_INVALID_ENUM, "Invalid pname."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001595 return false;
1596 }
1597
Geoff Lange102fee2015-12-10 11:23:30 -05001598 return true;
1599}
Jamie Madillc29968b2016-01-20 11:17:23 -05001600
1601bool ValidateBlitFramebufferANGLE(Context *context,
1602 GLint srcX0,
1603 GLint srcY0,
1604 GLint srcX1,
1605 GLint srcY1,
1606 GLint dstX0,
1607 GLint dstY0,
1608 GLint dstX1,
1609 GLint dstY1,
1610 GLbitfield mask,
1611 GLenum filter)
1612{
1613 if (!context->getExtensions().framebufferBlit)
1614 {
Jamie Madill437fa652016-05-03 15:13:24 -04001615 context->handleError(Error(GL_INVALID_OPERATION, "Blit extension not available."));
Jamie Madillc29968b2016-01-20 11:17:23 -05001616 return false;
1617 }
1618
1619 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
1620 {
1621 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madill437fa652016-05-03 15:13:24 -04001622 context->handleError(Error(
Jamie Madillc29968b2016-01-20 11:17:23 -05001623 GL_INVALID_OPERATION,
1624 "Scaling and flipping in BlitFramebufferANGLE not supported by this implementation."));
1625 return false;
1626 }
1627
1628 if (filter == GL_LINEAR)
1629 {
Jamie Madill437fa652016-05-03 15:13:24 -04001630 context->handleError(Error(GL_INVALID_ENUM, "Linear blit not supported in this extension"));
Jamie Madillc29968b2016-01-20 11:17:23 -05001631 return false;
1632 }
1633
1634 const Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
1635 const Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
1636
1637 if (mask & GL_COLOR_BUFFER_BIT)
1638 {
1639 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
1640 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
1641
1642 if (readColorAttachment && drawColorAttachment)
1643 {
1644 if (!(readColorAttachment->type() == GL_TEXTURE &&
1645 readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
1646 readColorAttachment->type() != GL_RENDERBUFFER &&
1647 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
1648 {
Jamie Madill437fa652016-05-03 15:13:24 -04001649 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001650 return false;
1651 }
1652
Geoff Langa15472a2015-08-11 11:48:03 -04001653 for (size_t drawbufferIdx = 0;
1654 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05001655 {
Geoff Langa15472a2015-08-11 11:48:03 -04001656 const FramebufferAttachment *attachment =
1657 drawFramebuffer->getDrawBuffer(drawbufferIdx);
1658 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05001659 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001660 if (!(attachment->type() == GL_TEXTURE &&
1661 attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
1662 attachment->type() != GL_RENDERBUFFER &&
1663 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
1664 {
Jamie Madill437fa652016-05-03 15:13:24 -04001665 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001666 return false;
1667 }
1668
1669 // Return an error if the destination formats do not match
1670 if (attachment->getInternalFormat() != readColorAttachment->getInternalFormat())
1671 {
Jamie Madill437fa652016-05-03 15:13:24 -04001672 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001673 return false;
1674 }
1675 }
1676 }
1677
1678 int readSamples = readFramebuffer->getSamples(context->getData());
1679
1680 if (readSamples != 0 &&
1681 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
1682 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
1683 {
Jamie Madill437fa652016-05-03 15:13:24 -04001684 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001685 return false;
1686 }
1687 }
1688 }
1689
1690 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
1691 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1692 for (size_t i = 0; i < 2; i++)
1693 {
1694 if (mask & masks[i])
1695 {
1696 const FramebufferAttachment *readBuffer =
1697 readFramebuffer->getAttachment(attachments[i]);
1698 const FramebufferAttachment *drawBuffer =
1699 drawFramebuffer->getAttachment(attachments[i]);
1700
1701 if (readBuffer && drawBuffer)
1702 {
1703 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
1704 dstX0, dstY0, dstX1, dstY1))
1705 {
1706 // only whole-buffer copies are permitted
1707 ERR(
1708 "Only whole-buffer depth and stencil blits are supported by this "
1709 "implementation.");
Jamie Madill437fa652016-05-03 15:13:24 -04001710 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001711 return false;
1712 }
1713
1714 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
1715 {
Jamie Madill437fa652016-05-03 15:13:24 -04001716 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001717 return false;
1718 }
1719 }
1720 }
1721 }
1722
1723 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
1724 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001725}
Jamie Madillc29968b2016-01-20 11:17:23 -05001726
1727bool ValidateClear(ValidationContext *context, GLbitfield mask)
1728{
1729 const Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
1730 ASSERT(framebufferObject);
1731
1732 if (framebufferObject->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
1733 {
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);
1833 if (imageSize < 0 ||
1834 static_cast<GLuint>(imageSize) !=
1835 formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
1836 {
Jamie Madill437fa652016-05-03 15:13:24 -04001837 context->handleError(Error(GL_INVALID_VALUE));
Jamie Madill73a84962016-02-12 09:27:23 -05001838 return false;
1839 }
1840
1841 return true;
1842}
1843
1844bool ValidateCompressedTexSubImage2D(Context *context,
1845 GLenum target,
1846 GLint level,
1847 GLint xoffset,
1848 GLint yoffset,
1849 GLsizei width,
1850 GLsizei height,
1851 GLenum format,
1852 GLsizei imageSize,
1853 const GLvoid *data)
1854{
1855 if (context->getClientVersion() < 3)
1856 {
1857 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
1858 yoffset, width, height, 0, GL_NONE, GL_NONE, data))
1859 {
1860 return false;
1861 }
1862 }
1863 else
1864 {
1865 ASSERT(context->getClientVersion() >= 3);
1866 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
1867 yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE,
1868 data))
1869 {
1870 return false;
1871 }
1872 }
1873
1874 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
1875 if (imageSize < 0 ||
1876 static_cast<GLuint>(imageSize) !=
1877 formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
1878 {
Jamie Madill437fa652016-05-03 15:13:24 -04001879 context->handleError(Error(GL_INVALID_VALUE));
Jamie Madill73a84962016-02-12 09:27:23 -05001880 return false;
1881 }
1882
1883 return true;
1884}
1885
Olli Etuaho4f667482016-03-30 15:56:35 +03001886bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params)
1887{
1888 if (!context->getExtensions().mapBuffer)
1889 {
Jamie Madill437fa652016-05-03 15:13:24 -04001890 context->handleError(Error(GL_INVALID_OPERATION, "Map buffer extension not available."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001891 return false;
1892 }
1893
1894 return ValidateGetBufferPointervBase(context, target, pname, params);
1895}
1896
1897bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access)
1898{
1899 if (!context->getExtensions().mapBuffer)
1900 {
Jamie Madill437fa652016-05-03 15:13:24 -04001901 context->handleError(Error(GL_INVALID_OPERATION, "Map buffer extension not available."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001902 return false;
1903 }
1904
1905 if (!ValidBufferTarget(context, target))
1906 {
Jamie Madill437fa652016-05-03 15:13:24 -04001907 context->handleError(Error(GL_INVALID_ENUM, "Invalid buffer target."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001908 return false;
1909 }
1910
1911 Buffer *buffer = context->getState().getTargetBuffer(target);
1912
1913 if (buffer == nullptr)
1914 {
Jamie Madill437fa652016-05-03 15:13:24 -04001915 context->handleError(Error(GL_INVALID_OPERATION, "Attempted to map buffer object zero."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001916 return false;
1917 }
1918
1919 if (access != GL_WRITE_ONLY_OES)
1920 {
Jamie Madill437fa652016-05-03 15:13:24 -04001921 context->handleError(Error(GL_INVALID_ENUM, "Non-write buffer mapping not supported."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001922 return false;
1923 }
1924
1925 if (buffer->isMapped())
1926 {
Jamie Madill437fa652016-05-03 15:13:24 -04001927 context->handleError(Error(GL_INVALID_OPERATION, "Buffer is already mapped."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001928 return false;
1929 }
1930
1931 return true;
1932}
1933
1934bool ValidateUnmapBufferOES(Context *context, GLenum target)
1935{
1936 if (!context->getExtensions().mapBuffer)
1937 {
Jamie Madill437fa652016-05-03 15:13:24 -04001938 context->handleError(Error(GL_INVALID_OPERATION, "Map buffer extension not available."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001939 return false;
1940 }
1941
1942 return ValidateUnmapBufferBase(context, target);
1943}
1944
1945bool ValidateMapBufferRangeEXT(Context *context,
1946 GLenum target,
1947 GLintptr offset,
1948 GLsizeiptr length,
1949 GLbitfield access)
1950{
1951 if (!context->getExtensions().mapBufferRange)
1952 {
Jamie Madill437fa652016-05-03 15:13:24 -04001953 context->handleError(
Olli Etuaho4f667482016-03-30 15:56:35 +03001954 Error(GL_INVALID_OPERATION, "Map buffer range extension not available."));
1955 return false;
1956 }
1957
1958 return ValidateMapBufferRangeBase(context, target, offset, length, access);
1959}
1960
1961bool ValidateFlushMappedBufferRangeEXT(Context *context,
1962 GLenum target,
1963 GLintptr offset,
1964 GLsizeiptr length)
1965{
1966 if (!context->getExtensions().mapBufferRange)
1967 {
Jamie Madill437fa652016-05-03 15:13:24 -04001968 context->handleError(
Olli Etuaho4f667482016-03-30 15:56:35 +03001969 Error(GL_INVALID_OPERATION, "Map buffer range extension not available."));
1970 return false;
1971 }
1972
1973 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
1974}
1975
Ian Ewell54f87462016-03-10 13:47:21 -05001976bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
1977{
1978 Texture *textureObject = context->getTexture(texture);
1979 if (textureObject && textureObject->getTarget() != target && texture != 0)
1980 {
Jamie Madill437fa652016-05-03 15:13:24 -04001981 context->handleError(Error(GL_INVALID_OPERATION, "Invalid texture"));
Ian Ewell54f87462016-03-10 13:47:21 -05001982 return false;
1983 }
1984
1985 switch (target)
1986 {
1987 case GL_TEXTURE_2D:
1988 case GL_TEXTURE_CUBE_MAP:
1989 break;
1990
1991 case GL_TEXTURE_3D:
1992 case GL_TEXTURE_2D_ARRAY:
1993 if (context->getClientVersion() < 3)
1994 {
Jamie Madill437fa652016-05-03 15:13:24 -04001995 context->handleError(Error(GL_INVALID_ENUM, "GLES 3.0 disabled"));
Ian Ewell54f87462016-03-10 13:47:21 -05001996 return false;
1997 }
1998 break;
1999 case GL_TEXTURE_EXTERNAL_OES:
2000 if (!context->getExtensions().eglStreamConsumerExternal)
2001 {
Jamie Madill437fa652016-05-03 15:13:24 -04002002 context->handleError(
Ian Ewell54f87462016-03-10 13:47:21 -05002003 Error(GL_INVALID_ENUM, "External texture extension not enabled"));
2004 return false;
2005 }
2006 break;
2007 default:
Jamie Madill437fa652016-05-03 15:13:24 -04002008 context->handleError(Error(GL_INVALID_ENUM, "Invalid target"));
Ian Ewell54f87462016-03-10 13:47:21 -05002009 return false;
2010 }
2011
2012 return true;
2013}
2014
Geoff Langd8605522016-04-13 10:19:12 -04002015bool ValidateBindUniformLocationCHROMIUM(Context *context,
2016 GLuint program,
2017 GLint location,
2018 const GLchar *name)
2019{
2020 if (!context->getExtensions().bindUniformLocation)
2021 {
Jamie Madill437fa652016-05-03 15:13:24 -04002022 context->handleError(
Geoff Langd8605522016-04-13 10:19:12 -04002023 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_bind_uniform_location is not available."));
2024 return false;
2025 }
2026
2027 Program *programObject = GetValidProgram(context, program);
2028 if (!programObject)
2029 {
2030 return false;
2031 }
2032
2033 if (location < 0)
2034 {
Jamie Madill437fa652016-05-03 15:13:24 -04002035 context->handleError(Error(GL_INVALID_VALUE, "Location cannot be less than 0."));
Geoff Langd8605522016-04-13 10:19:12 -04002036 return false;
2037 }
2038
2039 const Caps &caps = context->getCaps();
2040 if (static_cast<size_t>(location) >=
2041 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
2042 {
Jamie Madill437fa652016-05-03 15:13:24 -04002043 context->handleError(Error(GL_INVALID_VALUE,
Geoff Langd8605522016-04-13 10:19:12 -04002044 "Location must be less than (MAX_VERTEX_UNIFORM_VECTORS + "
2045 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4"));
2046 return false;
2047 }
2048
2049 if (strncmp(name, "gl_", 3) == 0)
2050 {
Jamie Madill437fa652016-05-03 15:13:24 -04002051 context->handleError(
Geoff Langd8605522016-04-13 10:19:12 -04002052 Error(GL_INVALID_OPERATION, "Name cannot start with the reserved \"gl_\" prefix."));
2053 return false;
2054 }
2055
2056 return true;
2057}
2058
Sami Väisänena797e062016-05-12 15:23:40 +03002059bool ValidateCoverageModulationCHROMIUM(Context* context, GLenum components)
2060{
2061 if (!context->getExtensions().framebufferMixedSamples)
2062 {
2063 context->handleError(
2064 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_framebuffer_mixed_samples is not available."));
2065 return false;
2066 }
2067 switch (components)
2068 {
2069 case GL_RGB:
2070 case GL_RGBA:
2071 case GL_ALPHA:
2072 case GL_NONE:
2073 break;
2074 default:
2075 context->handleError(
2076 Error(GL_INVALID_ENUM, "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE."));
2077 return false;
2078 }
2079
2080 return true;
2081}
2082
Jamie Madillc29968b2016-01-20 11:17:23 -05002083} // namespace gl