blob: aa02c3d77c49f1972e66857c2134f2dca2f195dd [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madillef300b12016-10-07 15:12:09 -040018#include "libANGLE/Framebuffer.h"
19#include "libANGLE/FramebufferAttachment.h"
20#include "libANGLE/Renderbuffer.h"
21#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040022#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040023#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040024#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040025#include "libANGLE/formatutils.h"
26#include "libANGLE/validationES.h"
27#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040028
29namespace gl
30{
31
Jamie Madillc29968b2016-01-20 11:17:23 -050032namespace
33{
34
35bool IsPartialBlit(gl::Context *context,
36 const FramebufferAttachment *readBuffer,
37 const FramebufferAttachment *writeBuffer,
38 GLint srcX0,
39 GLint srcY0,
40 GLint srcX1,
41 GLint srcY1,
42 GLint dstX0,
43 GLint dstY0,
44 GLint dstX1,
45 GLint dstY1)
46{
47 const Extents &writeSize = writeBuffer->getSize();
48 const Extents &readSize = readBuffer->getSize();
49
50 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
51 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
52 {
53 return true;
54 }
55
Jamie Madilldfde6ab2016-06-09 07:07:18 -070056 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050057 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070058 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050059 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
60 scissor.height < writeSize.height;
61 }
62
63 return false;
64}
65
Sami Väisänend59ca052016-06-21 16:10:00 +030066template <typename T>
67bool ValidatePathInstances(gl::Context *context,
68 GLsizei numPaths,
69 const void *paths,
70 GLuint pathBase)
71{
72 const auto *array = static_cast<const T *>(paths);
73
74 for (GLsizei i = 0; i < numPaths; ++i)
75 {
76 const GLuint pathName = array[i] + pathBase;
77 if (context->hasPath(pathName) && !context->hasPathData(pathName))
78 {
Brandon Jonesafa75152017-07-21 13:11:29 -070079 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030080 return false;
81 }
82 }
83 return true;
84}
85
86bool ValidateInstancedPathParameters(gl::Context *context,
87 GLsizei numPaths,
88 GLenum pathNameType,
89 const void *paths,
90 GLuint pathBase,
91 GLenum transformType,
92 const GLfloat *transformValues)
93{
94 if (!context->getExtensions().pathRendering)
95 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050096 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030097 return false;
98 }
99
100 if (paths == nullptr)
101 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500102 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300103 return false;
104 }
105
106 if (numPaths < 0)
107 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500108 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300109 return false;
110 }
111
112 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
113 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700114 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300115 return false;
116 }
117
118 std::uint32_t pathNameTypeSize = 0;
119 std::uint32_t componentCount = 0;
120
121 switch (pathNameType)
122 {
123 case GL_UNSIGNED_BYTE:
124 pathNameTypeSize = sizeof(GLubyte);
125 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
126 return false;
127 break;
128
129 case GL_BYTE:
130 pathNameTypeSize = sizeof(GLbyte);
131 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
132 return false;
133 break;
134
135 case GL_UNSIGNED_SHORT:
136 pathNameTypeSize = sizeof(GLushort);
137 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
138 return false;
139 break;
140
141 case GL_SHORT:
142 pathNameTypeSize = sizeof(GLshort);
143 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
144 return false;
145 break;
146
147 case GL_UNSIGNED_INT:
148 pathNameTypeSize = sizeof(GLuint);
149 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
150 return false;
151 break;
152
153 case GL_INT:
154 pathNameTypeSize = sizeof(GLint);
155 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
156 return false;
157 break;
158
159 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500160 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300161 return false;
162 }
163
164 switch (transformType)
165 {
166 case GL_NONE:
167 componentCount = 0;
168 break;
169 case GL_TRANSLATE_X_CHROMIUM:
170 case GL_TRANSLATE_Y_CHROMIUM:
171 componentCount = 1;
172 break;
173 case GL_TRANSLATE_2D_CHROMIUM:
174 componentCount = 2;
175 break;
176 case GL_TRANSLATE_3D_CHROMIUM:
177 componentCount = 3;
178 break;
179 case GL_AFFINE_2D_CHROMIUM:
180 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
181 componentCount = 6;
182 break;
183 case GL_AFFINE_3D_CHROMIUM:
184 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
185 componentCount = 12;
186 break;
187 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500188 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300189 return false;
190 }
191 if (componentCount != 0 && transformValues == nullptr)
192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500193 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300194 return false;
195 }
196
197 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
198 checkedSize += (numPaths * pathNameTypeSize);
199 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
200 if (!checkedSize.IsValid())
201 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700202 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300203 return false;
204 }
205
206 return true;
207}
208
Geoff Lang4f0e0032017-05-01 16:04:35 -0400209bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700210{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400211 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400212 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700213 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400214 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700215 case GL_ALPHA:
216 case GL_LUMINANCE:
217 case GL_LUMINANCE_ALPHA:
218 case GL_RGB:
219 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400220 case GL_RGB8:
221 case GL_RGBA8:
222 case GL_BGRA_EXT:
223 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700224 return true;
225
Geoff Lang4f0e0032017-05-01 16:04:35 -0400226 default:
227 return false;
228 }
229}
Geoff Lang97073d12016-04-20 10:42:34 -0700230
Geoff Lang4f0e0032017-05-01 16:04:35 -0400231bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
232{
233 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
234}
235
Geoff Lang4f0e0032017-05-01 16:04:35 -0400236bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
237{
238 // Table 1.0 from the CHROMIUM_copy_texture spec
239 switch (internalFormat)
240 {
241 case GL_RGB:
242 case GL_RGBA:
243 case GL_RGB8:
244 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700245 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400246 case GL_BGRA8_EXT:
247 case GL_SRGB_EXT:
248 case GL_SRGB_ALPHA_EXT:
249 case GL_R8:
250 case GL_R8UI:
251 case GL_RG8:
252 case GL_RG8UI:
253 case GL_SRGB8:
254 case GL_RGB565:
255 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400256 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400257 case GL_SRGB8_ALPHA8:
258 case GL_RGB5_A1:
259 case GL_RGBA4:
260 case GL_RGBA8UI:
261 case GL_RGB9_E5:
262 case GL_R16F:
263 case GL_R32F:
264 case GL_RG16F:
265 case GL_RG32F:
266 case GL_RGB16F:
267 case GL_RGB32F:
268 case GL_RGBA16F:
269 case GL_RGBA32F:
270 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700271 case GL_LUMINANCE:
272 case GL_LUMINANCE_ALPHA:
273 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400274 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700275
276 default:
277 return false;
278 }
279}
280
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400281bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
282{
283 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
284}
285
Geoff Lang97073d12016-04-20 10:42:34 -0700286bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
287{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400288 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700289 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400290 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700291 }
292
Geoff Langc0094ec2017-08-16 14:16:24 -0400293 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
294 {
295 context->handleError(InvalidOperation()
296 << "Invalid combination of type and internalFormat.");
297 return false;
298 }
299
Geoff Lang4f0e0032017-05-01 16:04:35 -0400300 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
301 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700302 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400303 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700304 }
305
306 return true;
307}
308
Geoff Lang63458a32017-10-30 15:16:53 -0400309bool IsValidCopyTextureDestinationTargetEnum(Context *context, GLenum target)
Geoff Lang97073d12016-04-20 10:42:34 -0700310{
311 switch (target)
312 {
313 case GL_TEXTURE_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400314 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
315 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
316 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
317 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
318 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
319 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
Geoff Lang63458a32017-10-30 15:16:53 -0400320 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700321
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400322 case GL_TEXTURE_RECTANGLE_ANGLE:
Geoff Lang63458a32017-10-30 15:16:53 -0400323 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700324
325 default:
326 return false;
327 }
328}
329
Geoff Lang63458a32017-10-30 15:16:53 -0400330bool IsValidCopyTextureDestinationTarget(Context *context, GLenum textureType, GLenum target)
331{
332 if (IsCubeMapTextureTarget(target))
333 {
334 return textureType == GL_TEXTURE_CUBE_MAP;
335 }
336 else
337 {
338 return textureType == target;
339 }
340}
341
Geoff Lang97073d12016-04-20 10:42:34 -0700342bool IsValidCopyTextureSourceTarget(Context *context, GLenum target)
343{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400344 switch (target)
Geoff Lang97073d12016-04-20 10:42:34 -0700345 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346 case GL_TEXTURE_2D:
347 return true;
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400348 case GL_TEXTURE_RECTANGLE_ANGLE:
349 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400350
351 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
352 // supported
353
354 default:
355 return false;
356 }
357}
358
359bool IsValidCopyTextureSourceLevel(Context *context, GLenum target, GLint level)
360{
Geoff Lang3847f942017-07-12 11:17:28 -0400361 if (!ValidMipLevel(context, target, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 {
363 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700364 }
365
Geoff Lang4f0e0032017-05-01 16:04:35 -0400366 if (level > 0 && context->getClientVersion() < ES_3_0)
367 {
368 return false;
369 }
Geoff Lang97073d12016-04-20 10:42:34 -0700370
Geoff Lang4f0e0032017-05-01 16:04:35 -0400371 return true;
372}
373
374bool IsValidCopyTextureDestinationLevel(Context *context,
375 GLenum target,
376 GLint level,
377 GLsizei width,
378 GLsizei height)
379{
Geoff Lang3847f942017-07-12 11:17:28 -0400380 if (!ValidMipLevel(context, target, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400381 {
382 return false;
383 }
384
Geoff Lang4f0e0032017-05-01 16:04:35 -0400385 const Caps &caps = context->getCaps();
386 if (target == GL_TEXTURE_2D)
387 {
388 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
389 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
390 {
391 return false;
392 }
393 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400394 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
395 {
396 ASSERT(level == 0);
397 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
398 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
399 {
400 return false;
401 }
402 }
Geoff Lang4f0e0032017-05-01 16:04:35 -0400403 else if (IsCubeMapTextureTarget(target))
404 {
405 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
406 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
407 {
408 return false;
409 }
410 }
411
412 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700413}
414
Jamie Madillc1d770e2017-04-13 17:31:24 -0400415bool IsValidStencilFunc(GLenum func)
416{
417 switch (func)
418 {
419 case GL_NEVER:
420 case GL_ALWAYS:
421 case GL_LESS:
422 case GL_LEQUAL:
423 case GL_EQUAL:
424 case GL_GEQUAL:
425 case GL_GREATER:
426 case GL_NOTEQUAL:
427 return true;
428
429 default:
430 return false;
431 }
432}
433
434bool IsValidStencilFace(GLenum face)
435{
436 switch (face)
437 {
438 case GL_FRONT:
439 case GL_BACK:
440 case GL_FRONT_AND_BACK:
441 return true;
442
443 default:
444 return false;
445 }
446}
447
448bool IsValidStencilOp(GLenum op)
449{
450 switch (op)
451 {
452 case GL_ZERO:
453 case GL_KEEP:
454 case GL_REPLACE:
455 case GL_INCR:
456 case GL_DECR:
457 case GL_INVERT:
458 case GL_INCR_WRAP:
459 case GL_DECR_WRAP:
460 return true;
461
462 default:
463 return false;
464 }
465}
466
Jamie Madillbe849e42017-05-02 15:49:00 -0400467bool ValidateES2CopyTexImageParameters(ValidationContext *context,
468 GLenum target,
469 GLint level,
470 GLenum internalformat,
471 bool isSubImage,
472 GLint xoffset,
473 GLint yoffset,
474 GLint x,
475 GLint y,
476 GLsizei width,
477 GLsizei height,
478 GLint border)
479{
480 if (!ValidTexture2DDestinationTarget(context, target))
481 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700482 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400483 return false;
484 }
485
486 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
487 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500488 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400489 return false;
490 }
491
492 Format textureFormat = Format::Invalid();
493 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
494 xoffset, yoffset, 0, x, y, width, height, border,
495 &textureFormat))
496 {
497 return false;
498 }
499
500 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
501 GLenum colorbufferFormat =
502 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
503 const auto &formatInfo = *textureFormat.info;
504
505 // [OpenGL ES 2.0.24] table 3.9
506 if (isSubImage)
507 {
508 switch (formatInfo.format)
509 {
510 case GL_ALPHA:
511 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400512 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
513 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400514 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700515 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400516 return false;
517 }
518 break;
519 case GL_LUMINANCE:
520 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
521 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
522 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400523 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
524 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400525 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700526 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400527 return false;
528 }
529 break;
530 case GL_RED_EXT:
531 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
532 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
533 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
534 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
535 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400536 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
537 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400538 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700539 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400540 return false;
541 }
542 break;
543 case GL_RG_EXT:
544 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
545 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
546 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
547 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400548 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
549 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400550 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700551 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400552 return false;
553 }
554 break;
555 case GL_RGB:
556 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
557 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
558 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400559 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
560 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400561 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700562 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 return false;
564 }
565 break;
566 case GL_LUMINANCE_ALPHA:
567 case GL_RGBA:
568 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400569 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
570 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400571 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700572 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400573 return false;
574 }
575 break;
576 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
577 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
578 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
579 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
580 case GL_ETC1_RGB8_OES:
581 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
582 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
583 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
584 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
585 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700586 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400587 return false;
588 case GL_DEPTH_COMPONENT:
589 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700590 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400591 return false;
592 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700593 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400594 return false;
595 }
596
597 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
598 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700599 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400600 return false;
601 }
602 }
603 else
604 {
605 switch (internalformat)
606 {
607 case GL_ALPHA:
608 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
609 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
610 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
611 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700612 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400613 return false;
614 }
615 break;
616 case GL_LUMINANCE:
617 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
618 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
619 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
620 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
621 colorbufferFormat != GL_BGR5_A1_ANGLEX)
622 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700623 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400624 return false;
625 }
626 break;
627 case GL_RED_EXT:
628 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
629 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
630 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
631 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
632 colorbufferFormat != GL_BGR5_A1_ANGLEX)
633 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700634 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400635 return false;
636 }
637 break;
638 case GL_RG_EXT:
639 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
640 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
641 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
642 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
643 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700644 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400645 return false;
646 }
647 break;
648 case GL_RGB:
649 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
650 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
651 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
652 colorbufferFormat != GL_BGR5_A1_ANGLEX)
653 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700654 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400655 return false;
656 }
657 break;
658 case GL_LUMINANCE_ALPHA:
659 case GL_RGBA:
660 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
661 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
662 colorbufferFormat != GL_BGR5_A1_ANGLEX)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 break;
668 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
669 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
670 if (context->getExtensions().textureCompressionDXT1)
671 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700672 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400673 return false;
674 }
675 else
676 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700677 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400678 return false;
679 }
680 break;
681 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
682 if (context->getExtensions().textureCompressionDXT3)
683 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700684 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400685 return false;
686 }
687 else
688 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700689 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400690 return false;
691 }
692 break;
693 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
694 if (context->getExtensions().textureCompressionDXT5)
695 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700696 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400697 return false;
698 }
699 else
700 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700701 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400702 return false;
703 }
704 break;
705 case GL_ETC1_RGB8_OES:
706 if (context->getExtensions().compressedETC1RGB8Texture)
707 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500708 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400709 return false;
710 }
711 else
712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500713 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400714 return false;
715 }
716 break;
717 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
718 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
719 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
720 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
721 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
722 if (context->getExtensions().lossyETCDecode)
723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500724 context->handleError(InvalidOperation()
725 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400726 return false;
727 }
728 else
729 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500730 context->handleError(InvalidEnum()
731 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400732 return false;
733 }
734 break;
735 case GL_DEPTH_COMPONENT:
736 case GL_DEPTH_COMPONENT16:
737 case GL_DEPTH_COMPONENT32_OES:
738 case GL_DEPTH_STENCIL_OES:
739 case GL_DEPTH24_STENCIL8_OES:
740 if (context->getExtensions().depthTextures)
741 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500742 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400743 return false;
744 }
745 else
746 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500747 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400748 return false;
749 }
750 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500751 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400752 return false;
753 }
754 }
755
756 // If width or height is zero, it is a no-op. Return false without setting an error.
757 return (width > 0 && height > 0);
758}
759
760bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
761{
762 switch (cap)
763 {
764 // EXT_multisample_compatibility
765 case GL_MULTISAMPLE_EXT:
766 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
767 return context->getExtensions().multisampleCompatibility;
768
769 case GL_CULL_FACE:
770 case GL_POLYGON_OFFSET_FILL:
771 case GL_SAMPLE_ALPHA_TO_COVERAGE:
772 case GL_SAMPLE_COVERAGE:
773 case GL_SCISSOR_TEST:
774 case GL_STENCIL_TEST:
775 case GL_DEPTH_TEST:
776 case GL_BLEND:
777 case GL_DITHER:
778 return true;
779
780 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
781 case GL_RASTERIZER_DISCARD:
782 return (context->getClientMajorVersion() >= 3);
783
784 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
785 case GL_DEBUG_OUTPUT:
786 return context->getExtensions().debug;
787
788 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
789 return queryOnly && context->getExtensions().bindGeneratesResource;
790
791 case GL_CLIENT_ARRAYS_ANGLE:
792 return queryOnly && context->getExtensions().clientArrays;
793
794 case GL_FRAMEBUFFER_SRGB_EXT:
795 return context->getExtensions().sRGBWriteControl;
796
797 case GL_SAMPLE_MASK:
798 return context->getClientVersion() >= Version(3, 1);
799
Geoff Langb433e872017-10-05 14:01:47 -0400800 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400801 return queryOnly && context->getExtensions().robustResourceInitialization;
802
803 default:
804 return false;
805 }
806}
807
Geoff Langfc32e8b2017-05-31 14:16:59 -0400808// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
809// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400810bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400811{
812 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400813 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
814 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400815 {
816 return true;
817 }
818
819 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
820 if (c >= 9 && c <= 13)
821 {
822 return true;
823 }
824
825 return false;
826}
827
Geoff Langcab92ee2017-07-19 17:32:07 -0400828bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400829{
Geoff Langa71a98e2017-06-19 15:15:00 -0400830 for (size_t i = 0; i < len; i++)
831 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400832 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400833 {
834 return false;
835 }
836 }
837
838 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400839}
840
Geoff Langcab92ee2017-07-19 17:32:07 -0400841bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
842{
843 enum class ParseState
844 {
845 // Have not seen an ASCII non-whitespace character yet on
846 // this line. Possible that we might see a preprocessor
847 // directive.
848 BEGINING_OF_LINE,
849
850 // Have seen at least one ASCII non-whitespace character
851 // on this line.
852 MIDDLE_OF_LINE,
853
854 // Handling a preprocessor directive. Passes through all
855 // characters up to the end of the line. Disables comment
856 // processing.
857 IN_PREPROCESSOR_DIRECTIVE,
858
859 // Handling a single-line comment. The comment text is
860 // replaced with a single space.
861 IN_SINGLE_LINE_COMMENT,
862
863 // Handling a multi-line comment. Newlines are passed
864 // through to preserve line numbers.
865 IN_MULTI_LINE_COMMENT
866 };
867
868 ParseState state = ParseState::BEGINING_OF_LINE;
869 size_t pos = 0;
870
871 while (pos < len)
872 {
873 char c = str[pos];
874 char next = pos + 1 < len ? str[pos + 1] : 0;
875
876 // Check for newlines
877 if (c == '\n' || c == '\r')
878 {
879 if (state != ParseState::IN_MULTI_LINE_COMMENT)
880 {
881 state = ParseState::BEGINING_OF_LINE;
882 }
883
884 pos++;
885 continue;
886 }
887
888 switch (state)
889 {
890 case ParseState::BEGINING_OF_LINE:
891 if (c == ' ')
892 {
893 // Maintain the BEGINING_OF_LINE state until a non-space is seen
894 pos++;
895 }
896 else if (c == '#')
897 {
898 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
899 pos++;
900 }
901 else
902 {
903 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
904 state = ParseState::MIDDLE_OF_LINE;
905 }
906 break;
907
908 case ParseState::MIDDLE_OF_LINE:
909 if (c == '/' && next == '/')
910 {
911 state = ParseState::IN_SINGLE_LINE_COMMENT;
912 pos++;
913 }
914 else if (c == '/' && next == '*')
915 {
916 state = ParseState::IN_MULTI_LINE_COMMENT;
917 pos++;
918 }
919 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
920 {
921 // Skip line continuation characters
922 }
923 else if (!IsValidESSLCharacter(c))
924 {
925 return false;
926 }
927 pos++;
928 break;
929
930 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700931 // Line-continuation characters may not be permitted.
932 // Otherwise, just pass it through. Do not parse comments in this state.
933 if (!lineContinuationAllowed && c == '\\')
934 {
935 return false;
936 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400937 pos++;
938 break;
939
940 case ParseState::IN_SINGLE_LINE_COMMENT:
941 // Line-continuation characters are processed before comment processing.
942 // Advance string if a new line character is immediately behind
943 // line-continuation character.
944 if (c == '\\' && (next == '\n' || next == '\r'))
945 {
946 pos++;
947 }
948 pos++;
949 break;
950
951 case ParseState::IN_MULTI_LINE_COMMENT:
952 if (c == '*' && next == '/')
953 {
954 state = ParseState::MIDDLE_OF_LINE;
955 pos++;
956 }
957 pos++;
958 break;
959 }
960 }
961
962 return true;
963}
964
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700965bool ValidateWebGLNamePrefix(ValidationContext *context, const GLchar *name)
966{
967 ASSERT(context->isWebGL());
968
969 // WebGL 1.0 [Section 6.16] GLSL Constructs
970 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
971 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
972 {
973 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
974 return false;
975 }
976
977 return true;
978}
979
980bool ValidateWebGLNameLength(ValidationContext *context, size_t length)
981{
982 ASSERT(context->isWebGL());
983
984 if (context->isWebGL1() && length > 256)
985 {
986 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
987 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
988 // locations.
989 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
990
991 return false;
992 }
993 else if (length > 1024)
994 {
995 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
996 // uniform and attribute locations.
997 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
998 return false;
999 }
1000
1001 return true;
1002}
1003
Jamie Madillc29968b2016-01-20 11:17:23 -05001004} // anonymous namespace
1005
Geoff Langff5b2d52016-09-07 11:32:23 -04001006bool ValidateES2TexImageParameters(Context *context,
1007 GLenum target,
1008 GLint level,
1009 GLenum internalformat,
1010 bool isCompressed,
1011 bool isSubImage,
1012 GLint xoffset,
1013 GLint yoffset,
1014 GLsizei width,
1015 GLsizei height,
1016 GLint border,
1017 GLenum format,
1018 GLenum type,
1019 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001020 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001021{
Jamie Madill6f38f822014-06-06 17:12:20 -04001022 if (!ValidTexture2DDestinationTarget(context, target))
1023 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001024 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001025 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001026 }
1027
Austin Kinross08528e12015-10-07 16:24:40 -07001028 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001029 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001030 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001031 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001032 }
1033
Brandon Jones6cad5662017-06-14 13:25:13 -07001034 if (!ValidMipLevel(context, target, level))
1035 {
1036 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1037 return false;
1038 }
1039
1040 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001041 std::numeric_limits<GLsizei>::max() - yoffset < height)
1042 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001043 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001044 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001045 }
1046
Geoff Lang6e898aa2017-06-02 11:17:26 -04001047 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1048 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1049 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1050 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1051 // case.
1052 bool nonEqualFormatsAllowed =
1053 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1054 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1055
1056 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001058 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001059 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001060 }
1061
Geoff Langaae65a42014-05-26 12:43:44 -04001062 const gl::Caps &caps = context->getCaps();
1063
Geoff Langa9be0dc2014-12-17 12:34:40 -05001064 if (target == GL_TEXTURE_2D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001065 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05001066 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1067 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001069 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001070 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001071 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001072 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001073 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
1074 {
1075 ASSERT(level == 0);
1076 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1077 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1078 {
1079 context->handleError(InvalidValue());
1080 return false;
1081 }
1082 if (isCompressed)
1083 {
1084 context->handleError(InvalidEnum()
1085 << "Rectangle texture cannot have a compressed format.");
1086 return false;
1087 }
1088 }
Geoff Lang691e58c2014-12-19 17:03:25 -05001089 else if (IsCubeMapTextureTarget(target))
Geoff Langa9be0dc2014-12-17 12:34:40 -05001090 {
1091 if (!isSubImage && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001092 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001093 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001094 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001095 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001096
Geoff Langa9be0dc2014-12-17 12:34:40 -05001097 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1098 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1099 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001100 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001101 return false;
1102 }
1103 }
1104 else
1105 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001106 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001107 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001108 }
1109
He Yunchaoced53ae2016-11-29 15:00:51 +08001110 gl::Texture *texture =
1111 context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001112 if (!texture)
1113 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001114 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001115 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001116 }
1117
Geoff Langa9be0dc2014-12-17 12:34:40 -05001118 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001119 {
Geoff Langca271392017-04-05 12:30:00 -04001120 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1121 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001123 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001124 return false;
1125 }
1126
Geoff Langa9be0dc2014-12-17 12:34:40 -05001127 if (format != GL_NONE)
1128 {
Geoff Langca271392017-04-05 12:30:00 -04001129 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1130 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001131 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001132 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001133 return false;
1134 }
1135 }
1136
1137 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1138 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001140 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001141 return false;
1142 }
Geoff Langfb052642017-10-24 13:42:09 -04001143
1144 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallez336129f2017-10-17 15:55:40 -04001145 context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001146 {
1147 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1148 return false;
1149 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001150 }
1151 else
1152 {
Geoff Lang69cce582015-09-17 13:20:36 -04001153 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001155 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001156 return false;
1157 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001158 }
1159
1160 // Verify zero border
1161 if (border != 0)
1162 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001163 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001164 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001165 }
1166
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001167 if (isCompressed)
1168 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001169 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001170 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1171 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001172 switch (actualInternalFormat)
1173 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001174 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1175 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1176 if (!context->getExtensions().textureCompressionDXT1)
1177 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001178 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001179 return false;
1180 }
1181 break;
1182 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001183 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001184 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001185 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001186 return false;
1187 }
1188 break;
1189 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1190 if (!context->getExtensions().textureCompressionDXT5)
1191 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001192 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001193 return false;
1194 }
1195 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001196 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1197 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1198 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1199 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1200 if (!context->getExtensions().textureCompressionS3TCsRGB)
1201 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001202 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001203 return false;
1204 }
1205 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001206 case GL_ETC1_RGB8_OES:
1207 if (!context->getExtensions().compressedETC1RGB8Texture)
1208 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001209 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001210 return false;
1211 }
Geoff Lang86f81162017-10-30 15:10:45 -04001212 if (isSubImage)
1213 {
1214 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1215 return false;
1216 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001217 break;
1218 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001219 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1220 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1221 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1222 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001223 if (!context->getExtensions().lossyETCDecode)
1224 {
Geoff Lang86f81162017-10-30 15:10:45 -04001225 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001226 return false;
1227 }
1228 break;
1229 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001230 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001231 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001232 }
Geoff Lang966c9402017-04-18 12:38:27 -04001233
1234 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001235 {
Geoff Lang966c9402017-04-18 12:38:27 -04001236 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1237 height, texture->getWidth(target, level),
1238 texture->getHeight(target, level)))
1239 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001240 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001241 return false;
1242 }
1243
1244 if (format != actualInternalFormat)
1245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001246 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001247 return false;
1248 }
1249 }
1250 else
1251 {
1252 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1253 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001254 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001255 return false;
1256 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001257 }
1258 }
1259 else
1260 {
1261 // validate <type> by itself (used as secondary key below)
1262 switch (type)
1263 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001264 case GL_UNSIGNED_BYTE:
1265 case GL_UNSIGNED_SHORT_5_6_5:
1266 case GL_UNSIGNED_SHORT_4_4_4_4:
1267 case GL_UNSIGNED_SHORT_5_5_5_1:
1268 case GL_UNSIGNED_SHORT:
1269 case GL_UNSIGNED_INT:
1270 case GL_UNSIGNED_INT_24_8_OES:
1271 case GL_HALF_FLOAT_OES:
1272 case GL_FLOAT:
1273 break;
1274 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001275 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001276 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001277 }
1278
1279 // validate <format> + <type> combinations
1280 // - invalid <format> -> sets INVALID_ENUM
1281 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1282 switch (format)
1283 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001284 case GL_ALPHA:
1285 case GL_LUMINANCE:
1286 case GL_LUMINANCE_ALPHA:
1287 switch (type)
1288 {
1289 case GL_UNSIGNED_BYTE:
1290 case GL_FLOAT:
1291 case GL_HALF_FLOAT_OES:
1292 break;
1293 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001294 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001295 return false;
1296 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001297 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001298 case GL_RED:
1299 case GL_RG:
1300 if (!context->getExtensions().textureRG)
1301 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001302 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 return false;
1304 }
1305 switch (type)
1306 {
1307 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001308 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001309 case GL_FLOAT:
1310 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001311 if (!context->getExtensions().textureFloat)
1312 {
1313 context->handleError(InvalidEnum());
1314 return false;
1315 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001316 break;
1317 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001318 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001319 return false;
1320 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001321 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001322 case GL_RGB:
1323 switch (type)
1324 {
1325 case GL_UNSIGNED_BYTE:
1326 case GL_UNSIGNED_SHORT_5_6_5:
1327 case GL_FLOAT:
1328 case GL_HALF_FLOAT_OES:
1329 break;
1330 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001331 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001332 return false;
1333 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001334 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001335 case GL_RGBA:
1336 switch (type)
1337 {
1338 case GL_UNSIGNED_BYTE:
1339 case GL_UNSIGNED_SHORT_4_4_4_4:
1340 case GL_UNSIGNED_SHORT_5_5_5_1:
1341 case GL_FLOAT:
1342 case GL_HALF_FLOAT_OES:
1343 break;
1344 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001345 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001346 return false;
1347 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001348 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001349 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001350 if (!context->getExtensions().textureFormatBGRA8888)
1351 {
1352 context->handleError(InvalidEnum());
1353 return false;
1354 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001355 switch (type)
1356 {
1357 case GL_UNSIGNED_BYTE:
1358 break;
1359 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001360 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001361 return false;
1362 }
1363 break;
1364 case GL_SRGB_EXT:
1365 case GL_SRGB_ALPHA_EXT:
1366 if (!context->getExtensions().sRGB)
1367 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001368 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 return false;
1370 }
1371 switch (type)
1372 {
1373 case GL_UNSIGNED_BYTE:
1374 break;
1375 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001376 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001377 return false;
1378 }
1379 break;
1380 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1381 // handled below
1382 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1383 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1384 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1385 break;
1386 case GL_DEPTH_COMPONENT:
1387 switch (type)
1388 {
1389 case GL_UNSIGNED_SHORT:
1390 case GL_UNSIGNED_INT:
1391 break;
1392 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001394 return false;
1395 }
1396 break;
1397 case GL_DEPTH_STENCIL_OES:
1398 switch (type)
1399 {
1400 case GL_UNSIGNED_INT_24_8_OES:
1401 break;
1402 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001403 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001404 return false;
1405 }
1406 break;
1407 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001408 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001409 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001410 }
1411
1412 switch (format)
1413 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001414 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1415 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1416 if (context->getExtensions().textureCompressionDXT1)
1417 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001418 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001419 return false;
1420 }
1421 else
1422 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001423 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001424 return false;
1425 }
1426 break;
1427 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1428 if (context->getExtensions().textureCompressionDXT3)
1429 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001430 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001431 return false;
1432 }
1433 else
1434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001435 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001436 return false;
1437 }
1438 break;
1439 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1440 if (context->getExtensions().textureCompressionDXT5)
1441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001442 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 else
1446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001447 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001448 return false;
1449 }
1450 break;
1451 case GL_ETC1_RGB8_OES:
1452 if (context->getExtensions().compressedETC1RGB8Texture)
1453 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001454 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001455 return false;
1456 }
1457 else
1458 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001459 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001460 return false;
1461 }
1462 break;
1463 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001464 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1465 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1466 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1467 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 if (context->getExtensions().lossyETCDecode)
1469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001470 context->handleError(InvalidOperation()
1471 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001472 return false;
1473 }
1474 else
1475 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001476 context->handleError(InvalidEnum()
1477 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001478 return false;
1479 }
1480 break;
1481 case GL_DEPTH_COMPONENT:
1482 case GL_DEPTH_STENCIL_OES:
1483 if (!context->getExtensions().depthTextures)
1484 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001485 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001486 return false;
1487 }
1488 if (target != GL_TEXTURE_2D)
1489 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001490 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001491 return false;
1492 }
1493 // OES_depth_texture supports loading depth data and multiple levels,
1494 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001495 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001496 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001497 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1498 return false;
1499 }
1500 if (level != 0)
1501 {
1502 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001503 return false;
1504 }
1505 break;
1506 default:
1507 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001508 }
1509
Geoff Lang6e898aa2017-06-02 11:17:26 -04001510 if (!isSubImage)
1511 {
1512 switch (internalformat)
1513 {
1514 case GL_RGBA32F:
1515 if (!context->getExtensions().colorBufferFloatRGBA)
1516 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001517 context->handleError(InvalidValue()
1518 << "Sized GL_RGBA32F internal format requires "
1519 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001520 return false;
1521 }
1522 if (type != GL_FLOAT)
1523 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001524 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001525 return false;
1526 }
1527 if (format != GL_RGBA)
1528 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001529 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001530 return false;
1531 }
1532 break;
1533
1534 case GL_RGB32F:
1535 if (!context->getExtensions().colorBufferFloatRGB)
1536 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001537 context->handleError(InvalidValue()
1538 << "Sized GL_RGB32F internal format requires "
1539 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001540 return false;
1541 }
1542 if (type != GL_FLOAT)
1543 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001544 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001545 return false;
1546 }
1547 if (format != GL_RGB)
1548 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001549 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001550 return false;
1551 }
1552 break;
1553
1554 default:
1555 break;
1556 }
1557 }
1558
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001559 if (type == GL_FLOAT)
1560 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001561 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001562 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001563 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001564 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001565 }
1566 }
1567 else if (type == GL_HALF_FLOAT_OES)
1568 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001569 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001570 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001571 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001572 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001573 }
1574 }
1575 }
1576
Geoff Langdbcced82017-06-06 15:55:54 -04001577 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1578 if (!ValidImageDataSize(context, target, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001579 imageSize))
1580 {
1581 return false;
1582 }
1583
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001584 return true;
1585}
1586
He Yunchaoced53ae2016-11-29 15:00:51 +08001587bool ValidateES2TexStorageParameters(Context *context,
1588 GLenum target,
1589 GLsizei levels,
1590 GLenum internalformat,
1591 GLsizei width,
1592 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001593{
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001594 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP &&
1595 target != GL_TEXTURE_RECTANGLE_ANGLE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001596 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001597 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001598 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001599 }
1600
1601 if (width < 1 || height < 1 || levels < 1)
1602 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001603 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001604 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001605 }
1606
1607 if (target == GL_TEXTURE_CUBE_MAP && width != height)
1608 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001609 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001610 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001611 }
1612
1613 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1614 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001615 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001616 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001617 }
1618
Geoff Langca271392017-04-05 12:30:00 -04001619 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001620 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001621 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001622 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001623 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001624 }
1625
Geoff Langaae65a42014-05-26 12:43:44 -04001626 const gl::Caps &caps = context->getCaps();
1627
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001628 switch (target)
1629 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001630 case GL_TEXTURE_2D:
1631 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1632 static_cast<GLuint>(height) > caps.max2DTextureSize)
1633 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001634 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001635 return false;
1636 }
1637 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001638 case GL_TEXTURE_RECTANGLE_ANGLE:
1639 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1640 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1641 {
1642 context->handleError(InvalidValue());
1643 return false;
1644 }
1645 if (formatInfo.compressed)
1646 {
1647 context->handleError(InvalidEnum()
1648 << "Rectangle texture cannot have a compressed format.");
1649 return false;
1650 }
1651 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001652 case GL_TEXTURE_CUBE_MAP:
1653 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1654 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1655 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001656 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001657 return false;
1658 }
1659 break;
1660 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001661 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001662 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001663 }
1664
Geoff Langc0b9ef42014-07-02 10:02:37 -04001665 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001666 {
1667 if (!gl::isPow2(width) || !gl::isPow2(height))
1668 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001669 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001670 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001671 }
1672 }
1673
1674 switch (internalformat)
1675 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001676 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1677 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1678 if (!context->getExtensions().textureCompressionDXT1)
1679 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001680 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001681 return false;
1682 }
1683 break;
1684 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1685 if (!context->getExtensions().textureCompressionDXT3)
1686 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001687 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001688 return false;
1689 }
1690 break;
1691 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1692 if (!context->getExtensions().textureCompressionDXT5)
1693 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001694 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001695 return false;
1696 }
1697 break;
1698 case GL_ETC1_RGB8_OES:
1699 if (!context->getExtensions().compressedETC1RGB8Texture)
1700 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001701 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001702 return false;
1703 }
1704 break;
1705 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001706 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1707 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1708 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1709 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001710 if (!context->getExtensions().lossyETCDecode)
1711 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001712 context->handleError(InvalidEnum()
1713 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001714 return false;
1715 }
1716 break;
1717 case GL_RGBA32F_EXT:
1718 case GL_RGB32F_EXT:
1719 case GL_ALPHA32F_EXT:
1720 case GL_LUMINANCE32F_EXT:
1721 case GL_LUMINANCE_ALPHA32F_EXT:
1722 if (!context->getExtensions().textureFloat)
1723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001724 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001725 return false;
1726 }
1727 break;
1728 case GL_RGBA16F_EXT:
1729 case GL_RGB16F_EXT:
1730 case GL_ALPHA16F_EXT:
1731 case GL_LUMINANCE16F_EXT:
1732 case GL_LUMINANCE_ALPHA16F_EXT:
1733 if (!context->getExtensions().textureHalfFloat)
1734 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001735 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001736 return false;
1737 }
1738 break;
1739 case GL_R8_EXT:
1740 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001741 if (!context->getExtensions().textureRG)
1742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001743 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001744 return false;
1745 }
1746 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001747 case GL_R16F_EXT:
1748 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001749 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001751 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001752 return false;
1753 }
1754 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001755 case GL_R32F_EXT:
1756 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001757 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001759 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001760 return false;
1761 }
1762 break;
1763 case GL_DEPTH_COMPONENT16:
1764 case GL_DEPTH_COMPONENT32_OES:
1765 case GL_DEPTH24_STENCIL8_OES:
1766 if (!context->getExtensions().depthTextures)
1767 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001768 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 return false;
1770 }
1771 if (target != GL_TEXTURE_2D)
1772 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001773 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001774 return false;
1775 }
1776 // ANGLE_depth_texture only supports 1-level textures
1777 if (levels != 1)
1778 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001779 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001780 return false;
1781 }
1782 break;
1783 default:
1784 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001785 }
1786
Geoff Lang691e58c2014-12-19 17:03:25 -05001787 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001788 if (!texture || texture->id() == 0)
1789 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001790 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001791 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001792 }
1793
Geoff Lang69cce582015-09-17 13:20:36 -04001794 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001795 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001796 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001797 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001798 }
1799
1800 return true;
1801}
1802
He Yunchaoced53ae2016-11-29 15:00:51 +08001803bool ValidateDiscardFramebufferEXT(Context *context,
1804 GLenum target,
1805 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001806 const GLenum *attachments)
1807{
Jamie Madillc29968b2016-01-20 11:17:23 -05001808 if (!context->getExtensions().discardFramebuffer)
1809 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001810 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001811 return false;
1812 }
1813
Austin Kinross08332632015-05-05 13:35:47 -07001814 bool defaultFramebuffer = false;
1815
1816 switch (target)
1817 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001818 case GL_FRAMEBUFFER:
1819 defaultFramebuffer =
1820 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1821 break;
1822 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001823 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001824 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001825 }
1826
He Yunchaoced53ae2016-11-29 15:00:51 +08001827 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1828 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001829}
1830
Austin Kinrossbc781f32015-10-26 09:27:38 -07001831bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1832{
1833 if (!context->getExtensions().vertexArrayObject)
1834 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001835 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001836 return false;
1837 }
1838
1839 return ValidateBindVertexArrayBase(context, array);
1840}
1841
Jamie Madilld7576732017-08-26 18:49:50 -04001842bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001843{
1844 if (!context->getExtensions().vertexArrayObject)
1845 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001846 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001847 return false;
1848 }
1849
Olli Etuaho41997e72016-03-10 13:38:39 +02001850 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001851}
1852
Jamie Madilld7576732017-08-26 18:49:50 -04001853bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001854{
1855 if (!context->getExtensions().vertexArrayObject)
1856 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001857 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001858 return false;
1859 }
1860
Olli Etuaho41997e72016-03-10 13:38:39 +02001861 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001862}
1863
Jamie Madilld7576732017-08-26 18:49:50 -04001864bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001865{
1866 if (!context->getExtensions().vertexArrayObject)
1867 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001868 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001869 return false;
1870 }
1871
1872 return true;
1873}
Geoff Langc5629752015-12-07 16:29:04 -05001874
1875bool ValidateProgramBinaryOES(Context *context,
1876 GLuint program,
1877 GLenum binaryFormat,
1878 const void *binary,
1879 GLint length)
1880{
1881 if (!context->getExtensions().getProgramBinary)
1882 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001883 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001884 return false;
1885 }
1886
1887 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1888}
1889
1890bool ValidateGetProgramBinaryOES(Context *context,
1891 GLuint program,
1892 GLsizei bufSize,
1893 GLsizei *length,
1894 GLenum *binaryFormat,
1895 void *binary)
1896{
1897 if (!context->getExtensions().getProgramBinary)
1898 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001899 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001900 return false;
1901 }
1902
1903 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1904}
Geoff Lange102fee2015-12-10 11:23:30 -05001905
Geoff Lang70d0f492015-12-10 17:45:46 -05001906static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1907{
1908 switch (source)
1909 {
1910 case GL_DEBUG_SOURCE_API:
1911 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1912 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1913 case GL_DEBUG_SOURCE_OTHER:
1914 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1915 return !mustBeThirdPartyOrApplication;
1916
1917 case GL_DEBUG_SOURCE_THIRD_PARTY:
1918 case GL_DEBUG_SOURCE_APPLICATION:
1919 return true;
1920
1921 default:
1922 return false;
1923 }
1924}
1925
1926static bool ValidDebugType(GLenum type)
1927{
1928 switch (type)
1929 {
1930 case GL_DEBUG_TYPE_ERROR:
1931 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1932 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1933 case GL_DEBUG_TYPE_PERFORMANCE:
1934 case GL_DEBUG_TYPE_PORTABILITY:
1935 case GL_DEBUG_TYPE_OTHER:
1936 case GL_DEBUG_TYPE_MARKER:
1937 case GL_DEBUG_TYPE_PUSH_GROUP:
1938 case GL_DEBUG_TYPE_POP_GROUP:
1939 return true;
1940
1941 default:
1942 return false;
1943 }
1944}
1945
1946static bool ValidDebugSeverity(GLenum severity)
1947{
1948 switch (severity)
1949 {
1950 case GL_DEBUG_SEVERITY_HIGH:
1951 case GL_DEBUG_SEVERITY_MEDIUM:
1952 case GL_DEBUG_SEVERITY_LOW:
1953 case GL_DEBUG_SEVERITY_NOTIFICATION:
1954 return true;
1955
1956 default:
1957 return false;
1958 }
1959}
1960
Geoff Lange102fee2015-12-10 11:23:30 -05001961bool ValidateDebugMessageControlKHR(Context *context,
1962 GLenum source,
1963 GLenum type,
1964 GLenum severity,
1965 GLsizei count,
1966 const GLuint *ids,
1967 GLboolean enabled)
1968{
1969 if (!context->getExtensions().debug)
1970 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001971 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001972 return false;
1973 }
1974
Geoff Lang70d0f492015-12-10 17:45:46 -05001975 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1976 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001977 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001978 return false;
1979 }
1980
1981 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1982 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001983 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001984 return false;
1985 }
1986
1987 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1988 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001989 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001990 return false;
1991 }
1992
1993 if (count > 0)
1994 {
1995 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1996 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001997 context->handleError(
1998 InvalidOperation()
1999 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002000 return false;
2001 }
2002
2003 if (severity != GL_DONT_CARE)
2004 {
Jamie Madill437fa652016-05-03 15:13:24 -04002005 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002006 InvalidOperation()
2007 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002008 return false;
2009 }
2010 }
2011
Geoff Lange102fee2015-12-10 11:23:30 -05002012 return true;
2013}
2014
2015bool ValidateDebugMessageInsertKHR(Context *context,
2016 GLenum source,
2017 GLenum type,
2018 GLuint id,
2019 GLenum severity,
2020 GLsizei length,
2021 const GLchar *buf)
2022{
2023 if (!context->getExtensions().debug)
2024 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002025 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002026 return false;
2027 }
2028
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002029 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002030 {
2031 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2032 // not generate an error.
2033 return false;
2034 }
2035
2036 if (!ValidDebugSeverity(severity))
2037 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002038 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002039 return false;
2040 }
2041
2042 if (!ValidDebugType(type))
2043 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002044 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002045 return false;
2046 }
2047
2048 if (!ValidDebugSource(source, true))
2049 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002051 return false;
2052 }
2053
2054 size_t messageLength = (length < 0) ? strlen(buf) : length;
2055 if (messageLength > context->getExtensions().maxDebugMessageLength)
2056 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002057 context->handleError(InvalidValue()
2058 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002059 return false;
2060 }
2061
Geoff Lange102fee2015-12-10 11:23:30 -05002062 return true;
2063}
2064
2065bool ValidateDebugMessageCallbackKHR(Context *context,
2066 GLDEBUGPROCKHR callback,
2067 const void *userParam)
2068{
2069 if (!context->getExtensions().debug)
2070 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002071 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002072 return false;
2073 }
2074
Geoff Lange102fee2015-12-10 11:23:30 -05002075 return true;
2076}
2077
2078bool ValidateGetDebugMessageLogKHR(Context *context,
2079 GLuint count,
2080 GLsizei bufSize,
2081 GLenum *sources,
2082 GLenum *types,
2083 GLuint *ids,
2084 GLenum *severities,
2085 GLsizei *lengths,
2086 GLchar *messageLog)
2087{
2088 if (!context->getExtensions().debug)
2089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002090 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002091 return false;
2092 }
2093
Geoff Lang70d0f492015-12-10 17:45:46 -05002094 if (bufSize < 0 && messageLog != nullptr)
2095 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002096 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002097 return false;
2098 }
2099
Geoff Lange102fee2015-12-10 11:23:30 -05002100 return true;
2101}
2102
2103bool ValidatePushDebugGroupKHR(Context *context,
2104 GLenum source,
2105 GLuint id,
2106 GLsizei length,
2107 const GLchar *message)
2108{
2109 if (!context->getExtensions().debug)
2110 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002111 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002112 return false;
2113 }
2114
Geoff Lang70d0f492015-12-10 17:45:46 -05002115 if (!ValidDebugSource(source, true))
2116 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002117 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002118 return false;
2119 }
2120
2121 size_t messageLength = (length < 0) ? strlen(message) : length;
2122 if (messageLength > context->getExtensions().maxDebugMessageLength)
2123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002124 context->handleError(InvalidValue()
2125 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 return false;
2127 }
2128
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002129 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002130 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002132 context
2133 ->handleError(StackOverflow()
2134 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002135 return false;
2136 }
2137
Geoff Lange102fee2015-12-10 11:23:30 -05002138 return true;
2139}
2140
2141bool ValidatePopDebugGroupKHR(Context *context)
2142{
2143 if (!context->getExtensions().debug)
2144 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002145 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002146 return false;
2147 }
2148
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002149 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002150 if (currentStackSize <= 1)
2151 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002152 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002153 return false;
2154 }
2155
2156 return true;
2157}
2158
2159static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2160{
2161 switch (identifier)
2162 {
2163 case GL_BUFFER:
2164 if (context->getBuffer(name) == nullptr)
2165 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002166 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002167 return false;
2168 }
2169 return true;
2170
2171 case GL_SHADER:
2172 if (context->getShader(name) == nullptr)
2173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002174 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002175 return false;
2176 }
2177 return true;
2178
2179 case GL_PROGRAM:
2180 if (context->getProgram(name) == nullptr)
2181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002182 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002183 return false;
2184 }
2185 return true;
2186
2187 case GL_VERTEX_ARRAY:
2188 if (context->getVertexArray(name) == nullptr)
2189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002190 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002191 return false;
2192 }
2193 return true;
2194
2195 case GL_QUERY:
2196 if (context->getQuery(name) == nullptr)
2197 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002198 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 return false;
2200 }
2201 return true;
2202
2203 case GL_TRANSFORM_FEEDBACK:
2204 if (context->getTransformFeedback(name) == nullptr)
2205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002206 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002207 return false;
2208 }
2209 return true;
2210
2211 case GL_SAMPLER:
2212 if (context->getSampler(name) == nullptr)
2213 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002214 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002215 return false;
2216 }
2217 return true;
2218
2219 case GL_TEXTURE:
2220 if (context->getTexture(name) == nullptr)
2221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002222 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002223 return false;
2224 }
2225 return true;
2226
2227 case GL_RENDERBUFFER:
2228 if (context->getRenderbuffer(name) == nullptr)
2229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002230 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 return false;
2232 }
2233 return true;
2234
2235 case GL_FRAMEBUFFER:
2236 if (context->getFramebuffer(name) == nullptr)
2237 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002238 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002239 return false;
2240 }
2241 return true;
2242
2243 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002244 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002245 return false;
2246 }
Geoff Lange102fee2015-12-10 11:23:30 -05002247}
2248
Martin Radev9d901792016-07-15 15:58:58 +03002249static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2250{
2251 size_t labelLength = 0;
2252
2253 if (length < 0)
2254 {
2255 if (label != nullptr)
2256 {
2257 labelLength = strlen(label);
2258 }
2259 }
2260 else
2261 {
2262 labelLength = static_cast<size_t>(length);
2263 }
2264
2265 if (labelLength > context->getExtensions().maxLabelLength)
2266 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002267 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002268 return false;
2269 }
2270
2271 return true;
2272}
2273
Geoff Lange102fee2015-12-10 11:23:30 -05002274bool ValidateObjectLabelKHR(Context *context,
2275 GLenum identifier,
2276 GLuint name,
2277 GLsizei length,
2278 const GLchar *label)
2279{
2280 if (!context->getExtensions().debug)
2281 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002282 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002283 return false;
2284 }
2285
Geoff Lang70d0f492015-12-10 17:45:46 -05002286 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2287 {
2288 return false;
2289 }
2290
Martin Radev9d901792016-07-15 15:58:58 +03002291 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002292 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002293 return false;
2294 }
2295
Geoff Lange102fee2015-12-10 11:23:30 -05002296 return true;
2297}
2298
2299bool ValidateGetObjectLabelKHR(Context *context,
2300 GLenum identifier,
2301 GLuint name,
2302 GLsizei bufSize,
2303 GLsizei *length,
2304 GLchar *label)
2305{
2306 if (!context->getExtensions().debug)
2307 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002308 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002309 return false;
2310 }
2311
Geoff Lang70d0f492015-12-10 17:45:46 -05002312 if (bufSize < 0)
2313 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002314 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002315 return false;
2316 }
2317
2318 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2319 {
2320 return false;
2321 }
2322
Martin Radev9d901792016-07-15 15:58:58 +03002323 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002324}
2325
2326static bool ValidateObjectPtrName(Context *context, const void *ptr)
2327{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002328 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002329 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002330 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002331 return false;
2332 }
2333
Geoff Lange102fee2015-12-10 11:23:30 -05002334 return true;
2335}
2336
2337bool ValidateObjectPtrLabelKHR(Context *context,
2338 const void *ptr,
2339 GLsizei length,
2340 const GLchar *label)
2341{
2342 if (!context->getExtensions().debug)
2343 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002345 return false;
2346 }
2347
Geoff Lang70d0f492015-12-10 17:45:46 -05002348 if (!ValidateObjectPtrName(context, ptr))
2349 {
2350 return false;
2351 }
2352
Martin Radev9d901792016-07-15 15:58:58 +03002353 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002354 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002355 return false;
2356 }
2357
Geoff Lange102fee2015-12-10 11:23:30 -05002358 return true;
2359}
2360
2361bool ValidateGetObjectPtrLabelKHR(Context *context,
2362 const void *ptr,
2363 GLsizei bufSize,
2364 GLsizei *length,
2365 GLchar *label)
2366{
2367 if (!context->getExtensions().debug)
2368 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002369 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002370 return false;
2371 }
2372
Geoff Lang70d0f492015-12-10 17:45:46 -05002373 if (bufSize < 0)
2374 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002375 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002376 return false;
2377 }
2378
2379 if (!ValidateObjectPtrName(context, ptr))
2380 {
2381 return false;
2382 }
2383
Martin Radev9d901792016-07-15 15:58:58 +03002384 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002385}
2386
2387bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2388{
2389 if (!context->getExtensions().debug)
2390 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002391 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002392 return false;
2393 }
2394
Geoff Lang70d0f492015-12-10 17:45:46 -05002395 // TODO: represent this in Context::getQueryParameterInfo.
2396 switch (pname)
2397 {
2398 case GL_DEBUG_CALLBACK_FUNCTION:
2399 case GL_DEBUG_CALLBACK_USER_PARAM:
2400 break;
2401
2402 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002403 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002404 return false;
2405 }
2406
Geoff Lange102fee2015-12-10 11:23:30 -05002407 return true;
2408}
Jamie Madillc29968b2016-01-20 11:17:23 -05002409
2410bool ValidateBlitFramebufferANGLE(Context *context,
2411 GLint srcX0,
2412 GLint srcY0,
2413 GLint srcX1,
2414 GLint srcY1,
2415 GLint dstX0,
2416 GLint dstY0,
2417 GLint dstX1,
2418 GLint dstY1,
2419 GLbitfield mask,
2420 GLenum filter)
2421{
2422 if (!context->getExtensions().framebufferBlit)
2423 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002424 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002425 return false;
2426 }
2427
2428 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2429 {
2430 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002431 context->handleError(InvalidOperation() << "Scaling and flipping in "
2432 "BlitFramebufferANGLE not supported by this "
2433 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002434 return false;
2435 }
2436
2437 if (filter == GL_LINEAR)
2438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002439 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002440 return false;
2441 }
2442
Jamie Madill51f40ec2016-06-15 14:06:00 -04002443 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2444 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002445
2446 if (mask & GL_COLOR_BUFFER_BIT)
2447 {
2448 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2449 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2450
2451 if (readColorAttachment && drawColorAttachment)
2452 {
2453 if (!(readColorAttachment->type() == GL_TEXTURE &&
2454 readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2455 readColorAttachment->type() != GL_RENDERBUFFER &&
2456 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002458 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002459 return false;
2460 }
2461
Geoff Langa15472a2015-08-11 11:48:03 -04002462 for (size_t drawbufferIdx = 0;
2463 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002464 {
Geoff Langa15472a2015-08-11 11:48:03 -04002465 const FramebufferAttachment *attachment =
2466 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2467 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002468 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002469 if (!(attachment->type() == GL_TEXTURE &&
2470 attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2471 attachment->type() != GL_RENDERBUFFER &&
2472 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2473 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002474 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002475 return false;
2476 }
2477
2478 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002479 if (!Format::EquivalentForBlit(attachment->getFormat(),
2480 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002482 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 return false;
2484 }
2485 }
2486 }
2487
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002488 if (readFramebuffer->getSamples(context) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002489 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2490 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2491 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002492 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002493 return false;
2494 }
2495 }
2496 }
2497
2498 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2499 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2500 for (size_t i = 0; i < 2; i++)
2501 {
2502 if (mask & masks[i])
2503 {
2504 const FramebufferAttachment *readBuffer =
2505 readFramebuffer->getAttachment(attachments[i]);
2506 const FramebufferAttachment *drawBuffer =
2507 drawFramebuffer->getAttachment(attachments[i]);
2508
2509 if (readBuffer && drawBuffer)
2510 {
2511 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2512 dstX0, dstY0, dstX1, dstY1))
2513 {
2514 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002515 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2516 "stencil blits are supported by "
2517 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002518 return false;
2519 }
2520
2521 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2522 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002523 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002524 return false;
2525 }
2526 }
2527 }
2528 }
2529
2530 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2531 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002532}
Jamie Madillc29968b2016-01-20 11:17:23 -05002533
2534bool ValidateClear(ValidationContext *context, GLbitfield mask)
2535{
Jamie Madill51f40ec2016-06-15 14:06:00 -04002536 auto fbo = context->getGLState().getDrawFramebuffer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002537 if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002539 context->handleError(InvalidFramebufferOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002540 return false;
2541 }
2542
2543 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2544 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002545 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002546 return false;
2547 }
2548
Geoff Lang76e65652017-03-27 14:58:02 -04002549 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2550 {
2551 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2552 GL_SIGNED_NORMALIZED};
2553
Corentin Wallez59c41592017-07-11 13:19:54 -04002554 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002555 drawBufferIdx++)
2556 {
2557 if (!ValidateWebGLFramebufferAttachmentClearType(
2558 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2559 {
2560 return false;
2561 }
2562 }
2563 }
2564
Jamie Madillc29968b2016-01-20 11:17:23 -05002565 return true;
2566}
2567
2568bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
2569{
2570 if (!context->getExtensions().drawBuffers)
2571 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002572 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002573 return false;
2574 }
2575
2576 return ValidateDrawBuffersBase(context, n, bufs);
2577}
2578
Jamie Madill73a84962016-02-12 09:27:23 -05002579bool ValidateTexImage2D(Context *context,
2580 GLenum target,
2581 GLint level,
2582 GLint internalformat,
2583 GLsizei width,
2584 GLsizei height,
2585 GLint border,
2586 GLenum format,
2587 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002588 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002589{
Martin Radev1be913c2016-07-11 17:59:16 +03002590 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002591 {
2592 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002593 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002594 }
2595
Martin Radev1be913c2016-07-11 17:59:16 +03002596 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002597 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002598 0, 0, width, height, 1, border, format, type, -1,
2599 pixels);
2600}
2601
2602bool ValidateTexImage2DRobust(Context *context,
2603 GLenum target,
2604 GLint level,
2605 GLint internalformat,
2606 GLsizei width,
2607 GLsizei height,
2608 GLint border,
2609 GLenum format,
2610 GLenum type,
2611 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002612 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002613{
2614 if (!ValidateRobustEntryPoint(context, bufSize))
2615 {
2616 return false;
2617 }
2618
2619 if (context->getClientMajorVersion() < 3)
2620 {
2621 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2622 0, 0, width, height, border, format, type, bufSize,
2623 pixels);
2624 }
2625
2626 ASSERT(context->getClientMajorVersion() >= 3);
2627 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2628 0, 0, width, height, 1, border, format, type, bufSize,
2629 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002630}
2631
2632bool ValidateTexSubImage2D(Context *context,
2633 GLenum target,
2634 GLint level,
2635 GLint xoffset,
2636 GLint yoffset,
2637 GLsizei width,
2638 GLsizei height,
2639 GLenum format,
2640 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002641 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002642{
2643
Martin Radev1be913c2016-07-11 17:59:16 +03002644 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002645 {
2646 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002647 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002648 }
2649
Martin Radev1be913c2016-07-11 17:59:16 +03002650 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002651 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002652 yoffset, 0, width, height, 1, 0, format, type, -1,
2653 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002654}
2655
Geoff Langc52f6f12016-10-14 10:18:00 -04002656bool ValidateTexSubImage2DRobustANGLE(Context *context,
2657 GLenum target,
2658 GLint level,
2659 GLint xoffset,
2660 GLint yoffset,
2661 GLsizei width,
2662 GLsizei height,
2663 GLenum format,
2664 GLenum type,
2665 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002666 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002667{
2668 if (!ValidateRobustEntryPoint(context, bufSize))
2669 {
2670 return false;
2671 }
2672
2673 if (context->getClientMajorVersion() < 3)
2674 {
2675 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2676 yoffset, width, height, 0, format, type, bufSize,
2677 pixels);
2678 }
2679
2680 ASSERT(context->getClientMajorVersion() >= 3);
2681 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2682 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2683 pixels);
2684}
2685
Jamie Madill73a84962016-02-12 09:27:23 -05002686bool ValidateCompressedTexImage2D(Context *context,
2687 GLenum target,
2688 GLint level,
2689 GLenum internalformat,
2690 GLsizei width,
2691 GLsizei height,
2692 GLint border,
2693 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002694 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002695{
Martin Radev1be913c2016-07-11 17:59:16 +03002696 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002697 {
2698 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002699 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002700 {
2701 return false;
2702 }
2703 }
2704 else
2705 {
Martin Radev1be913c2016-07-11 17:59:16 +03002706 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002707 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002708 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002709 data))
2710 {
2711 return false;
2712 }
2713 }
2714
Geoff Langca271392017-04-05 12:30:00 -04002715 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madill513558d2016-06-02 13:04:11 -04002716 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07002717 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002718 if (blockSizeOrErr.isError())
2719 {
2720 context->handleError(blockSizeOrErr.getError());
2721 return false;
2722 }
2723
2724 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002725 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002726 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002727 return false;
2728 }
2729
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002730 if (target == GL_TEXTURE_RECTANGLE_ANGLE)
2731 {
2732 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2733 return false;
2734 }
2735
Jamie Madill73a84962016-02-12 09:27:23 -05002736 return true;
2737}
2738
Corentin Wallezb2931602017-04-11 15:58:57 -04002739bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
2740 GLenum target,
2741 GLint level,
2742 GLenum internalformat,
2743 GLsizei width,
2744 GLsizei height,
2745 GLint border,
2746 GLsizei imageSize,
2747 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002748 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002749{
2750 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2751 {
2752 return false;
2753 }
2754
2755 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2756 border, imageSize, data);
2757}
2758bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
2759 GLenum target,
2760 GLint level,
2761 GLint xoffset,
2762 GLint yoffset,
2763 GLsizei width,
2764 GLsizei height,
2765 GLenum format,
2766 GLsizei imageSize,
2767 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002768 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002769{
2770 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2771 {
2772 return false;
2773 }
2774
2775 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2776 format, imageSize, data);
2777}
2778
Jamie Madill73a84962016-02-12 09:27:23 -05002779bool ValidateCompressedTexSubImage2D(Context *context,
2780 GLenum target,
2781 GLint level,
2782 GLint xoffset,
2783 GLint yoffset,
2784 GLsizei width,
2785 GLsizei height,
2786 GLenum format,
2787 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002788 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002789{
Martin Radev1be913c2016-07-11 17:59:16 +03002790 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002791 {
2792 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002793 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002794 {
2795 return false;
2796 }
2797 }
2798 else
2799 {
Martin Radev1be913c2016-07-11 17:59:16 +03002800 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002801 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002802 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002803 data))
2804 {
2805 return false;
2806 }
2807 }
2808
Geoff Langca271392017-04-05 12:30:00 -04002809 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madill513558d2016-06-02 13:04:11 -04002810 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07002811 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002812 if (blockSizeOrErr.isError())
2813 {
2814 context->handleError(blockSizeOrErr.getError());
2815 return false;
2816 }
2817
2818 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002819 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002820 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002821 return false;
2822 }
2823
2824 return true;
2825}
2826
Corentin Wallez336129f2017-10-17 15:55:40 -04002827bool ValidateGetBufferPointervOES(Context *context,
2828 BufferBinding target,
2829 GLenum pname,
2830 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002831{
Geoff Lang496c02d2016-10-20 11:38:11 -07002832 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002833}
2834
Corentin Wallez336129f2017-10-17 15:55:40 -04002835bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002836{
2837 if (!context->getExtensions().mapBuffer)
2838 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002839 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002840 return false;
2841 }
2842
Corentin Wallez336129f2017-10-17 15:55:40 -04002843 if (!ValidBufferType(context, target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002844 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002845 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002846 return false;
2847 }
2848
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002849 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002850
2851 if (buffer == nullptr)
2852 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002853 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002854 return false;
2855 }
2856
2857 if (access != GL_WRITE_ONLY_OES)
2858 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002859 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002860 return false;
2861 }
2862
2863 if (buffer->isMapped())
2864 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002865 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002866 return false;
2867 }
2868
Geoff Lang79f71042017-08-14 16:43:43 -04002869 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002870}
2871
Corentin Wallez336129f2017-10-17 15:55:40 -04002872bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002873{
2874 if (!context->getExtensions().mapBuffer)
2875 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002876 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002877 return false;
2878 }
2879
2880 return ValidateUnmapBufferBase(context, target);
2881}
2882
2883bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002884 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002885 GLintptr offset,
2886 GLsizeiptr length,
2887 GLbitfield access)
2888{
2889 if (!context->getExtensions().mapBufferRange)
2890 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002891 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002892 return false;
2893 }
2894
2895 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2896}
2897
Corentin Wallez336129f2017-10-17 15:55:40 -04002898bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002899{
2900 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2901 ASSERT(buffer != nullptr);
2902
2903 // Check if this buffer is currently being used as a transform feedback output buffer
2904 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2905 if (transformFeedback != nullptr && transformFeedback->isActive())
2906 {
2907 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2908 {
2909 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2910 if (transformFeedbackBuffer.get() == buffer)
2911 {
2912 context->handleError(InvalidOperation()
2913 << "Buffer is currently bound for transform feedback.");
2914 return false;
2915 }
2916 }
2917 }
2918
2919 return true;
2920}
2921
Olli Etuaho4f667482016-03-30 15:56:35 +03002922bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002923 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002924 GLintptr offset,
2925 GLsizeiptr length)
2926{
2927 if (!context->getExtensions().mapBufferRange)
2928 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002929 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002930 return false;
2931 }
2932
2933 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2934}
2935
Ian Ewell54f87462016-03-10 13:47:21 -05002936bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
2937{
2938 Texture *textureObject = context->getTexture(texture);
2939 if (textureObject && textureObject->getTarget() != target && texture != 0)
2940 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002941 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002942 return false;
2943 }
2944
Geoff Langf41a7152016-09-19 15:11:17 -04002945 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2946 !context->isTextureGenerated(texture))
2947 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002948 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002949 return false;
2950 }
2951
Ian Ewell54f87462016-03-10 13:47:21 -05002952 switch (target)
2953 {
2954 case GL_TEXTURE_2D:
2955 case GL_TEXTURE_CUBE_MAP:
2956 break;
2957
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002958 case GL_TEXTURE_RECTANGLE_ANGLE:
2959 if (!context->getExtensions().textureRectangle)
2960 {
2961 context->handleError(InvalidEnum()
2962 << "Context does not support GL_ANGLE_texture_rectangle");
2963 return false;
2964 }
2965 break;
2966
Ian Ewell54f87462016-03-10 13:47:21 -05002967 case GL_TEXTURE_3D:
2968 case GL_TEXTURE_2D_ARRAY:
Martin Radev1be913c2016-07-11 17:59:16 +03002969 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002970 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002971 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002972 return false;
2973 }
2974 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002975
2976 case GL_TEXTURE_2D_MULTISAMPLE:
2977 if (context->getClientVersion() < Version(3, 1))
2978 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002979 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002980 return false;
2981 }
Geoff Lang3b573612016-10-31 14:08:10 -04002982 break;
2983
Ian Ewell54f87462016-03-10 13:47:21 -05002984 case GL_TEXTURE_EXTERNAL_OES:
Geoff Langb66a9092016-05-16 15:59:14 -04002985 if (!context->getExtensions().eglImageExternal &&
2986 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05002987 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002988 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05002989 return false;
2990 }
2991 break;
2992 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002993 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05002994 return false;
2995 }
2996
2997 return true;
2998}
2999
Geoff Langd8605522016-04-13 10:19:12 -04003000bool ValidateBindUniformLocationCHROMIUM(Context *context,
3001 GLuint program,
3002 GLint location,
3003 const GLchar *name)
3004{
3005 if (!context->getExtensions().bindUniformLocation)
3006 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003007 context->handleError(InvalidOperation()
3008 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003009 return false;
3010 }
3011
3012 Program *programObject = GetValidProgram(context, program);
3013 if (!programObject)
3014 {
3015 return false;
3016 }
3017
3018 if (location < 0)
3019 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003020 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003021 return false;
3022 }
3023
3024 const Caps &caps = context->getCaps();
3025 if (static_cast<size_t>(location) >=
3026 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3027 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003028 context->handleError(InvalidValue() << "Location must be less than "
3029 "(MAX_VERTEX_UNIFORM_VECTORS + "
3030 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003031 return false;
3032 }
3033
Geoff Langfc32e8b2017-05-31 14:16:59 -04003034 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3035 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003036 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003037 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003038 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003039 return false;
3040 }
3041
Geoff Langd8605522016-04-13 10:19:12 -04003042 if (strncmp(name, "gl_", 3) == 0)
3043 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003044 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003045 return false;
3046 }
3047
3048 return true;
3049}
3050
Jamie Madille2e406c2016-06-02 13:04:10 -04003051bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003052{
3053 if (!context->getExtensions().framebufferMixedSamples)
3054 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003055 context->handleError(InvalidOperation()
3056 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003057 return false;
3058 }
3059 switch (components)
3060 {
3061 case GL_RGB:
3062 case GL_RGBA:
3063 case GL_ALPHA:
3064 case GL_NONE:
3065 break;
3066 default:
3067 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003068 InvalidEnum()
3069 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003070 return false;
3071 }
3072
3073 return true;
3074}
3075
Sami Väisänene45e53b2016-05-25 10:36:04 +03003076// CHROMIUM_path_rendering
3077
3078bool ValidateMatrix(Context *context, GLenum matrixMode, const GLfloat *matrix)
3079{
3080 if (!context->getExtensions().pathRendering)
3081 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003082 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003083 return false;
3084 }
3085 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
3086 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003087 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003088 return false;
3089 }
3090 if (matrix == nullptr)
3091 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003092 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003093 return false;
3094 }
3095 return true;
3096}
3097
3098bool ValidateMatrixMode(Context *context, GLenum matrixMode)
3099{
3100 if (!context->getExtensions().pathRendering)
3101 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003102 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003103 return false;
3104 }
3105 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
3106 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003107 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003108 return false;
3109 }
3110 return true;
3111}
3112
3113bool ValidateGenPaths(Context *context, GLsizei range)
3114{
3115 if (!context->getExtensions().pathRendering)
3116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003117 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003118 return false;
3119 }
3120
3121 // range = 0 is undefined in NV_path_rendering.
3122 // we add stricter semantic check here and require a non zero positive range.
3123 if (range <= 0)
3124 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003125 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003126 return false;
3127 }
3128
3129 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3130 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003131 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003132 return false;
3133 }
3134
3135 return true;
3136}
3137
3138bool ValidateDeletePaths(Context *context, GLuint path, GLsizei range)
3139{
3140 if (!context->getExtensions().pathRendering)
3141 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003142 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003143 return false;
3144 }
3145
3146 // range = 0 is undefined in NV_path_rendering.
3147 // we add stricter semantic check here and require a non zero positive range.
3148 if (range <= 0)
3149 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003150 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003151 return false;
3152 }
3153
3154 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3155 checkedRange += range;
3156
3157 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003160 return false;
3161 }
3162 return true;
3163}
3164
3165bool ValidatePathCommands(Context *context,
3166 GLuint path,
3167 GLsizei numCommands,
3168 const GLubyte *commands,
3169 GLsizei numCoords,
3170 GLenum coordType,
3171 const void *coords)
3172{
3173 if (!context->getExtensions().pathRendering)
3174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003175 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003176 return false;
3177 }
3178 if (!context->hasPath(path))
3179 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003180 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181 return false;
3182 }
3183
3184 if (numCommands < 0)
3185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003186 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003187 return false;
3188 }
3189 else if (numCommands > 0)
3190 {
3191 if (!commands)
3192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003193 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003194 return false;
3195 }
3196 }
3197
3198 if (numCoords < 0)
3199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003200 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003201 return false;
3202 }
3203 else if (numCoords > 0)
3204 {
3205 if (!coords)
3206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003207 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003208 return false;
3209 }
3210 }
3211
3212 std::uint32_t coordTypeSize = 0;
3213 switch (coordType)
3214 {
3215 case GL_BYTE:
3216 coordTypeSize = sizeof(GLbyte);
3217 break;
3218
3219 case GL_UNSIGNED_BYTE:
3220 coordTypeSize = sizeof(GLubyte);
3221 break;
3222
3223 case GL_SHORT:
3224 coordTypeSize = sizeof(GLshort);
3225 break;
3226
3227 case GL_UNSIGNED_SHORT:
3228 coordTypeSize = sizeof(GLushort);
3229 break;
3230
3231 case GL_FLOAT:
3232 coordTypeSize = sizeof(GLfloat);
3233 break;
3234
3235 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003236 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003237 return false;
3238 }
3239
3240 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3241 checkedSize += (coordTypeSize * numCoords);
3242 if (!checkedSize.IsValid())
3243 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003244 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003245 return false;
3246 }
3247
3248 // early return skips command data validation when it doesn't exist.
3249 if (!commands)
3250 return true;
3251
3252 GLsizei expectedNumCoords = 0;
3253 for (GLsizei i = 0; i < numCommands; ++i)
3254 {
3255 switch (commands[i])
3256 {
3257 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3258 break;
3259 case GL_MOVE_TO_CHROMIUM:
3260 case GL_LINE_TO_CHROMIUM:
3261 expectedNumCoords += 2;
3262 break;
3263 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3264 expectedNumCoords += 4;
3265 break;
3266 case GL_CUBIC_CURVE_TO_CHROMIUM:
3267 expectedNumCoords += 6;
3268 break;
3269 case GL_CONIC_CURVE_TO_CHROMIUM:
3270 expectedNumCoords += 5;
3271 break;
3272 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003273 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003274 return false;
3275 }
3276 }
3277 if (expectedNumCoords != numCoords)
3278 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003279 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280 return false;
3281 }
3282
3283 return true;
3284}
3285
3286bool ValidateSetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat value)
3287{
3288 if (!context->getExtensions().pathRendering)
3289 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003290 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003291 return false;
3292 }
3293 if (!context->hasPath(path))
3294 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003296 return false;
3297 }
3298
3299 switch (pname)
3300 {
3301 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3302 if (value < 0.0f)
3303 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003304 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003305 return false;
3306 }
3307 break;
3308 case GL_PATH_END_CAPS_CHROMIUM:
3309 switch (static_cast<GLenum>(value))
3310 {
3311 case GL_FLAT_CHROMIUM:
3312 case GL_SQUARE_CHROMIUM:
3313 case GL_ROUND_CHROMIUM:
3314 break;
3315 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003316 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317 return false;
3318 }
3319 break;
3320 case GL_PATH_JOIN_STYLE_CHROMIUM:
3321 switch (static_cast<GLenum>(value))
3322 {
3323 case GL_MITER_REVERT_CHROMIUM:
3324 case GL_BEVEL_CHROMIUM:
3325 case GL_ROUND_CHROMIUM:
3326 break;
3327 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003328 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003329 return false;
3330 }
3331 case GL_PATH_MITER_LIMIT_CHROMIUM:
3332 if (value < 0.0f)
3333 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003334 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003335 return false;
3336 }
3337 break;
3338
3339 case GL_PATH_STROKE_BOUND_CHROMIUM:
3340 // no errors, only clamping.
3341 break;
3342
3343 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003344 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003345 return false;
3346 }
3347 return true;
3348}
3349
3350bool ValidateGetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat *value)
3351{
3352 if (!context->getExtensions().pathRendering)
3353 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003354 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003355 return false;
3356 }
3357
3358 if (!context->hasPath(path))
3359 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003360 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003361 return false;
3362 }
3363 if (!value)
3364 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003365 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003366 return false;
3367 }
3368
3369 switch (pname)
3370 {
3371 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3372 case GL_PATH_END_CAPS_CHROMIUM:
3373 case GL_PATH_JOIN_STYLE_CHROMIUM:
3374 case GL_PATH_MITER_LIMIT_CHROMIUM:
3375 case GL_PATH_STROKE_BOUND_CHROMIUM:
3376 break;
3377
3378 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003379 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003380 return false;
3381 }
3382
3383 return true;
3384}
3385
3386bool ValidatePathStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
3387{
3388 if (!context->getExtensions().pathRendering)
3389 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003390 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003391 return false;
3392 }
3393
3394 switch (func)
3395 {
3396 case GL_NEVER:
3397 case GL_ALWAYS:
3398 case GL_LESS:
3399 case GL_LEQUAL:
3400 case GL_EQUAL:
3401 case GL_GEQUAL:
3402 case GL_GREATER:
3403 case GL_NOTEQUAL:
3404 break;
3405 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003406 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003407 return false;
3408 }
3409
3410 return true;
3411}
3412
3413// Note that the spec specifies that for the path drawing commands
3414// if the path object is not an existing path object the command
3415// does nothing and no error is generated.
3416// However if the path object exists but has not been specified any
3417// commands then an error is generated.
3418
3419bool ValidateStencilFillPath(Context *context, GLuint path, GLenum fillMode, GLuint mask)
3420{
3421 if (!context->getExtensions().pathRendering)
3422 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003423 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003424 return false;
3425 }
3426 if (context->hasPath(path) && !context->hasPathData(path))
3427 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003428 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003429 return false;
3430 }
3431
3432 switch (fillMode)
3433 {
3434 case GL_COUNT_UP_CHROMIUM:
3435 case GL_COUNT_DOWN_CHROMIUM:
3436 break;
3437 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003438 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003439 return false;
3440 }
3441
3442 if (!isPow2(mask + 1))
3443 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003444 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003445 return false;
3446 }
3447
3448 return true;
3449}
3450
3451bool ValidateStencilStrokePath(Context *context, GLuint path, GLint reference, GLuint mask)
3452{
3453 if (!context->getExtensions().pathRendering)
3454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003455 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003456 return false;
3457 }
3458 if (context->hasPath(path) && !context->hasPathData(path))
3459 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003460 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003461 return false;
3462 }
3463
3464 return true;
3465}
3466
3467bool ValidateCoverPath(Context *context, GLuint path, GLenum coverMode)
3468{
3469 if (!context->getExtensions().pathRendering)
3470 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003471 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003472 return false;
3473 }
3474 if (context->hasPath(path) && !context->hasPathData(path))
3475 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003477 return false;
3478 }
3479
3480 switch (coverMode)
3481 {
3482 case GL_CONVEX_HULL_CHROMIUM:
3483 case GL_BOUNDING_BOX_CHROMIUM:
3484 break;
3485 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003486 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003487 return false;
3488 }
3489 return true;
3490}
3491
3492bool ValidateStencilThenCoverFillPath(Context *context,
3493 GLuint path,
3494 GLenum fillMode,
3495 GLuint mask,
3496 GLenum coverMode)
3497{
3498 return ValidateStencilFillPath(context, path, fillMode, mask) &&
3499 ValidateCoverPath(context, path, coverMode);
3500}
3501
3502bool ValidateStencilThenCoverStrokePath(Context *context,
3503 GLuint path,
3504 GLint reference,
3505 GLuint mask,
3506 GLenum coverMode)
3507{
3508 return ValidateStencilStrokePath(context, path, reference, mask) &&
3509 ValidateCoverPath(context, path, coverMode);
3510}
3511
3512bool ValidateIsPath(Context *context)
3513{
3514 if (!context->getExtensions().pathRendering)
3515 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003516 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003517 return false;
3518 }
3519 return true;
3520}
3521
Sami Väisänend59ca052016-06-21 16:10:00 +03003522bool ValidateCoverFillPathInstanced(Context *context,
3523 GLsizei numPaths,
3524 GLenum pathNameType,
3525 const void *paths,
3526 GLuint pathBase,
3527 GLenum coverMode,
3528 GLenum transformType,
3529 const GLfloat *transformValues)
3530{
3531 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3532 transformType, transformValues))
3533 return false;
3534
3535 switch (coverMode)
3536 {
3537 case GL_CONVEX_HULL_CHROMIUM:
3538 case GL_BOUNDING_BOX_CHROMIUM:
3539 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3540 break;
3541 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003542 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003543 return false;
3544 }
3545
3546 return true;
3547}
3548
3549bool ValidateCoverStrokePathInstanced(Context *context,
3550 GLsizei numPaths,
3551 GLenum pathNameType,
3552 const void *paths,
3553 GLuint pathBase,
3554 GLenum coverMode,
3555 GLenum transformType,
3556 const GLfloat *transformValues)
3557{
3558 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3559 transformType, transformValues))
3560 return false;
3561
3562 switch (coverMode)
3563 {
3564 case GL_CONVEX_HULL_CHROMIUM:
3565 case GL_BOUNDING_BOX_CHROMIUM:
3566 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3567 break;
3568 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003569 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003570 return false;
3571 }
3572
3573 return true;
3574}
3575
3576bool ValidateStencilFillPathInstanced(Context *context,
3577 GLsizei numPaths,
3578 GLenum pathNameType,
3579 const void *paths,
3580 GLuint pathBase,
3581 GLenum fillMode,
3582 GLuint mask,
3583 GLenum transformType,
3584 const GLfloat *transformValues)
3585{
3586
3587 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3588 transformType, transformValues))
3589 return false;
3590
3591 switch (fillMode)
3592 {
3593 case GL_COUNT_UP_CHROMIUM:
3594 case GL_COUNT_DOWN_CHROMIUM:
3595 break;
3596 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003597 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003598 return false;
3599 }
3600 if (!isPow2(mask + 1))
3601 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003602 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003603 return false;
3604 }
3605 return true;
3606}
3607
3608bool ValidateStencilStrokePathInstanced(Context *context,
3609 GLsizei numPaths,
3610 GLenum pathNameType,
3611 const void *paths,
3612 GLuint pathBase,
3613 GLint reference,
3614 GLuint mask,
3615 GLenum transformType,
3616 const GLfloat *transformValues)
3617{
3618 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3619 transformType, transformValues))
3620 return false;
3621
3622 // no more validation here.
3623
3624 return true;
3625}
3626
3627bool ValidateStencilThenCoverFillPathInstanced(Context *context,
3628 GLsizei numPaths,
3629 GLenum pathNameType,
3630 const void *paths,
3631 GLuint pathBase,
3632 GLenum fillMode,
3633 GLuint mask,
3634 GLenum coverMode,
3635 GLenum transformType,
3636 const GLfloat *transformValues)
3637{
3638 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3639 transformType, transformValues))
3640 return false;
3641
3642 switch (coverMode)
3643 {
3644 case GL_CONVEX_HULL_CHROMIUM:
3645 case GL_BOUNDING_BOX_CHROMIUM:
3646 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3647 break;
3648 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003649 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003650 return false;
3651 }
3652
3653 switch (fillMode)
3654 {
3655 case GL_COUNT_UP_CHROMIUM:
3656 case GL_COUNT_DOWN_CHROMIUM:
3657 break;
3658 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003659 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003660 return false;
3661 }
3662 if (!isPow2(mask + 1))
3663 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003664 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003665 return false;
3666 }
3667
3668 return true;
3669}
3670
3671bool ValidateStencilThenCoverStrokePathInstanced(Context *context,
3672 GLsizei numPaths,
3673 GLenum pathNameType,
3674 const void *paths,
3675 GLuint pathBase,
3676 GLint reference,
3677 GLuint mask,
3678 GLenum coverMode,
3679 GLenum transformType,
3680 const GLfloat *transformValues)
3681{
3682 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3683 transformType, transformValues))
3684 return false;
3685
3686 switch (coverMode)
3687 {
3688 case GL_CONVEX_HULL_CHROMIUM:
3689 case GL_BOUNDING_BOX_CHROMIUM:
3690 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3691 break;
3692 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003694 return false;
3695 }
3696
3697 return true;
3698}
3699
Sami Väisänen46eaa942016-06-29 10:26:37 +03003700bool ValidateBindFragmentInputLocation(Context *context,
3701 GLuint program,
3702 GLint location,
3703 const GLchar *name)
3704{
3705 if (!context->getExtensions().pathRendering)
3706 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003707 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003708 return false;
3709 }
3710
3711 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3712 if (location >= MaxLocation)
3713 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003714 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003715 return false;
3716 }
3717
3718 const auto *programObject = context->getProgram(program);
3719 if (!programObject)
3720 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003721 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003722 return false;
3723 }
3724
3725 if (!name)
3726 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003727 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003728 return false;
3729 }
3730
3731 if (angle::BeginsWith(name, "gl_"))
3732 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003733 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003734 return false;
3735 }
3736
3737 return true;
3738}
3739
3740bool ValidateProgramPathFragmentInputGen(Context *context,
3741 GLuint program,
3742 GLint location,
3743 GLenum genMode,
3744 GLint components,
3745 const GLfloat *coeffs)
3746{
3747 if (!context->getExtensions().pathRendering)
3748 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003749 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003750 return false;
3751 }
3752
3753 const auto *programObject = context->getProgram(program);
3754 if (!programObject || programObject->isFlaggedForDeletion())
3755 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003756 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003757 return false;
3758 }
3759
3760 if (!programObject->isLinked())
3761 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003762 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003763 return false;
3764 }
3765
3766 switch (genMode)
3767 {
3768 case GL_NONE:
3769 if (components != 0)
3770 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003771 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003772 return false;
3773 }
3774 break;
3775
3776 case GL_OBJECT_LINEAR_CHROMIUM:
3777 case GL_EYE_LINEAR_CHROMIUM:
3778 case GL_CONSTANT_CHROMIUM:
3779 if (components < 1 || components > 4)
3780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003781 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003782 return false;
3783 }
3784 if (!coeffs)
3785 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003786 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003787 return false;
3788 }
3789 break;
3790
3791 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003792 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003793 return false;
3794 }
3795
3796 // If the location is -1 then the command is silently ignored
3797 // and no further validation is needed.
3798 if (location == -1)
3799 return true;
3800
Jamie Madillbd044ed2017-06-05 12:59:21 -04003801 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003802
3803 if (!binding.valid)
3804 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003805 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003806 return false;
3807 }
3808
3809 if (binding.type != GL_NONE)
3810 {
3811 GLint expectedComponents = 0;
3812 switch (binding.type)
3813 {
3814 case GL_FLOAT:
3815 expectedComponents = 1;
3816 break;
3817 case GL_FLOAT_VEC2:
3818 expectedComponents = 2;
3819 break;
3820 case GL_FLOAT_VEC3:
3821 expectedComponents = 3;
3822 break;
3823 case GL_FLOAT_VEC4:
3824 expectedComponents = 4;
3825 break;
3826 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003827 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003828 InvalidOperation()
3829 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003830 return false;
3831 }
3832 if (expectedComponents != components && genMode != GL_NONE)
3833 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003834 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003835 return false;
3836 }
3837 }
3838 return true;
3839}
3840
Geoff Lang97073d12016-04-20 10:42:34 -07003841bool ValidateCopyTextureCHROMIUM(Context *context,
3842 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003843 GLint sourceLevel,
3844 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003845 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003846 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003847 GLint internalFormat,
3848 GLenum destType,
3849 GLboolean unpackFlipY,
3850 GLboolean unpackPremultiplyAlpha,
3851 GLboolean unpackUnmultiplyAlpha)
3852{
3853 if (!context->getExtensions().copyTexture)
3854 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003855 context->handleError(InvalidOperation()
3856 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003857 return false;
3858 }
3859
Geoff Lang4f0e0032017-05-01 16:04:35 -04003860 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003861 if (source == nullptr)
3862 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003863 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003864 return false;
3865 }
3866
3867 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003869 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003870 return false;
3871 }
3872
3873 GLenum sourceTarget = source->getTarget();
3874 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003875
3876 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003877 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003878 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003879 return false;
3880 }
3881
Geoff Lang4f0e0032017-05-01 16:04:35 -04003882 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3883 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3884 if (sourceWidth == 0 || sourceHeight == 0)
3885 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003886 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003887 return false;
3888 }
3889
3890 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3891 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003892 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003893 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003894 return false;
3895 }
3896
Geoff Lang63458a32017-10-30 15:16:53 -04003897 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3898 {
3899 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3900 return false;
3901 }
3902
Geoff Lang4f0e0032017-05-01 16:04:35 -04003903 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003904 if (dest == nullptr)
3905 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003906 context->handleError(InvalidValue()
3907 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003908 return false;
3909 }
3910
Geoff Lang4f0e0032017-05-01 16:04:35 -04003911 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003912 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003913 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003914 return false;
3915 }
3916
Geoff Lang4f0e0032017-05-01 16:04:35 -04003917 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, sourceWidth,
3918 sourceHeight))
3919 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003920 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003921 return false;
3922 }
3923
Geoff Lang97073d12016-04-20 10:42:34 -07003924 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3925 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003926 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003927 return false;
3928 }
3929
Geoff Lang4f0e0032017-05-01 16:04:35 -04003930 if (IsCubeMapTextureTarget(destTarget) && sourceWidth != sourceHeight)
3931 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003932 context->handleError(
3933 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003934 return false;
3935 }
3936
Geoff Lang97073d12016-04-20 10:42:34 -07003937 if (dest->getImmutableFormat())
3938 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003939 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003940 return false;
3941 }
3942
3943 return true;
3944}
3945
3946bool ValidateCopySubTextureCHROMIUM(Context *context,
3947 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003948 GLint sourceLevel,
3949 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003950 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003951 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003952 GLint xoffset,
3953 GLint yoffset,
3954 GLint x,
3955 GLint y,
3956 GLsizei width,
3957 GLsizei height,
3958 GLboolean unpackFlipY,
3959 GLboolean unpackPremultiplyAlpha,
3960 GLboolean unpackUnmultiplyAlpha)
3961{
3962 if (!context->getExtensions().copyTexture)
3963 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003964 context->handleError(InvalidOperation()
3965 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003966 return false;
3967 }
3968
Geoff Lang4f0e0032017-05-01 16:04:35 -04003969 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003970 if (source == nullptr)
3971 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003972 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003973 return false;
3974 }
3975
3976 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3977 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003978 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003979 return false;
3980 }
3981
3982 GLenum sourceTarget = source->getTarget();
3983 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003984
3985 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
3986 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003987 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003988 return false;
3989 }
3990
3991 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
3992 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07003993 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003994 context->handleError(InvalidValue()
3995 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07003996 return false;
3997 }
3998
3999 if (x < 0 || y < 0)
4000 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004001 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004002 return false;
4003 }
4004
4005 if (width < 0 || height < 0)
4006 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004007 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004008 return false;
4009 }
4010
Geoff Lang4f0e0032017-05-01 16:04:35 -04004011 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4012 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004013 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004014 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004015 return false;
4016 }
4017
Geoff Lang4f0e0032017-05-01 16:04:35 -04004018 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4019 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004020 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004021 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004022 return false;
4023 }
4024
Geoff Lang63458a32017-10-30 15:16:53 -04004025 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4026 {
4027 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4028 return false;
4029 }
4030
Geoff Lang4f0e0032017-05-01 16:04:35 -04004031 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004032 if (dest == nullptr)
4033 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004034 context->handleError(InvalidValue()
4035 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004036 return false;
4037 }
4038
Geoff Lang4f0e0032017-05-01 16:04:35 -04004039 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004040 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004041 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004042 return false;
4043 }
4044
Geoff Lang4f0e0032017-05-01 16:04:35 -04004045 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, width, height))
Geoff Lang97073d12016-04-20 10:42:34 -07004046 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004047 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004048 return false;
4049 }
4050
Geoff Lang4f0e0032017-05-01 16:04:35 -04004051 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4052 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004053 context
4054 ->handleError(InvalidOperation()
4055 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004056 return false;
4057 }
4058
4059 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4060 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004061 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004062 context->handleError(InvalidOperation()
4063 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004064 return false;
4065 }
4066
4067 if (xoffset < 0 || yoffset < 0)
4068 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004069 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004070 return false;
4071 }
4072
Geoff Lang4f0e0032017-05-01 16:04:35 -04004073 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4074 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004075 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004076 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004077 return false;
4078 }
4079
4080 return true;
4081}
4082
Geoff Lang47110bf2016-04-20 11:13:22 -07004083bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4084{
4085 if (!context->getExtensions().copyCompressedTexture)
4086 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004087 context->handleError(InvalidOperation()
4088 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004089 return false;
4090 }
4091
4092 const gl::Texture *source = context->getTexture(sourceId);
4093 if (source == nullptr)
4094 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004095 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004096 return false;
4097 }
4098
4099 if (source->getTarget() != GL_TEXTURE_2D)
4100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004101 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004102 return false;
4103 }
4104
4105 if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0)
4106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004107 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004108 return false;
4109 }
4110
4111 const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0);
4112 if (!sourceFormat.info->compressed)
4113 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004114 context->handleError(InvalidOperation()
4115 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004116 return false;
4117 }
4118
4119 const gl::Texture *dest = context->getTexture(destId);
4120 if (dest == nullptr)
4121 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004122 context->handleError(InvalidValue()
4123 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004124 return false;
4125 }
4126
4127 if (dest->getTarget() != GL_TEXTURE_2D)
4128 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004129 context->handleError(InvalidValue()
4130 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004131 return false;
4132 }
4133
4134 if (dest->getImmutableFormat())
4135 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004136 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004137 return false;
4138 }
4139
4140 return true;
4141}
4142
Martin Radev4c4c8e72016-08-04 12:25:34 +03004143bool ValidateCreateShader(Context *context, GLenum type)
4144{
4145 switch (type)
4146 {
4147 case GL_VERTEX_SHADER:
4148 case GL_FRAGMENT_SHADER:
4149 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004150
Martin Radev4c4c8e72016-08-04 12:25:34 +03004151 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004152 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004153 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004154 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004155 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004156 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004157 break;
4158
Martin Radev4c4c8e72016-08-04 12:25:34 +03004159 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004160 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004161 return false;
4162 }
Jamie Madill29639852016-09-02 15:00:09 -04004163
4164 return true;
4165}
4166
4167bool ValidateBufferData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004168 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004169 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004170 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004171 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004172{
4173 if (size < 0)
4174 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004175 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004176 return false;
4177 }
4178
4179 switch (usage)
4180 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004181 case BufferUsage::StreamDraw:
4182 case BufferUsage::StaticDraw:
4183 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004184 break;
4185
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004186 case BufferUsage::StreamRead:
4187 case BufferUsage::StaticRead:
4188 case BufferUsage::DynamicRead:
4189 case BufferUsage::StreamCopy:
4190 case BufferUsage::StaticCopy:
4191 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004192 if (context->getClientMajorVersion() < 3)
4193 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004194 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004195 return false;
4196 }
4197 break;
4198
4199 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004201 return false;
4202 }
4203
Corentin Wallez336129f2017-10-17 15:55:40 -04004204 if (!ValidBufferType(context, target))
Jamie Madill29639852016-09-02 15:00:09 -04004205 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004206 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004207 return false;
4208 }
4209
4210 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4211
4212 if (!buffer)
4213 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004214 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004215 return false;
4216 }
4217
4218 return true;
4219}
4220
4221bool ValidateBufferSubData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004222 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004223 GLintptr offset,
4224 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004225 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004226{
Brandon Jones6cad5662017-06-14 13:25:13 -07004227 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004228 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004229 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4230 return false;
4231 }
4232
4233 if (offset < 0)
4234 {
4235 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004236 return false;
4237 }
4238
Corentin Wallez336129f2017-10-17 15:55:40 -04004239 if (!ValidBufferType(context, target))
Jamie Madill29639852016-09-02 15:00:09 -04004240 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004241 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004242 return false;
4243 }
4244
4245 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4246
4247 if (!buffer)
4248 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004249 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004250 return false;
4251 }
4252
4253 if (buffer->isMapped())
4254 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004255 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004256 return false;
4257 }
4258
4259 // Check for possible overflow of size + offset
4260 angle::CheckedNumeric<size_t> checkedSize(size);
4261 checkedSize += offset;
4262 if (!checkedSize.IsValid())
4263 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004264 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004265 return false;
4266 }
4267
4268 if (size + offset > buffer->getSize())
4269 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004270 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004271 return false;
4272 }
4273
Martin Radev4c4c8e72016-08-04 12:25:34 +03004274 return true;
4275}
4276
Geoff Lang111a99e2017-10-17 10:58:41 -04004277bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004278{
Geoff Langc339c4e2016-11-29 10:37:36 -05004279 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004280 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004281 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004282 return false;
4283 }
4284
Geoff Lang111a99e2017-10-17 10:58:41 -04004285 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004286 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004287 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004288 return false;
4289 }
4290
4291 return true;
4292}
4293
Jamie Madillef300b12016-10-07 15:12:09 -04004294bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4295{
4296 if (texture < GL_TEXTURE0 ||
4297 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4298 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004299 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004300 return false;
4301 }
4302
4303 return true;
4304}
4305
4306bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4307{
4308 Program *programObject = GetValidProgram(context, program);
4309 if (!programObject)
4310 {
4311 return false;
4312 }
4313
4314 Shader *shaderObject = GetValidShader(context, shader);
4315 if (!shaderObject)
4316 {
4317 return false;
4318 }
4319
4320 switch (shaderObject->getType())
4321 {
4322 case GL_VERTEX_SHADER:
4323 {
4324 if (programObject->getAttachedVertexShader())
4325 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004326 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004327 return false;
4328 }
4329 break;
4330 }
4331 case GL_FRAGMENT_SHADER:
4332 {
4333 if (programObject->getAttachedFragmentShader())
4334 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004335 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004336 return false;
4337 }
4338 break;
4339 }
4340 case GL_COMPUTE_SHADER:
4341 {
4342 if (programObject->getAttachedComputeShader())
4343 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004345 return false;
4346 }
4347 break;
4348 }
4349 default:
4350 UNREACHABLE();
4351 break;
4352 }
4353
4354 return true;
4355}
4356
Jamie Madill01a80ee2016-11-07 12:06:18 -05004357bool ValidateBindAttribLocation(ValidationContext *context,
4358 GLuint program,
4359 GLuint index,
4360 const GLchar *name)
4361{
4362 if (index >= MAX_VERTEX_ATTRIBS)
4363 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004364 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004365 return false;
4366 }
4367
4368 if (strncmp(name, "gl_", 3) == 0)
4369 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004370 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004371 return false;
4372 }
4373
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004374 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004375 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004376 const size_t length = strlen(name);
4377
4378 if (!IsValidESSLString(name, length))
4379 {
4380 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4381 // for shader-related entry points
4382 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4383 return false;
4384 }
4385
4386 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4387 {
4388 return false;
4389 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004390 }
4391
Jamie Madill01a80ee2016-11-07 12:06:18 -05004392 return GetValidProgram(context, program) != nullptr;
4393}
4394
Corentin Wallez336129f2017-10-17 15:55:40 -04004395bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004396{
Corentin Wallez336129f2017-10-17 15:55:40 -04004397 if (!ValidBufferType(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004398 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004399 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004400 return false;
4401 }
4402
4403 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4404 !context->isBufferGenerated(buffer))
4405 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004406 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004407 return false;
4408 }
4409
4410 return true;
4411}
4412
4413bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4414{
4415 if (!ValidFramebufferTarget(target))
4416 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004417 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004418 return false;
4419 }
4420
4421 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4422 !context->isFramebufferGenerated(framebuffer))
4423 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004424 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004425 return false;
4426 }
4427
4428 return true;
4429}
4430
4431bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4432{
4433 if (target != GL_RENDERBUFFER)
4434 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004435 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004436 return false;
4437 }
4438
4439 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4440 !context->isRenderbufferGenerated(renderbuffer))
4441 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004442 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004443 return false;
4444 }
4445
4446 return true;
4447}
4448
Geoff Lang50cac572017-09-26 17:37:43 -04004449static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004450{
4451 switch (mode)
4452 {
4453 case GL_FUNC_ADD:
4454 case GL_FUNC_SUBTRACT:
4455 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004456 return true;
4457
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004458 case GL_MIN:
4459 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004460 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004461
4462 default:
4463 return false;
4464 }
4465}
4466
Jamie Madillc1d770e2017-04-13 17:31:24 -04004467bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004468 GLfloat red,
4469 GLfloat green,
4470 GLfloat blue,
4471 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004472{
4473 return true;
4474}
4475
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004476bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4477{
Geoff Lang50cac572017-09-26 17:37:43 -04004478 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004479 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004480 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004481 return false;
4482 }
4483
4484 return true;
4485}
4486
4487bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4488{
Geoff Lang50cac572017-09-26 17:37:43 -04004489 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004490 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004491 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004492 return false;
4493 }
4494
Geoff Lang50cac572017-09-26 17:37:43 -04004495 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004496 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004497 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004498 return false;
4499 }
4500
4501 return true;
4502}
4503
4504bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4505{
4506 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4507}
4508
4509static bool ValidSrcBlendFunc(GLenum srcBlend)
4510{
4511 switch (srcBlend)
4512 {
4513 case GL_ZERO:
4514 case GL_ONE:
4515 case GL_SRC_COLOR:
4516 case GL_ONE_MINUS_SRC_COLOR:
4517 case GL_DST_COLOR:
4518 case GL_ONE_MINUS_DST_COLOR:
4519 case GL_SRC_ALPHA:
4520 case GL_ONE_MINUS_SRC_ALPHA:
4521 case GL_DST_ALPHA:
4522 case GL_ONE_MINUS_DST_ALPHA:
4523 case GL_CONSTANT_COLOR:
4524 case GL_ONE_MINUS_CONSTANT_COLOR:
4525 case GL_CONSTANT_ALPHA:
4526 case GL_ONE_MINUS_CONSTANT_ALPHA:
4527 case GL_SRC_ALPHA_SATURATE:
4528 return true;
4529
4530 default:
4531 return false;
4532 }
4533}
4534
4535static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4536{
4537 switch (dstBlend)
4538 {
4539 case GL_ZERO:
4540 case GL_ONE:
4541 case GL_SRC_COLOR:
4542 case GL_ONE_MINUS_SRC_COLOR:
4543 case GL_DST_COLOR:
4544 case GL_ONE_MINUS_DST_COLOR:
4545 case GL_SRC_ALPHA:
4546 case GL_ONE_MINUS_SRC_ALPHA:
4547 case GL_DST_ALPHA:
4548 case GL_ONE_MINUS_DST_ALPHA:
4549 case GL_CONSTANT_COLOR:
4550 case GL_ONE_MINUS_CONSTANT_COLOR:
4551 case GL_CONSTANT_ALPHA:
4552 case GL_ONE_MINUS_CONSTANT_ALPHA:
4553 return true;
4554
4555 case GL_SRC_ALPHA_SATURATE:
4556 return (contextMajorVersion >= 3);
4557
4558 default:
4559 return false;
4560 }
4561}
4562
4563bool ValidateBlendFuncSeparate(ValidationContext *context,
4564 GLenum srcRGB,
4565 GLenum dstRGB,
4566 GLenum srcAlpha,
4567 GLenum dstAlpha)
4568{
4569 if (!ValidSrcBlendFunc(srcRGB))
4570 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004571 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004572 return false;
4573 }
4574
4575 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4576 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004577 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004578 return false;
4579 }
4580
4581 if (!ValidSrcBlendFunc(srcAlpha))
4582 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004583 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004584 return false;
4585 }
4586
4587 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4588 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004589 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004590 return false;
4591 }
4592
Frank Henigman146e8a12017-03-02 23:22:37 -05004593 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4594 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004595 {
4596 bool constantColorUsed =
4597 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4598 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4599
4600 bool constantAlphaUsed =
4601 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4602 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4603
4604 if (constantColorUsed && constantAlphaUsed)
4605 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004606 const char *msg;
4607 if (context->getExtensions().webglCompatibility)
4608 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004609 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004610 }
4611 else
4612 {
4613 msg =
4614 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4615 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4616 "implementation.";
4617 ERR() << msg;
4618 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004619 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004620 return false;
4621 }
4622 }
4623
4624 return true;
4625}
4626
Geoff Langc339c4e2016-11-29 10:37:36 -05004627bool ValidateGetString(Context *context, GLenum name)
4628{
4629 switch (name)
4630 {
4631 case GL_VENDOR:
4632 case GL_RENDERER:
4633 case GL_VERSION:
4634 case GL_SHADING_LANGUAGE_VERSION:
4635 case GL_EXTENSIONS:
4636 break;
4637
4638 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4639 if (!context->getExtensions().requestExtension)
4640 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004641 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004642 return false;
4643 }
4644 break;
4645
4646 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004647 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004648 return false;
4649 }
4650
4651 return true;
4652}
4653
Geoff Lang47c48082016-12-07 15:38:13 -05004654bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4655{
4656 if (width <= 0.0f || isNaN(width))
4657 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004658 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004659 return false;
4660 }
4661
4662 return true;
4663}
4664
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004665bool ValidateVertexAttribPointer(ValidationContext *context,
4666 GLuint index,
4667 GLint size,
4668 GLenum type,
4669 GLboolean normalized,
4670 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004671 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004672{
Shao80957d92017-02-20 21:25:59 +08004673 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004674 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004675 return false;
4676 }
4677
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004678 if (stride < 0)
4679 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004680 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004681 return false;
4682 }
4683
Shao80957d92017-02-20 21:25:59 +08004684 const Caps &caps = context->getCaps();
4685 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004686 {
Shao80957d92017-02-20 21:25:59 +08004687 if (stride > caps.maxVertexAttribStride)
4688 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004689 context->handleError(InvalidValue()
4690 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004691 return false;
4692 }
4693
4694 if (index >= caps.maxVertexAttribBindings)
4695 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004696 context->handleError(InvalidValue()
4697 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004698 return false;
4699 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004700 }
4701
4702 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4703 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4704 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4705 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004706 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4707 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004708 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4709 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004710 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004711 context
4712 ->handleError(InvalidOperation()
4713 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004714 return false;
4715 }
4716
4717 if (context->getExtensions().webglCompatibility)
4718 {
4719 // WebGL 1.0 [Section 6.14] Fixed point support
4720 // The WebGL API does not support the GL_FIXED data type.
4721 if (type == GL_FIXED)
4722 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004723 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004724 return false;
4725 }
4726
Geoff Lang2d62ab72017-03-23 16:54:40 -04004727 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004728 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004729 return false;
4730 }
4731 }
4732
4733 return true;
4734}
4735
Jamie Madill876429b2017-04-20 15:46:24 -04004736bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004737{
4738 if (context->getExtensions().webglCompatibility && zNear > zFar)
4739 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004740 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004741 return false;
4742 }
4743
4744 return true;
4745}
4746
Jamie Madille8fb6402017-02-14 17:56:40 -05004747bool ValidateRenderbufferStorage(ValidationContext *context,
4748 GLenum target,
4749 GLenum internalformat,
4750 GLsizei width,
4751 GLsizei height)
4752{
4753 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4754 height);
4755}
4756
4757bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4758 GLenum target,
4759 GLsizei samples,
4760 GLenum internalformat,
4761 GLsizei width,
4762 GLsizei height)
4763{
4764 if (!context->getExtensions().framebufferMultisample)
4765 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004766 context->handleError(InvalidOperation()
4767 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004768 return false;
4769 }
4770
4771 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4772 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4773 // generated.
4774 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4775 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004776 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004777 return false;
4778 }
4779
4780 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4781 // the specified storage. This is different than ES 3.0 in which a sample number higher
4782 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4783 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4784 if (context->getClientMajorVersion() >= 3)
4785 {
4786 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4787 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4788 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004789 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004790 return false;
4791 }
4792 }
4793
4794 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4795 width, height);
4796}
4797
Jamie Madillc1d770e2017-04-13 17:31:24 -04004798bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4799{
4800 if (!ValidFramebufferTarget(target))
4801 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004802 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004803 return false;
4804 }
4805
4806 return true;
4807}
4808
4809bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004810 GLfloat red,
4811 GLfloat green,
4812 GLfloat blue,
4813 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004814{
4815 return true;
4816}
4817
Jamie Madill876429b2017-04-20 15:46:24 -04004818bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004819{
4820 return true;
4821}
4822
4823bool ValidateClearStencil(ValidationContext *context, GLint s)
4824{
4825 return true;
4826}
4827
4828bool ValidateColorMask(ValidationContext *context,
4829 GLboolean red,
4830 GLboolean green,
4831 GLboolean blue,
4832 GLboolean alpha)
4833{
4834 return true;
4835}
4836
4837bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4838{
4839 return true;
4840}
4841
4842bool ValidateCreateProgram(ValidationContext *context)
4843{
4844 return true;
4845}
4846
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004847bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004848{
4849 switch (mode)
4850 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004851 case CullFaceMode::Front:
4852 case CullFaceMode::Back:
4853 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004854 break;
4855
4856 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004857 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004858 return false;
4859 }
4860
4861 return true;
4862}
4863
4864bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4865{
4866 if (program == 0)
4867 {
4868 return false;
4869 }
4870
4871 if (!context->getProgram(program))
4872 {
4873 if (context->getShader(program))
4874 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004875 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004876 return false;
4877 }
4878 else
4879 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004880 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004881 return false;
4882 }
4883 }
4884
4885 return true;
4886}
4887
4888bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4889{
4890 if (shader == 0)
4891 {
4892 return false;
4893 }
4894
4895 if (!context->getShader(shader))
4896 {
4897 if (context->getProgram(shader))
4898 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004899 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004900 return false;
4901 }
4902 else
4903 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004904 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004905 return false;
4906 }
4907 }
4908
4909 return true;
4910}
4911
4912bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4913{
4914 switch (func)
4915 {
4916 case GL_NEVER:
4917 case GL_ALWAYS:
4918 case GL_LESS:
4919 case GL_LEQUAL:
4920 case GL_EQUAL:
4921 case GL_GREATER:
4922 case GL_GEQUAL:
4923 case GL_NOTEQUAL:
4924 break;
4925
4926 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004927 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004928 return false;
4929 }
4930
4931 return true;
4932}
4933
4934bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4935{
4936 return true;
4937}
4938
4939bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4940{
4941 Program *programObject = GetValidProgram(context, program);
4942 if (!programObject)
4943 {
4944 return false;
4945 }
4946
4947 Shader *shaderObject = GetValidShader(context, shader);
4948 if (!shaderObject)
4949 {
4950 return false;
4951 }
4952
4953 const Shader *attachedShader = nullptr;
4954
4955 switch (shaderObject->getType())
4956 {
4957 case GL_VERTEX_SHADER:
4958 {
4959 attachedShader = programObject->getAttachedVertexShader();
4960 break;
4961 }
4962 case GL_FRAGMENT_SHADER:
4963 {
4964 attachedShader = programObject->getAttachedFragmentShader();
4965 break;
4966 }
4967 case GL_COMPUTE_SHADER:
4968 {
4969 attachedShader = programObject->getAttachedComputeShader();
4970 break;
4971 }
4972 default:
4973 UNREACHABLE();
4974 return false;
4975 }
4976
4977 if (attachedShader != shaderObject)
4978 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004979 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004980 return false;
4981 }
4982
4983 return true;
4984}
4985
4986bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
4987{
4988 if (index >= MAX_VERTEX_ATTRIBS)
4989 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004990 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004991 return false;
4992 }
4993
4994 return true;
4995}
4996
4997bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
4998{
4999 if (index >= MAX_VERTEX_ATTRIBS)
5000 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005001 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005002 return false;
5003 }
5004
5005 return true;
5006}
5007
5008bool ValidateFinish(ValidationContext *context)
5009{
5010 return true;
5011}
5012
5013bool ValidateFlush(ValidationContext *context)
5014{
5015 return true;
5016}
5017
5018bool ValidateFrontFace(ValidationContext *context, GLenum mode)
5019{
5020 switch (mode)
5021 {
5022 case GL_CW:
5023 case GL_CCW:
5024 break;
5025 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005026 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005027 return false;
5028 }
5029
5030 return true;
5031}
5032
5033bool ValidateGetActiveAttrib(ValidationContext *context,
5034 GLuint program,
5035 GLuint index,
5036 GLsizei bufsize,
5037 GLsizei *length,
5038 GLint *size,
5039 GLenum *type,
5040 GLchar *name)
5041{
5042 if (bufsize < 0)
5043 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005044 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005045 return false;
5046 }
5047
5048 Program *programObject = GetValidProgram(context, program);
5049
5050 if (!programObject)
5051 {
5052 return false;
5053 }
5054
5055 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5056 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005057 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005058 return false;
5059 }
5060
5061 return true;
5062}
5063
5064bool ValidateGetActiveUniform(ValidationContext *context,
5065 GLuint program,
5066 GLuint index,
5067 GLsizei bufsize,
5068 GLsizei *length,
5069 GLint *size,
5070 GLenum *type,
5071 GLchar *name)
5072{
5073 if (bufsize < 0)
5074 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005075 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005076 return false;
5077 }
5078
5079 Program *programObject = GetValidProgram(context, program);
5080
5081 if (!programObject)
5082 {
5083 return false;
5084 }
5085
5086 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5087 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005088 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005089 return false;
5090 }
5091
5092 return true;
5093}
5094
5095bool ValidateGetAttachedShaders(ValidationContext *context,
5096 GLuint program,
5097 GLsizei maxcount,
5098 GLsizei *count,
5099 GLuint *shaders)
5100{
5101 if (maxcount < 0)
5102 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005103 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005104 return false;
5105 }
5106
5107 Program *programObject = GetValidProgram(context, program);
5108
5109 if (!programObject)
5110 {
5111 return false;
5112 }
5113
5114 return true;
5115}
5116
5117bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5118{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005119 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5120 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005121 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005122 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005123 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005124 return false;
5125 }
5126
Jamie Madillc1d770e2017-04-13 17:31:24 -04005127 Program *programObject = GetValidProgram(context, program);
5128
5129 if (!programObject)
5130 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005131 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005132 return false;
5133 }
5134
5135 if (!programObject->isLinked())
5136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005137 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005138 return false;
5139 }
5140
5141 return true;
5142}
5143
5144bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5145{
5146 GLenum nativeType;
5147 unsigned int numParams = 0;
5148 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5149}
5150
5151bool ValidateGetError(ValidationContext *context)
5152{
5153 return true;
5154}
5155
5156bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5157{
5158 GLenum nativeType;
5159 unsigned int numParams = 0;
5160 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5161}
5162
5163bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5164{
5165 GLenum nativeType;
5166 unsigned int numParams = 0;
5167 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5168}
5169
5170bool ValidateGetProgramInfoLog(ValidationContext *context,
5171 GLuint program,
5172 GLsizei bufsize,
5173 GLsizei *length,
5174 GLchar *infolog)
5175{
5176 if (bufsize < 0)
5177 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005178 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005179 return false;
5180 }
5181
5182 Program *programObject = GetValidProgram(context, program);
5183 if (!programObject)
5184 {
5185 return false;
5186 }
5187
5188 return true;
5189}
5190
5191bool ValidateGetShaderInfoLog(ValidationContext *context,
5192 GLuint shader,
5193 GLsizei bufsize,
5194 GLsizei *length,
5195 GLchar *infolog)
5196{
5197 if (bufsize < 0)
5198 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005199 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005200 return false;
5201 }
5202
5203 Shader *shaderObject = GetValidShader(context, shader);
5204 if (!shaderObject)
5205 {
5206 return false;
5207 }
5208
5209 return true;
5210}
5211
5212bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5213 GLenum shadertype,
5214 GLenum precisiontype,
5215 GLint *range,
5216 GLint *precision)
5217{
5218 switch (shadertype)
5219 {
5220 case GL_VERTEX_SHADER:
5221 case GL_FRAGMENT_SHADER:
5222 break;
5223 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005224 context->handleError(InvalidOperation()
5225 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005226 return false;
5227 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005228 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005229 return false;
5230 }
5231
5232 switch (precisiontype)
5233 {
5234 case GL_LOW_FLOAT:
5235 case GL_MEDIUM_FLOAT:
5236 case GL_HIGH_FLOAT:
5237 case GL_LOW_INT:
5238 case GL_MEDIUM_INT:
5239 case GL_HIGH_INT:
5240 break;
5241
5242 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005243 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005244 return false;
5245 }
5246
5247 return true;
5248}
5249
5250bool ValidateGetShaderSource(ValidationContext *context,
5251 GLuint shader,
5252 GLsizei bufsize,
5253 GLsizei *length,
5254 GLchar *source)
5255{
5256 if (bufsize < 0)
5257 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005258 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005259 return false;
5260 }
5261
5262 Shader *shaderObject = GetValidShader(context, shader);
5263 if (!shaderObject)
5264 {
5265 return false;
5266 }
5267
5268 return true;
5269}
5270
5271bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5272{
5273 if (strstr(name, "gl_") == name)
5274 {
5275 return false;
5276 }
5277
Geoff Langfc32e8b2017-05-31 14:16:59 -04005278 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5279 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005280 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005281 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005282 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005283 return false;
5284 }
5285
Jamie Madillc1d770e2017-04-13 17:31:24 -04005286 Program *programObject = GetValidProgram(context, program);
5287
5288 if (!programObject)
5289 {
5290 return false;
5291 }
5292
5293 if (!programObject->isLinked())
5294 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005296 return false;
5297 }
5298
5299 return true;
5300}
5301
5302bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5303{
5304 switch (mode)
5305 {
5306 case GL_FASTEST:
5307 case GL_NICEST:
5308 case GL_DONT_CARE:
5309 break;
5310
5311 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005312 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005313 return false;
5314 }
5315
5316 switch (target)
5317 {
5318 case GL_GENERATE_MIPMAP_HINT:
5319 break;
5320
Geoff Lange7bd2182017-06-16 16:13:13 -04005321 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5322 if (context->getClientVersion() < ES_3_0 &&
5323 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005324 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005325 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005326 return false;
5327 }
5328 break;
5329
5330 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005331 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005332 return false;
5333 }
5334
5335 return true;
5336}
5337
5338bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5339{
5340 return true;
5341}
5342
5343bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5344{
5345 return true;
5346}
5347
5348bool ValidateIsProgram(ValidationContext *context, GLuint program)
5349{
5350 return true;
5351}
5352
5353bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5354{
5355 return true;
5356}
5357
5358bool ValidateIsShader(ValidationContext *context, GLuint shader)
5359{
5360 return true;
5361}
5362
5363bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5364{
5365 return true;
5366}
5367
5368bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5369{
5370 if (context->getClientMajorVersion() < 3)
5371 {
5372 switch (pname)
5373 {
5374 case GL_UNPACK_IMAGE_HEIGHT:
5375 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005376 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005377 return false;
5378
5379 case GL_UNPACK_ROW_LENGTH:
5380 case GL_UNPACK_SKIP_ROWS:
5381 case GL_UNPACK_SKIP_PIXELS:
5382 if (!context->getExtensions().unpackSubimage)
5383 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005384 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385 return false;
5386 }
5387 break;
5388
5389 case GL_PACK_ROW_LENGTH:
5390 case GL_PACK_SKIP_ROWS:
5391 case GL_PACK_SKIP_PIXELS:
5392 if (!context->getExtensions().packSubimage)
5393 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005394 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005395 return false;
5396 }
5397 break;
5398 }
5399 }
5400
5401 if (param < 0)
5402 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005403 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005404 return false;
5405 }
5406
5407 switch (pname)
5408 {
5409 case GL_UNPACK_ALIGNMENT:
5410 if (param != 1 && param != 2 && param != 4 && param != 8)
5411 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005412 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005413 return false;
5414 }
5415 break;
5416
5417 case GL_PACK_ALIGNMENT:
5418 if (param != 1 && param != 2 && param != 4 && param != 8)
5419 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005420 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005421 return false;
5422 }
5423 break;
5424
5425 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005426 if (!context->getExtensions().packReverseRowOrder)
5427 {
5428 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5429 }
5430 break;
5431
Jamie Madillc1d770e2017-04-13 17:31:24 -04005432 case GL_UNPACK_ROW_LENGTH:
5433 case GL_UNPACK_IMAGE_HEIGHT:
5434 case GL_UNPACK_SKIP_IMAGES:
5435 case GL_UNPACK_SKIP_ROWS:
5436 case GL_UNPACK_SKIP_PIXELS:
5437 case GL_PACK_ROW_LENGTH:
5438 case GL_PACK_SKIP_ROWS:
5439 case GL_PACK_SKIP_PIXELS:
5440 break;
5441
5442 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005443 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444 return false;
5445 }
5446
5447 return true;
5448}
5449
5450bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5451{
5452 return true;
5453}
5454
5455bool ValidateReleaseShaderCompiler(ValidationContext *context)
5456{
5457 return true;
5458}
5459
Jamie Madill876429b2017-04-20 15:46:24 -04005460bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005461{
5462 return true;
5463}
5464
5465bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5466{
5467 if (width < 0 || height < 0)
5468 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005469 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470 return false;
5471 }
5472
5473 return true;
5474}
5475
5476bool ValidateShaderBinary(ValidationContext *context,
5477 GLsizei n,
5478 const GLuint *shaders,
5479 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005480 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005481 GLsizei length)
5482{
5483 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5484 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5485 shaderBinaryFormats.end())
5486 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005487 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005488 return false;
5489 }
5490
5491 return true;
5492}
5493
5494bool ValidateShaderSource(ValidationContext *context,
5495 GLuint shader,
5496 GLsizei count,
5497 const GLchar *const *string,
5498 const GLint *length)
5499{
5500 if (count < 0)
5501 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005502 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005503 return false;
5504 }
5505
Geoff Langfc32e8b2017-05-31 14:16:59 -04005506 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5507 // shader-related entry points
5508 if (context->getExtensions().webglCompatibility)
5509 {
5510 for (GLsizei i = 0; i < count; i++)
5511 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005512 size_t len =
5513 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005514
5515 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005516 if (!IsValidESSLShaderSourceString(string[i], len,
5517 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005518 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005519 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005520 return false;
5521 }
5522 }
5523 }
5524
Jamie Madillc1d770e2017-04-13 17:31:24 -04005525 Shader *shaderObject = GetValidShader(context, shader);
5526 if (!shaderObject)
5527 {
5528 return false;
5529 }
5530
5531 return true;
5532}
5533
5534bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5535{
5536 if (!IsValidStencilFunc(func))
5537 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005538 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005539 return false;
5540 }
5541
5542 return true;
5543}
5544
5545bool ValidateStencilFuncSeparate(ValidationContext *context,
5546 GLenum face,
5547 GLenum func,
5548 GLint ref,
5549 GLuint mask)
5550{
5551 if (!IsValidStencilFace(face))
5552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005553 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005554 return false;
5555 }
5556
5557 if (!IsValidStencilFunc(func))
5558 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005559 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005560 return false;
5561 }
5562
5563 return true;
5564}
5565
5566bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5567{
5568 return true;
5569}
5570
5571bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5572{
5573 if (!IsValidStencilFace(face))
5574 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005575 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005576 return false;
5577 }
5578
5579 return true;
5580}
5581
5582bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5583{
5584 if (!IsValidStencilOp(fail))
5585 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005586 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005587 return false;
5588 }
5589
5590 if (!IsValidStencilOp(zfail))
5591 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005592 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005593 return false;
5594 }
5595
5596 if (!IsValidStencilOp(zpass))
5597 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005598 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005599 return false;
5600 }
5601
5602 return true;
5603}
5604
5605bool ValidateStencilOpSeparate(ValidationContext *context,
5606 GLenum face,
5607 GLenum fail,
5608 GLenum zfail,
5609 GLenum zpass)
5610{
5611 if (!IsValidStencilFace(face))
5612 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005613 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005614 return false;
5615 }
5616
5617 return ValidateStencilOp(context, fail, zfail, zpass);
5618}
5619
5620bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5621{
5622 return ValidateUniform(context, GL_FLOAT, location, 1);
5623}
5624
5625bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5626{
5627 return ValidateUniform(context, GL_FLOAT, location, count);
5628}
5629
Jamie Madillbe849e42017-05-02 15:49:00 -04005630bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5631{
5632 return ValidateUniform1iv(context, location, 1, &x);
5633}
5634
Jamie Madillc1d770e2017-04-13 17:31:24 -04005635bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5636{
5637 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5638}
5639
5640bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5641{
5642 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5643}
5644
5645bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5646{
5647 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5648}
5649
5650bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5651{
5652 return ValidateUniform(context, GL_INT_VEC2, location, count);
5653}
5654
5655bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5656{
5657 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5658}
5659
5660bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5661{
5662 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5663}
5664
5665bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5666{
5667 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5668}
5669
5670bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5671{
5672 return ValidateUniform(context, GL_INT_VEC3, location, count);
5673}
5674
5675bool ValidateUniform4f(ValidationContext *context,
5676 GLint location,
5677 GLfloat x,
5678 GLfloat y,
5679 GLfloat z,
5680 GLfloat w)
5681{
5682 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5683}
5684
5685bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5686{
5687 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5688}
5689
5690bool ValidateUniform4i(ValidationContext *context,
5691 GLint location,
5692 GLint x,
5693 GLint y,
5694 GLint z,
5695 GLint w)
5696{
5697 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5698}
5699
5700bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5701{
5702 return ValidateUniform(context, GL_INT_VEC4, location, count);
5703}
5704
5705bool ValidateUniformMatrix2fv(ValidationContext *context,
5706 GLint location,
5707 GLsizei count,
5708 GLboolean transpose,
5709 const GLfloat *value)
5710{
5711 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5712}
5713
5714bool ValidateUniformMatrix3fv(ValidationContext *context,
5715 GLint location,
5716 GLsizei count,
5717 GLboolean transpose,
5718 const GLfloat *value)
5719{
5720 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5721}
5722
5723bool ValidateUniformMatrix4fv(ValidationContext *context,
5724 GLint location,
5725 GLsizei count,
5726 GLboolean transpose,
5727 const GLfloat *value)
5728{
5729 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5730}
5731
5732bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5733{
5734 Program *programObject = GetValidProgram(context, program);
5735
5736 if (!programObject)
5737 {
5738 return false;
5739 }
5740
5741 return true;
5742}
5743
Jamie Madillc1d770e2017-04-13 17:31:24 -04005744bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5745{
5746 return ValidateVertexAttribIndex(context, index);
5747}
5748
5749bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5750{
5751 return ValidateVertexAttribIndex(context, index);
5752}
5753
5754bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5755{
5756 return ValidateVertexAttribIndex(context, index);
5757}
5758
5759bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5760{
5761 return ValidateVertexAttribIndex(context, index);
5762}
5763
5764bool ValidateVertexAttrib3f(ValidationContext *context,
5765 GLuint index,
5766 GLfloat x,
5767 GLfloat y,
5768 GLfloat z)
5769{
5770 return ValidateVertexAttribIndex(context, index);
5771}
5772
5773bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5774{
5775 return ValidateVertexAttribIndex(context, index);
5776}
5777
5778bool ValidateVertexAttrib4f(ValidationContext *context,
5779 GLuint index,
5780 GLfloat x,
5781 GLfloat y,
5782 GLfloat z,
5783 GLfloat w)
5784{
5785 return ValidateVertexAttribIndex(context, index);
5786}
5787
5788bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5789{
5790 return ValidateVertexAttribIndex(context, index);
5791}
5792
5793bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5794{
5795 if (width < 0 || height < 0)
5796 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005797 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005798 return false;
5799 }
5800
5801 return true;
5802}
5803
5804bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5805{
5806 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5807}
5808
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005809bool ValidateDrawElements(ValidationContext *context,
5810 GLenum mode,
5811 GLsizei count,
5812 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005813 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005814{
5815 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5816}
5817
Jamie Madillbe849e42017-05-02 15:49:00 -04005818bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context,
5819 GLenum target,
5820 GLenum attachment,
5821 GLenum pname,
5822 GLint *params)
5823{
5824 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5825 nullptr);
5826}
5827
5828bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5829{
5830 return ValidateGetProgramivBase(context, program, pname, nullptr);
5831}
5832
5833bool ValidateCopyTexImage2D(ValidationContext *context,
5834 GLenum target,
5835 GLint level,
5836 GLenum internalformat,
5837 GLint x,
5838 GLint y,
5839 GLsizei width,
5840 GLsizei height,
5841 GLint border)
5842{
5843 if (context->getClientMajorVersion() < 3)
5844 {
5845 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5846 0, x, y, width, height, border);
5847 }
5848
5849 ASSERT(context->getClientMajorVersion() == 3);
5850 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5851 0, x, y, width, height, border);
5852}
5853
5854bool ValidateCopyTexSubImage2D(Context *context,
5855 GLenum target,
5856 GLint level,
5857 GLint xoffset,
5858 GLint yoffset,
5859 GLint x,
5860 GLint y,
5861 GLsizei width,
5862 GLsizei height)
5863{
5864 if (context->getClientMajorVersion() < 3)
5865 {
5866 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5867 yoffset, x, y, width, height, 0);
5868 }
5869
5870 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5871 yoffset, 0, x, y, width, height, 0);
5872}
5873
5874bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5875{
5876 return ValidateGenOrDelete(context, n);
5877}
5878
5879bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5880{
5881 return ValidateGenOrDelete(context, n);
5882}
5883
5884bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5885{
5886 return ValidateGenOrDelete(context, n);
5887}
5888
5889bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5890{
5891 return ValidateGenOrDelete(context, n);
5892}
5893
5894bool ValidateDisable(Context *context, GLenum cap)
5895{
5896 if (!ValidCap(context, cap, false))
5897 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005898 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005899 return false;
5900 }
5901
5902 return true;
5903}
5904
5905bool ValidateEnable(Context *context, GLenum cap)
5906{
5907 if (!ValidCap(context, cap, false))
5908 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005909 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005910 return false;
5911 }
5912
5913 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5914 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5915 {
5916 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005917 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005918
5919 // We also output an error message to the debugger window if tracing is active, so that
5920 // developers can see the error message.
5921 ERR() << errorMessage;
5922 return false;
5923 }
5924
5925 return true;
5926}
5927
5928bool ValidateFramebufferRenderbuffer(Context *context,
5929 GLenum target,
5930 GLenum attachment,
5931 GLenum renderbuffertarget,
5932 GLuint renderbuffer)
5933{
Brandon Jones6cad5662017-06-14 13:25:13 -07005934 if (!ValidFramebufferTarget(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005935 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005936 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5937 return false;
5938 }
5939
5940 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5941 {
5942 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005943 return false;
5944 }
5945
5946 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5947 renderbuffertarget, renderbuffer);
5948}
5949
5950bool ValidateFramebufferTexture2D(Context *context,
5951 GLenum target,
5952 GLenum attachment,
5953 GLenum textarget,
5954 GLuint texture,
5955 GLint level)
5956{
5957 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5958 // extension
5959 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5960 level != 0)
5961 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005962 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005963 return false;
5964 }
5965
5966 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5967 {
5968 return false;
5969 }
5970
5971 if (texture != 0)
5972 {
5973 gl::Texture *tex = context->getTexture(texture);
5974 ASSERT(tex);
5975
5976 const gl::Caps &caps = context->getCaps();
5977
5978 switch (textarget)
5979 {
5980 case GL_TEXTURE_2D:
5981 {
5982 if (level > gl::log2(caps.max2DTextureSize))
5983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005984 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005985 return false;
5986 }
5987 if (tex->getTarget() != GL_TEXTURE_2D)
5988 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005989 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005990 return false;
5991 }
5992 }
5993 break;
5994
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005995 case GL_TEXTURE_RECTANGLE_ANGLE:
5996 {
5997 if (level != 0)
5998 {
5999 context->handleError(InvalidValue());
6000 return false;
6001 }
6002 if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE)
6003 {
6004 context->handleError(InvalidOperation()
6005 << "Textarget must match the texture target type.");
6006 return false;
6007 }
6008 }
6009 break;
6010
Jamie Madillbe849e42017-05-02 15:49:00 -04006011 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
6012 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
6013 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
6014 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
6015 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
6016 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
6017 {
6018 if (level > gl::log2(caps.maxCubeMapTextureSize))
6019 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006020 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006021 return false;
6022 }
6023 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
6024 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006025 context->handleError(InvalidOperation()
6026 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006027 return false;
6028 }
6029 }
6030 break;
6031
6032 case GL_TEXTURE_2D_MULTISAMPLE:
6033 {
6034 if (context->getClientVersion() < ES_3_1)
6035 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006036 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 return false;
6038 }
6039
6040 if (level != 0)
6041 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006042 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006043 return false;
6044 }
6045 if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE)
6046 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006047 context->handleError(InvalidOperation()
6048 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 return false;
6050 }
6051 }
6052 break;
6053
6054 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006055 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006056 return false;
6057 }
6058
6059 const Format &format = tex->getFormat(textarget, level);
6060 if (format.info->compressed)
6061 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006062 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006063 return false;
6064 }
6065 }
6066
6067 return true;
6068}
6069
6070bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6071{
6072 return ValidateGenOrDelete(context, n);
6073}
6074
6075bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6076{
6077 return ValidateGenOrDelete(context, n);
6078}
6079
6080bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6081{
6082 return ValidateGenOrDelete(context, n);
6083}
6084
6085bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6086{
6087 return ValidateGenOrDelete(context, n);
6088}
6089
6090bool ValidateGenerateMipmap(Context *context, GLenum target)
6091{
6092 if (!ValidTextureTarget(context, target))
6093 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006094 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006095 return false;
6096 }
6097
6098 Texture *texture = context->getTargetTexture(target);
6099
6100 if (texture == nullptr)
6101 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006102 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006103 return false;
6104 }
6105
6106 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6107
6108 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6109 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6110 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6111 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006112 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006113 return false;
6114 }
6115
6116 GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
Geoff Lang536eca12017-09-13 11:23:35 -04006117 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6118 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6119 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006120 {
6121 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6122 return false;
6123 }
6124
Geoff Lang536eca12017-09-13 11:23:35 -04006125 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6126 bool formatUnsized = !format.sized;
6127 bool formatColorRenderableAndFilterable =
6128 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6129 format.renderSupport(context->getClientVersion(), context->getExtensions());
6130 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006131 {
Geoff Lang536eca12017-09-13 11:23:35 -04006132 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006133 return false;
6134 }
6135
Geoff Lang536eca12017-09-13 11:23:35 -04006136 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6137 // generation
6138 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6139 {
6140 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6141 return false;
6142 }
6143
6144 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6145 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006146 bool supportsSRGBMipmapGeneration =
6147 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006148 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006149 {
Geoff Lang536eca12017-09-13 11:23:35 -04006150 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006151 return false;
6152 }
6153
6154 // Non-power of 2 ES2 check
6155 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6156 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6157 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6158 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006159 ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ANGLE ||
6160 target == GL_TEXTURE_CUBE_MAP);
Brandon Jones6cad5662017-06-14 13:25:13 -07006161 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006162 return false;
6163 }
6164
6165 // Cube completeness check
6166 if (target == GL_TEXTURE_CUBE_MAP && !texture->getTextureState().isCubeComplete())
6167 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006168 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006169 return false;
6170 }
6171
6172 return true;
6173}
6174
6175bool ValidateGetBufferParameteriv(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006176 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006177 GLenum pname,
6178 GLint *params)
6179{
6180 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6181}
6182
6183bool ValidateGetRenderbufferParameteriv(Context *context,
6184 GLenum target,
6185 GLenum pname,
6186 GLint *params)
6187{
6188 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6189}
6190
6191bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6192{
6193 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6194}
6195
6196bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params)
6197{
6198 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6199}
6200
6201bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
6202{
6203 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6204}
6205
6206bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6207{
6208 return ValidateGetUniformBase(context, program, location);
6209}
6210
6211bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6212{
6213 return ValidateGetUniformBase(context, program, location);
6214}
6215
6216bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6217{
6218 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6219}
6220
6221bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6222{
6223 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6224}
6225
6226bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6227{
6228 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6229}
6230
6231bool ValidateIsEnabled(Context *context, GLenum cap)
6232{
6233 if (!ValidCap(context, cap, true))
6234 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006235 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006236 return false;
6237 }
6238
6239 return true;
6240}
6241
6242bool ValidateLinkProgram(Context *context, GLuint program)
6243{
6244 if (context->hasActiveTransformFeedback(program))
6245 {
6246 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006247 context->handleError(InvalidOperation() << "Cannot link program while program is "
6248 "associated with an active transform "
6249 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006250 return false;
6251 }
6252
6253 Program *programObject = GetValidProgram(context, program);
6254 if (!programObject)
6255 {
6256 return false;
6257 }
6258
6259 return true;
6260}
6261
Jamie Madill4928b7c2017-06-20 12:57:39 -04006262bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006263 GLint x,
6264 GLint y,
6265 GLsizei width,
6266 GLsizei height,
6267 GLenum format,
6268 GLenum type,
6269 void *pixels)
6270{
6271 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6272 nullptr, pixels);
6273}
6274
6275bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param)
6276{
6277 return ValidateTexParameterBase(context, target, pname, -1, &param);
6278}
6279
6280bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params)
6281{
6282 return ValidateTexParameterBase(context, target, pname, -1, params);
6283}
6284
6285bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param)
6286{
6287 return ValidateTexParameterBase(context, target, pname, -1, &param);
6288}
6289
6290bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params)
6291{
6292 return ValidateTexParameterBase(context, target, pname, -1, params);
6293}
6294
6295bool ValidateUseProgram(Context *context, GLuint program)
6296{
6297 if (program != 0)
6298 {
6299 Program *programObject = context->getProgram(program);
6300 if (!programObject)
6301 {
6302 // ES 3.1.0 section 7.3 page 72
6303 if (context->getShader(program))
6304 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006306 return false;
6307 }
6308 else
6309 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006310 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006311 return false;
6312 }
6313 }
6314 if (!programObject->isLinked())
6315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006317 return false;
6318 }
6319 }
6320 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6321 {
6322 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006323 context
6324 ->handleError(InvalidOperation()
6325 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006326 return false;
6327 }
6328
6329 return true;
6330}
6331
Jamie Madillc29968b2016-01-20 11:17:23 -05006332} // namespace gl