blob: 9dd1eb0c6a4020dd7de07584ec05cf90562e88a5 [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
Jamie Madilldfde6ab2016-06-09 07:07:18 -070050 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050051 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070052 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050053 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 Madilldfde6ab2016-06-09 07:07:18 -0700498 const gl::Framebuffer *framebuffer = context->getGLState().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
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700966bool ValidES2ReadFormatType(ValidationContext *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:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001025 defaultFramebuffer =
1026 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1027 break;
Austin Kinross08332632015-05-05 13:35:47 -07001028 default:
Jamie Madill437fa652016-05-03 15:13:24 -04001029 context->handleError(Error(GL_INVALID_ENUM, "Invalid framebuffer target"));
Austin Kinross08332632015-05-05 13:35:47 -07001030 return false;
1031 }
1032
1033 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer);
1034}
1035
Austin Kinrossbc781f32015-10-26 09:27:38 -07001036bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1037{
1038 if (!context->getExtensions().vertexArrayObject)
1039 {
Jamie Madill437fa652016-05-03 15:13:24 -04001040 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001041 return false;
1042 }
1043
1044 return ValidateBindVertexArrayBase(context, array);
1045}
1046
1047bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n)
1048{
1049 if (!context->getExtensions().vertexArrayObject)
1050 {
Jamie Madill437fa652016-05-03 15:13:24 -04001051 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001052 return false;
1053 }
1054
Olli Etuaho41997e72016-03-10 13:38:39 +02001055 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001056}
1057
1058bool ValidateGenVertexArraysOES(Context *context, GLsizei n)
1059{
1060 if (!context->getExtensions().vertexArrayObject)
1061 {
Jamie Madill437fa652016-05-03 15:13:24 -04001062 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001063 return false;
1064 }
1065
Olli Etuaho41997e72016-03-10 13:38:39 +02001066 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001067}
1068
1069bool ValidateIsVertexArrayOES(Context *context)
1070{
1071 if (!context->getExtensions().vertexArrayObject)
1072 {
Jamie Madill437fa652016-05-03 15:13:24 -04001073 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Austin Kinrossbc781f32015-10-26 09:27:38 -07001074 return false;
1075 }
1076
1077 return true;
1078}
Geoff Langc5629752015-12-07 16:29:04 -05001079
1080bool ValidateProgramBinaryOES(Context *context,
1081 GLuint program,
1082 GLenum binaryFormat,
1083 const void *binary,
1084 GLint length)
1085{
1086 if (!context->getExtensions().getProgramBinary)
1087 {
Jamie Madill437fa652016-05-03 15:13:24 -04001088 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Langc5629752015-12-07 16:29:04 -05001089 return false;
1090 }
1091
1092 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1093}
1094
1095bool ValidateGetProgramBinaryOES(Context *context,
1096 GLuint program,
1097 GLsizei bufSize,
1098 GLsizei *length,
1099 GLenum *binaryFormat,
1100 void *binary)
1101{
1102 if (!context->getExtensions().getProgramBinary)
1103 {
Jamie Madill437fa652016-05-03 15:13:24 -04001104 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Langc5629752015-12-07 16:29:04 -05001105 return false;
1106 }
1107
1108 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1109}
Geoff Lange102fee2015-12-10 11:23:30 -05001110
Geoff Lang70d0f492015-12-10 17:45:46 -05001111static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1112{
1113 switch (source)
1114 {
1115 case GL_DEBUG_SOURCE_API:
1116 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1117 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1118 case GL_DEBUG_SOURCE_OTHER:
1119 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1120 return !mustBeThirdPartyOrApplication;
1121
1122 case GL_DEBUG_SOURCE_THIRD_PARTY:
1123 case GL_DEBUG_SOURCE_APPLICATION:
1124 return true;
1125
1126 default:
1127 return false;
1128 }
1129}
1130
1131static bool ValidDebugType(GLenum type)
1132{
1133 switch (type)
1134 {
1135 case GL_DEBUG_TYPE_ERROR:
1136 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1137 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1138 case GL_DEBUG_TYPE_PERFORMANCE:
1139 case GL_DEBUG_TYPE_PORTABILITY:
1140 case GL_DEBUG_TYPE_OTHER:
1141 case GL_DEBUG_TYPE_MARKER:
1142 case GL_DEBUG_TYPE_PUSH_GROUP:
1143 case GL_DEBUG_TYPE_POP_GROUP:
1144 return true;
1145
1146 default:
1147 return false;
1148 }
1149}
1150
1151static bool ValidDebugSeverity(GLenum severity)
1152{
1153 switch (severity)
1154 {
1155 case GL_DEBUG_SEVERITY_HIGH:
1156 case GL_DEBUG_SEVERITY_MEDIUM:
1157 case GL_DEBUG_SEVERITY_LOW:
1158 case GL_DEBUG_SEVERITY_NOTIFICATION:
1159 return true;
1160
1161 default:
1162 return false;
1163 }
1164}
1165
Geoff Lange102fee2015-12-10 11:23:30 -05001166bool ValidateDebugMessageControlKHR(Context *context,
1167 GLenum source,
1168 GLenum type,
1169 GLenum severity,
1170 GLsizei count,
1171 const GLuint *ids,
1172 GLboolean enabled)
1173{
1174 if (!context->getExtensions().debug)
1175 {
Jamie Madill437fa652016-05-03 15:13:24 -04001176 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001177 return false;
1178 }
1179
Geoff Lang70d0f492015-12-10 17:45:46 -05001180 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1181 {
Jamie Madill437fa652016-05-03 15:13:24 -04001182 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug source."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001183 return false;
1184 }
1185
1186 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1187 {
Jamie Madill437fa652016-05-03 15:13:24 -04001188 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug type."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001189 return false;
1190 }
1191
1192 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1193 {
Jamie Madill437fa652016-05-03 15:13:24 -04001194 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug severity."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001195 return false;
1196 }
1197
1198 if (count > 0)
1199 {
1200 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1201 {
Jamie Madill437fa652016-05-03 15:13:24 -04001202 context->handleError(Error(
Geoff Lang70d0f492015-12-10 17:45:46 -05001203 GL_INVALID_OPERATION,
1204 "If count is greater than zero, source and severity cannot be GL_DONT_CARE."));
1205 return false;
1206 }
1207
1208 if (severity != GL_DONT_CARE)
1209 {
Jamie Madill437fa652016-05-03 15:13:24 -04001210 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001211 Error(GL_INVALID_OPERATION,
1212 "If count is greater than zero, severity must be GL_DONT_CARE."));
1213 return false;
1214 }
1215 }
1216
Geoff Lange102fee2015-12-10 11:23:30 -05001217 return true;
1218}
1219
1220bool ValidateDebugMessageInsertKHR(Context *context,
1221 GLenum source,
1222 GLenum type,
1223 GLuint id,
1224 GLenum severity,
1225 GLsizei length,
1226 const GLchar *buf)
1227{
1228 if (!context->getExtensions().debug)
1229 {
Jamie Madill437fa652016-05-03 15:13:24 -04001230 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001231 return false;
1232 }
1233
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001234 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05001235 {
1236 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
1237 // not generate an error.
1238 return false;
1239 }
1240
1241 if (!ValidDebugSeverity(severity))
1242 {
Jamie Madill437fa652016-05-03 15:13:24 -04001243 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug severity."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001244 return false;
1245 }
1246
1247 if (!ValidDebugType(type))
1248 {
Jamie Madill437fa652016-05-03 15:13:24 -04001249 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug type."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001250 return false;
1251 }
1252
1253 if (!ValidDebugSource(source, true))
1254 {
Jamie Madill437fa652016-05-03 15:13:24 -04001255 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug source."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001256 return false;
1257 }
1258
1259 size_t messageLength = (length < 0) ? strlen(buf) : length;
1260 if (messageLength > context->getExtensions().maxDebugMessageLength)
1261 {
Jamie Madill437fa652016-05-03 15:13:24 -04001262 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001263 Error(GL_INVALID_VALUE, "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH."));
1264 return false;
1265 }
1266
Geoff Lange102fee2015-12-10 11:23:30 -05001267 return true;
1268}
1269
1270bool ValidateDebugMessageCallbackKHR(Context *context,
1271 GLDEBUGPROCKHR callback,
1272 const void *userParam)
1273{
1274 if (!context->getExtensions().debug)
1275 {
Jamie Madill437fa652016-05-03 15:13:24 -04001276 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001277 return false;
1278 }
1279
Geoff Lange102fee2015-12-10 11:23:30 -05001280 return true;
1281}
1282
1283bool ValidateGetDebugMessageLogKHR(Context *context,
1284 GLuint count,
1285 GLsizei bufSize,
1286 GLenum *sources,
1287 GLenum *types,
1288 GLuint *ids,
1289 GLenum *severities,
1290 GLsizei *lengths,
1291 GLchar *messageLog)
1292{
1293 if (!context->getExtensions().debug)
1294 {
Jamie Madill437fa652016-05-03 15:13:24 -04001295 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001296 return false;
1297 }
1298
Geoff Lang70d0f492015-12-10 17:45:46 -05001299 if (bufSize < 0 && messageLog != nullptr)
1300 {
Jamie Madill437fa652016-05-03 15:13:24 -04001301 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001302 Error(GL_INVALID_VALUE, "bufSize must be positive if messageLog is not null."));
1303 return false;
1304 }
1305
Geoff Lange102fee2015-12-10 11:23:30 -05001306 return true;
1307}
1308
1309bool ValidatePushDebugGroupKHR(Context *context,
1310 GLenum source,
1311 GLuint id,
1312 GLsizei length,
1313 const GLchar *message)
1314{
1315 if (!context->getExtensions().debug)
1316 {
Jamie Madill437fa652016-05-03 15:13:24 -04001317 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001318 return false;
1319 }
1320
Geoff Lang70d0f492015-12-10 17:45:46 -05001321 if (!ValidDebugSource(source, true))
1322 {
Jamie Madill437fa652016-05-03 15:13:24 -04001323 context->handleError(Error(GL_INVALID_ENUM, "Invalid debug source."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001324 return false;
1325 }
1326
1327 size_t messageLength = (length < 0) ? strlen(message) : length;
1328 if (messageLength > context->getExtensions().maxDebugMessageLength)
1329 {
Jamie Madill437fa652016-05-03 15:13:24 -04001330 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001331 Error(GL_INVALID_VALUE, "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH."));
1332 return false;
1333 }
1334
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001335 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05001336 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
1337 {
Jamie Madill437fa652016-05-03 15:13:24 -04001338 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001339 Error(GL_STACK_OVERFLOW,
1340 "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups."));
1341 return false;
1342 }
1343
Geoff Lange102fee2015-12-10 11:23:30 -05001344 return true;
1345}
1346
1347bool ValidatePopDebugGroupKHR(Context *context)
1348{
1349 if (!context->getExtensions().debug)
1350 {
Jamie Madill437fa652016-05-03 15:13:24 -04001351 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001352 return false;
1353 }
1354
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001355 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05001356 if (currentStackSize <= 1)
1357 {
Jamie Madill437fa652016-05-03 15:13:24 -04001358 context->handleError(Error(GL_STACK_UNDERFLOW, "Cannot pop the default debug group."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001359 return false;
1360 }
1361
1362 return true;
1363}
1364
1365static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
1366{
1367 switch (identifier)
1368 {
1369 case GL_BUFFER:
1370 if (context->getBuffer(name) == nullptr)
1371 {
Jamie Madill437fa652016-05-03 15:13:24 -04001372 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid buffer."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001373 return false;
1374 }
1375 return true;
1376
1377 case GL_SHADER:
1378 if (context->getShader(name) == nullptr)
1379 {
Jamie Madill437fa652016-05-03 15:13:24 -04001380 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid shader."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001381 return false;
1382 }
1383 return true;
1384
1385 case GL_PROGRAM:
1386 if (context->getProgram(name) == nullptr)
1387 {
Jamie Madill437fa652016-05-03 15:13:24 -04001388 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid program."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001389 return false;
1390 }
1391 return true;
1392
1393 case GL_VERTEX_ARRAY:
1394 if (context->getVertexArray(name) == nullptr)
1395 {
Jamie Madill437fa652016-05-03 15:13:24 -04001396 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid vertex array."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001397 return false;
1398 }
1399 return true;
1400
1401 case GL_QUERY:
1402 if (context->getQuery(name) == nullptr)
1403 {
Jamie Madill437fa652016-05-03 15:13:24 -04001404 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid query."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001405 return false;
1406 }
1407 return true;
1408
1409 case GL_TRANSFORM_FEEDBACK:
1410 if (context->getTransformFeedback(name) == nullptr)
1411 {
Jamie Madill437fa652016-05-03 15:13:24 -04001412 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001413 Error(GL_INVALID_VALUE, "name is not a valid transform feedback."));
1414 return false;
1415 }
1416 return true;
1417
1418 case GL_SAMPLER:
1419 if (context->getSampler(name) == nullptr)
1420 {
Jamie Madill437fa652016-05-03 15:13:24 -04001421 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid sampler."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001422 return false;
1423 }
1424 return true;
1425
1426 case GL_TEXTURE:
1427 if (context->getTexture(name) == nullptr)
1428 {
Jamie Madill437fa652016-05-03 15:13:24 -04001429 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid texture."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001430 return false;
1431 }
1432 return true;
1433
1434 case GL_RENDERBUFFER:
1435 if (context->getRenderbuffer(name) == nullptr)
1436 {
Jamie Madill437fa652016-05-03 15:13:24 -04001437 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid renderbuffer."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001438 return false;
1439 }
1440 return true;
1441
1442 case GL_FRAMEBUFFER:
1443 if (context->getFramebuffer(name) == nullptr)
1444 {
Jamie Madill437fa652016-05-03 15:13:24 -04001445 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid framebuffer."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001446 return false;
1447 }
1448 return true;
1449
1450 default:
Jamie Madill437fa652016-05-03 15:13:24 -04001451 context->handleError(Error(GL_INVALID_ENUM, "Invalid identifier."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001452 return false;
1453 }
1454
Geoff Lange102fee2015-12-10 11:23:30 -05001455 return true;
1456}
1457
1458bool ValidateObjectLabelKHR(Context *context,
1459 GLenum identifier,
1460 GLuint name,
1461 GLsizei length,
1462 const GLchar *label)
1463{
1464 if (!context->getExtensions().debug)
1465 {
Jamie Madill437fa652016-05-03 15:13:24 -04001466 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001467 return false;
1468 }
1469
Geoff Lang70d0f492015-12-10 17:45:46 -05001470 if (!ValidateObjectIdentifierAndName(context, identifier, name))
1471 {
1472 return false;
1473 }
1474
1475 size_t labelLength = (length < 0) ? strlen(label) : length;
1476 if (labelLength > context->getExtensions().maxLabelLength)
1477 {
Jamie Madill437fa652016-05-03 15:13:24 -04001478 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001479 Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH."));
1480 return false;
1481 }
1482
Geoff Lange102fee2015-12-10 11:23:30 -05001483 return true;
1484}
1485
1486bool ValidateGetObjectLabelKHR(Context *context,
1487 GLenum identifier,
1488 GLuint name,
1489 GLsizei bufSize,
1490 GLsizei *length,
1491 GLchar *label)
1492{
1493 if (!context->getExtensions().debug)
1494 {
Jamie Madill437fa652016-05-03 15:13:24 -04001495 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001496 return false;
1497 }
1498
Geoff Lang70d0f492015-12-10 17:45:46 -05001499 if (bufSize < 0)
1500 {
Jamie Madill437fa652016-05-03 15:13:24 -04001501 context->handleError(Error(GL_INVALID_VALUE, "bufSize cannot be negative."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001502 return false;
1503 }
1504
1505 if (!ValidateObjectIdentifierAndName(context, identifier, name))
1506 {
1507 return false;
1508 }
1509
1510 // Can no-op if bufSize is zero.
1511 return bufSize > 0;
1512}
1513
1514static bool ValidateObjectPtrName(Context *context, const void *ptr)
1515{
1516 if (context->getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
1517 {
Jamie Madill437fa652016-05-03 15:13:24 -04001518 context->handleError(Error(GL_INVALID_VALUE, "name is not a valid sync."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001519 return false;
1520 }
1521
Geoff Lange102fee2015-12-10 11:23:30 -05001522 return true;
1523}
1524
1525bool ValidateObjectPtrLabelKHR(Context *context,
1526 const void *ptr,
1527 GLsizei length,
1528 const GLchar *label)
1529{
1530 if (!context->getExtensions().debug)
1531 {
Jamie Madill437fa652016-05-03 15:13:24 -04001532 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001533 return false;
1534 }
1535
Geoff Lang70d0f492015-12-10 17:45:46 -05001536 if (!ValidateObjectPtrName(context, ptr))
1537 {
1538 return false;
1539 }
1540
1541 size_t labelLength = (length < 0) ? strlen(label) : length;
1542 if (labelLength > context->getExtensions().maxLabelLength)
1543 {
Jamie Madill437fa652016-05-03 15:13:24 -04001544 context->handleError(
Geoff Lang70d0f492015-12-10 17:45:46 -05001545 Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH."));
1546 return false;
1547 }
1548
Geoff Lange102fee2015-12-10 11:23:30 -05001549 return true;
1550}
1551
1552bool ValidateGetObjectPtrLabelKHR(Context *context,
1553 const void *ptr,
1554 GLsizei bufSize,
1555 GLsizei *length,
1556 GLchar *label)
1557{
1558 if (!context->getExtensions().debug)
1559 {
Jamie Madill437fa652016-05-03 15:13:24 -04001560 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001561 return false;
1562 }
1563
Geoff Lang70d0f492015-12-10 17:45:46 -05001564 if (bufSize < 0)
1565 {
Jamie Madill437fa652016-05-03 15:13:24 -04001566 context->handleError(Error(GL_INVALID_VALUE, "bufSize cannot be negative."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001567 return false;
1568 }
1569
1570 if (!ValidateObjectPtrName(context, ptr))
1571 {
1572 return false;
1573 }
1574
1575 // Can no-op if bufSize is zero.
1576 return bufSize > 0;
Geoff Lange102fee2015-12-10 11:23:30 -05001577}
1578
1579bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
1580{
1581 if (!context->getExtensions().debug)
1582 {
Jamie Madill437fa652016-05-03 15:13:24 -04001583 context->handleError(Error(GL_INVALID_OPERATION, "Extension not enabled"));
Geoff Lange102fee2015-12-10 11:23:30 -05001584 return false;
1585 }
1586
Geoff Lang70d0f492015-12-10 17:45:46 -05001587 // TODO: represent this in Context::getQueryParameterInfo.
1588 switch (pname)
1589 {
1590 case GL_DEBUG_CALLBACK_FUNCTION:
1591 case GL_DEBUG_CALLBACK_USER_PARAM:
1592 break;
1593
1594 default:
Jamie Madill437fa652016-05-03 15:13:24 -04001595 context->handleError(Error(GL_INVALID_ENUM, "Invalid pname."));
Geoff Lang70d0f492015-12-10 17:45:46 -05001596 return false;
1597 }
1598
Geoff Lange102fee2015-12-10 11:23:30 -05001599 return true;
1600}
Jamie Madillc29968b2016-01-20 11:17:23 -05001601
1602bool ValidateBlitFramebufferANGLE(Context *context,
1603 GLint srcX0,
1604 GLint srcY0,
1605 GLint srcX1,
1606 GLint srcY1,
1607 GLint dstX0,
1608 GLint dstY0,
1609 GLint dstX1,
1610 GLint dstY1,
1611 GLbitfield mask,
1612 GLenum filter)
1613{
1614 if (!context->getExtensions().framebufferBlit)
1615 {
Jamie Madill437fa652016-05-03 15:13:24 -04001616 context->handleError(Error(GL_INVALID_OPERATION, "Blit extension not available."));
Jamie Madillc29968b2016-01-20 11:17:23 -05001617 return false;
1618 }
1619
1620 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
1621 {
1622 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madill437fa652016-05-03 15:13:24 -04001623 context->handleError(Error(
Jamie Madillc29968b2016-01-20 11:17:23 -05001624 GL_INVALID_OPERATION,
1625 "Scaling and flipping in BlitFramebufferANGLE not supported by this implementation."));
1626 return false;
1627 }
1628
1629 if (filter == GL_LINEAR)
1630 {
Jamie Madill437fa652016-05-03 15:13:24 -04001631 context->handleError(Error(GL_INVALID_ENUM, "Linear blit not supported in this extension"));
Jamie Madillc29968b2016-01-20 11:17:23 -05001632 return false;
1633 }
1634
Jamie Madill51f40ec2016-06-15 14:06:00 -04001635 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
1636 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05001637
1638 if (mask & GL_COLOR_BUFFER_BIT)
1639 {
1640 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
1641 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
1642
1643 if (readColorAttachment && drawColorAttachment)
1644 {
1645 if (!(readColorAttachment->type() == GL_TEXTURE &&
1646 readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
1647 readColorAttachment->type() != GL_RENDERBUFFER &&
1648 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
1649 {
Jamie Madill437fa652016-05-03 15:13:24 -04001650 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001651 return false;
1652 }
1653
Geoff Langa15472a2015-08-11 11:48:03 -04001654 for (size_t drawbufferIdx = 0;
1655 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05001656 {
Geoff Langa15472a2015-08-11 11:48:03 -04001657 const FramebufferAttachment *attachment =
1658 drawFramebuffer->getDrawBuffer(drawbufferIdx);
1659 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05001660 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001661 if (!(attachment->type() == GL_TEXTURE &&
1662 attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
1663 attachment->type() != GL_RENDERBUFFER &&
1664 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
1665 {
Jamie Madill437fa652016-05-03 15:13:24 -04001666 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001667 return false;
1668 }
1669
1670 // Return an error if the destination formats do not match
1671 if (attachment->getInternalFormat() != readColorAttachment->getInternalFormat())
1672 {
Jamie Madill437fa652016-05-03 15:13:24 -04001673 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001674 return false;
1675 }
1676 }
1677 }
1678
Jamie Madill51f40ec2016-06-15 14:06:00 -04001679 if (readFramebuffer->getSamples(context->getContextState()) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05001680 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
1681 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
1682 {
Jamie Madill437fa652016-05-03 15:13:24 -04001683 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001684 return false;
1685 }
1686 }
1687 }
1688
1689 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
1690 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1691 for (size_t i = 0; i < 2; i++)
1692 {
1693 if (mask & masks[i])
1694 {
1695 const FramebufferAttachment *readBuffer =
1696 readFramebuffer->getAttachment(attachments[i]);
1697 const FramebufferAttachment *drawBuffer =
1698 drawFramebuffer->getAttachment(attachments[i]);
1699
1700 if (readBuffer && drawBuffer)
1701 {
1702 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
1703 dstX0, dstY0, dstX1, dstY1))
1704 {
1705 // only whole-buffer copies are permitted
1706 ERR(
1707 "Only whole-buffer depth and stencil blits are supported by this "
1708 "implementation.");
Jamie Madill437fa652016-05-03 15:13:24 -04001709 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001710 return false;
1711 }
1712
1713 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
1714 {
Jamie Madill437fa652016-05-03 15:13:24 -04001715 context->handleError(Error(GL_INVALID_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001716 return false;
1717 }
1718 }
1719 }
1720 }
1721
1722 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
1723 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001724}
Jamie Madillc29968b2016-01-20 11:17:23 -05001725
1726bool ValidateClear(ValidationContext *context, GLbitfield mask)
1727{
Jamie Madill51f40ec2016-06-15 14:06:00 -04001728 auto fbo = context->getGLState().getDrawFramebuffer();
1729 if (fbo->checkStatus(context->getContextState()) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05001730 {
Jamie Madill437fa652016-05-03 15:13:24 -04001731 context->handleError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
Jamie Madillc29968b2016-01-20 11:17:23 -05001732 return false;
1733 }
1734
1735 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
1736 {
Jamie Madill437fa652016-05-03 15:13:24 -04001737 context->handleError(Error(GL_INVALID_VALUE));
Jamie Madillc29968b2016-01-20 11:17:23 -05001738 return false;
1739 }
1740
1741 return true;
1742}
1743
1744bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
1745{
1746 if (!context->getExtensions().drawBuffers)
1747 {
Jamie Madill437fa652016-05-03 15:13:24 -04001748 context->handleError(Error(GL_INVALID_OPERATION, "Extension not supported."));
Jamie Madillc29968b2016-01-20 11:17:23 -05001749 return false;
1750 }
1751
1752 return ValidateDrawBuffersBase(context, n, bufs);
1753}
1754
Jamie Madill73a84962016-02-12 09:27:23 -05001755bool ValidateTexImage2D(Context *context,
1756 GLenum target,
1757 GLint level,
1758 GLint internalformat,
1759 GLsizei width,
1760 GLsizei height,
1761 GLint border,
1762 GLenum format,
1763 GLenum type,
1764 const GLvoid *pixels)
1765{
1766 if (context->getClientVersion() < 3)
1767 {
1768 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
1769 0, 0, width, height, border, format, type, pixels);
1770 }
1771
1772 ASSERT(context->getClientVersion() >= 3);
1773 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
1774 0, 0, width, height, 1, border, format, type, pixels);
1775}
1776
1777bool ValidateTexSubImage2D(Context *context,
1778 GLenum target,
1779 GLint level,
1780 GLint xoffset,
1781 GLint yoffset,
1782 GLsizei width,
1783 GLsizei height,
1784 GLenum format,
1785 GLenum type,
1786 const GLvoid *pixels)
1787{
1788
1789 if (context->getClientVersion() < 3)
1790 {
1791 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
1792 yoffset, width, height, 0, format, type, pixels);
1793 }
1794
1795 ASSERT(context->getClientVersion() >= 3);
1796 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
1797 yoffset, 0, width, height, 1, 0, format, type, pixels);
1798}
1799
1800bool ValidateCompressedTexImage2D(Context *context,
1801 GLenum target,
1802 GLint level,
1803 GLenum internalformat,
1804 GLsizei width,
1805 GLsizei height,
1806 GLint border,
1807 GLsizei imageSize,
1808 const GLvoid *data)
1809{
1810 if (context->getClientVersion() < 3)
1811 {
1812 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
1813 0, width, height, border, GL_NONE, GL_NONE, data))
1814 {
1815 return false;
1816 }
1817 }
1818 else
1819 {
1820 ASSERT(context->getClientVersion() >= 3);
1821 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
1822 0, 0, width, height, 1, border, GL_NONE, GL_NONE,
1823 data))
1824 {
1825 return false;
1826 }
1827 }
1828
1829 const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
Jamie Madill513558d2016-06-02 13:04:11 -04001830 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001831 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04001832 if (blockSizeOrErr.isError())
1833 {
1834 context->handleError(blockSizeOrErr.getError());
1835 return false;
1836 }
1837
1838 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05001839 {
Jamie Madill437fa652016-05-03 15:13:24 -04001840 context->handleError(Error(GL_INVALID_VALUE));
Jamie Madill73a84962016-02-12 09:27:23 -05001841 return false;
1842 }
1843
1844 return true;
1845}
1846
1847bool ValidateCompressedTexSubImage2D(Context *context,
1848 GLenum target,
1849 GLint level,
1850 GLint xoffset,
1851 GLint yoffset,
1852 GLsizei width,
1853 GLsizei height,
1854 GLenum format,
1855 GLsizei imageSize,
1856 const GLvoid *data)
1857{
1858 if (context->getClientVersion() < 3)
1859 {
1860 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
1861 yoffset, width, height, 0, GL_NONE, GL_NONE, data))
1862 {
1863 return false;
1864 }
1865 }
1866 else
1867 {
1868 ASSERT(context->getClientVersion() >= 3);
1869 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
1870 yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE,
1871 data))
1872 {
1873 return false;
1874 }
1875 }
1876
1877 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Jamie Madill513558d2016-06-02 13:04:11 -04001878 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07001879 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04001880 if (blockSizeOrErr.isError())
1881 {
1882 context->handleError(blockSizeOrErr.getError());
1883 return false;
1884 }
1885
1886 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05001887 {
Jamie Madill437fa652016-05-03 15:13:24 -04001888 context->handleError(Error(GL_INVALID_VALUE));
Jamie Madill73a84962016-02-12 09:27:23 -05001889 return false;
1890 }
1891
1892 return true;
1893}
1894
Olli Etuaho4f667482016-03-30 15:56:35 +03001895bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params)
1896{
1897 if (!context->getExtensions().mapBuffer)
1898 {
Jamie Madill437fa652016-05-03 15:13:24 -04001899 context->handleError(Error(GL_INVALID_OPERATION, "Map buffer extension not available."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001900 return false;
1901 }
1902
1903 return ValidateGetBufferPointervBase(context, target, pname, params);
1904}
1905
1906bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access)
1907{
1908 if (!context->getExtensions().mapBuffer)
1909 {
Jamie Madill437fa652016-05-03 15:13:24 -04001910 context->handleError(Error(GL_INVALID_OPERATION, "Map buffer extension not available."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001911 return false;
1912 }
1913
1914 if (!ValidBufferTarget(context, target))
1915 {
Jamie Madill437fa652016-05-03 15:13:24 -04001916 context->handleError(Error(GL_INVALID_ENUM, "Invalid buffer target."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001917 return false;
1918 }
1919
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001920 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03001921
1922 if (buffer == nullptr)
1923 {
Jamie Madill437fa652016-05-03 15:13:24 -04001924 context->handleError(Error(GL_INVALID_OPERATION, "Attempted to map buffer object zero."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001925 return false;
1926 }
1927
1928 if (access != GL_WRITE_ONLY_OES)
1929 {
Jamie Madill437fa652016-05-03 15:13:24 -04001930 context->handleError(Error(GL_INVALID_ENUM, "Non-write buffer mapping not supported."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001931 return false;
1932 }
1933
1934 if (buffer->isMapped())
1935 {
Jamie Madill437fa652016-05-03 15:13:24 -04001936 context->handleError(Error(GL_INVALID_OPERATION, "Buffer is already mapped."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001937 return false;
1938 }
1939
1940 return true;
1941}
1942
1943bool ValidateUnmapBufferOES(Context *context, GLenum target)
1944{
1945 if (!context->getExtensions().mapBuffer)
1946 {
Jamie Madill437fa652016-05-03 15:13:24 -04001947 context->handleError(Error(GL_INVALID_OPERATION, "Map buffer extension not available."));
Olli Etuaho4f667482016-03-30 15:56:35 +03001948 return false;
1949 }
1950
1951 return ValidateUnmapBufferBase(context, target);
1952}
1953
1954bool ValidateMapBufferRangeEXT(Context *context,
1955 GLenum target,
1956 GLintptr offset,
1957 GLsizeiptr length,
1958 GLbitfield access)
1959{
1960 if (!context->getExtensions().mapBufferRange)
1961 {
Jamie Madill437fa652016-05-03 15:13:24 -04001962 context->handleError(
Olli Etuaho4f667482016-03-30 15:56:35 +03001963 Error(GL_INVALID_OPERATION, "Map buffer range extension not available."));
1964 return false;
1965 }
1966
1967 return ValidateMapBufferRangeBase(context, target, offset, length, access);
1968}
1969
1970bool ValidateFlushMappedBufferRangeEXT(Context *context,
1971 GLenum target,
1972 GLintptr offset,
1973 GLsizeiptr length)
1974{
1975 if (!context->getExtensions().mapBufferRange)
1976 {
Jamie Madill437fa652016-05-03 15:13:24 -04001977 context->handleError(
Olli Etuaho4f667482016-03-30 15:56:35 +03001978 Error(GL_INVALID_OPERATION, "Map buffer range extension not available."));
1979 return false;
1980 }
1981
1982 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
1983}
1984
Ian Ewell54f87462016-03-10 13:47:21 -05001985bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
1986{
1987 Texture *textureObject = context->getTexture(texture);
1988 if (textureObject && textureObject->getTarget() != target && texture != 0)
1989 {
Jamie Madill437fa652016-05-03 15:13:24 -04001990 context->handleError(Error(GL_INVALID_OPERATION, "Invalid texture"));
Ian Ewell54f87462016-03-10 13:47:21 -05001991 return false;
1992 }
1993
1994 switch (target)
1995 {
1996 case GL_TEXTURE_2D:
1997 case GL_TEXTURE_CUBE_MAP:
1998 break;
1999
2000 case GL_TEXTURE_3D:
2001 case GL_TEXTURE_2D_ARRAY:
2002 if (context->getClientVersion() < 3)
2003 {
Jamie Madill437fa652016-05-03 15:13:24 -04002004 context->handleError(Error(GL_INVALID_ENUM, "GLES 3.0 disabled"));
Ian Ewell54f87462016-03-10 13:47:21 -05002005 return false;
2006 }
2007 break;
2008 case GL_TEXTURE_EXTERNAL_OES:
Geoff Langb66a9092016-05-16 15:59:14 -04002009 if (!context->getExtensions().eglImageExternal &&
2010 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05002011 {
Jamie Madill437fa652016-05-03 15:13:24 -04002012 context->handleError(
Ian Ewell54f87462016-03-10 13:47:21 -05002013 Error(GL_INVALID_ENUM, "External texture extension not enabled"));
2014 return false;
2015 }
2016 break;
2017 default:
Jamie Madill437fa652016-05-03 15:13:24 -04002018 context->handleError(Error(GL_INVALID_ENUM, "Invalid target"));
Ian Ewell54f87462016-03-10 13:47:21 -05002019 return false;
2020 }
2021
2022 return true;
2023}
2024
Geoff Langd8605522016-04-13 10:19:12 -04002025bool ValidateBindUniformLocationCHROMIUM(Context *context,
2026 GLuint program,
2027 GLint location,
2028 const GLchar *name)
2029{
2030 if (!context->getExtensions().bindUniformLocation)
2031 {
Jamie Madill437fa652016-05-03 15:13:24 -04002032 context->handleError(
Geoff Langd8605522016-04-13 10:19:12 -04002033 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_bind_uniform_location is not available."));
2034 return false;
2035 }
2036
2037 Program *programObject = GetValidProgram(context, program);
2038 if (!programObject)
2039 {
2040 return false;
2041 }
2042
2043 if (location < 0)
2044 {
Jamie Madill437fa652016-05-03 15:13:24 -04002045 context->handleError(Error(GL_INVALID_VALUE, "Location cannot be less than 0."));
Geoff Langd8605522016-04-13 10:19:12 -04002046 return false;
2047 }
2048
2049 const Caps &caps = context->getCaps();
2050 if (static_cast<size_t>(location) >=
2051 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
2052 {
Jamie Madill437fa652016-05-03 15:13:24 -04002053 context->handleError(Error(GL_INVALID_VALUE,
Geoff Langd8605522016-04-13 10:19:12 -04002054 "Location must be less than (MAX_VERTEX_UNIFORM_VECTORS + "
2055 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4"));
2056 return false;
2057 }
2058
2059 if (strncmp(name, "gl_", 3) == 0)
2060 {
Jamie Madill437fa652016-05-03 15:13:24 -04002061 context->handleError(
Geoff Langd8605522016-04-13 10:19:12 -04002062 Error(GL_INVALID_OPERATION, "Name cannot start with the reserved \"gl_\" prefix."));
2063 return false;
2064 }
2065
2066 return true;
2067}
2068
Jamie Madille2e406c2016-06-02 13:04:10 -04002069bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03002070{
2071 if (!context->getExtensions().framebufferMixedSamples)
2072 {
2073 context->handleError(
2074 Error(GL_INVALID_OPERATION, "GL_CHROMIUM_framebuffer_mixed_samples is not available."));
2075 return false;
2076 }
2077 switch (components)
2078 {
2079 case GL_RGB:
2080 case GL_RGBA:
2081 case GL_ALPHA:
2082 case GL_NONE:
2083 break;
2084 default:
2085 context->handleError(
Jamie Madille2e406c2016-06-02 13:04:10 -04002086 Error(GL_INVALID_ENUM,
2087 "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE."));
Sami Väisänena797e062016-05-12 15:23:40 +03002088 return false;
2089 }
2090
2091 return true;
2092}
2093
Jamie Madillc29968b2016-01-20 11:17:23 -05002094} // namespace gl