blob: e754e5d8031f058bc20130b2a300c72085b1682b [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 Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070078 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030079 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700291 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400292 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700293 }
294
Geoff Langc0094ec2017-08-16 14:16:24 -0400295 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
296 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700297 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Langc0094ec2017-08-16 14:16:24 -0400298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700304 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400305 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700306 }
307
308 return true;
309}
310
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800311bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700312{
313 switch (target)
314 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800315 case TextureTarget::_2D:
316 case TextureTarget::CubeMapNegativeX:
317 case TextureTarget::CubeMapNegativeY:
318 case TextureTarget::CubeMapNegativeZ:
319 case TextureTarget::CubeMapPositiveX:
320 case TextureTarget::CubeMapPositiveY:
321 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400322 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700323
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800324 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400325 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700326
327 default:
328 return false;
329 }
330}
331
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800332bool IsValidCopyTextureDestinationTarget(Context *context,
333 TextureType textureType,
334 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400335{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800336 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400337}
338
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800339bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700340{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800341 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700342 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800343 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400344 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800345 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400346 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400347
348 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
349 // supported
350
351 default:
352 return false;
353 }
354}
355
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800356bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400357{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800358 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400359 {
360 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700361 }
362
Geoff Lang4f0e0032017-05-01 16:04:35 -0400363 if (level > 0 && context->getClientVersion() < ES_3_0)
364 {
365 return false;
366 }
Geoff Lang97073d12016-04-20 10:42:34 -0700367
Geoff Lang4f0e0032017-05-01 16:04:35 -0400368 return true;
369}
370
371bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800372 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400373 GLint level,
374 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800375 GLsizei height,
376 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400377{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800378 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400379 {
380 return false;
381 }
382
Brandon Jones28783792018-03-05 09:37:32 -0800383 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
384 {
385 return false;
386 }
387
Geoff Lang4f0e0032017-05-01 16:04:35 -0400388 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800389 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400390 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800391 case TextureType::_2D:
392 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
393 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
394 case TextureType::Rectangle:
395 ASSERT(level == 0);
396 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
397 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400398
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800399 case TextureType::CubeMap:
400 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
401 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
402 default:
403 return true;
404 }
Geoff Lang97073d12016-04-20 10:42:34 -0700405}
406
Jamie Madillc1d770e2017-04-13 17:31:24 -0400407bool IsValidStencilFunc(GLenum func)
408{
409 switch (func)
410 {
411 case GL_NEVER:
412 case GL_ALWAYS:
413 case GL_LESS:
414 case GL_LEQUAL:
415 case GL_EQUAL:
416 case GL_GEQUAL:
417 case GL_GREATER:
418 case GL_NOTEQUAL:
419 return true;
420
421 default:
422 return false;
423 }
424}
425
426bool IsValidStencilFace(GLenum face)
427{
428 switch (face)
429 {
430 case GL_FRONT:
431 case GL_BACK:
432 case GL_FRONT_AND_BACK:
433 return true;
434
435 default:
436 return false;
437 }
438}
439
440bool IsValidStencilOp(GLenum op)
441{
442 switch (op)
443 {
444 case GL_ZERO:
445 case GL_KEEP:
446 case GL_REPLACE:
447 case GL_INCR:
448 case GL_DECR:
449 case GL_INVERT:
450 case GL_INCR_WRAP:
451 case GL_DECR_WRAP:
452 return true;
453
454 default:
455 return false;
456 }
457}
458
Jamie Madill5b772312018-03-08 20:28:32 -0500459bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800460 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400461 GLint level,
462 GLenum internalformat,
463 bool isSubImage,
464 GLint xoffset,
465 GLint yoffset,
466 GLint x,
467 GLint y,
468 GLsizei width,
469 GLsizei height,
470 GLint border)
471{
472 if (!ValidTexture2DDestinationTarget(context, target))
473 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700474 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400475 return false;
476 }
477
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800478 TextureType texType = TextureTargetToType(target);
479 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400480 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500481 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400482 return false;
483 }
484
485 Format textureFormat = Format::Invalid();
486 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
487 xoffset, yoffset, 0, x, y, width, height, border,
488 &textureFormat))
489 {
490 return false;
491 }
492
493 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
494 GLenum colorbufferFormat =
495 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
496 const auto &formatInfo = *textureFormat.info;
497
498 // [OpenGL ES 2.0.24] table 3.9
499 if (isSubImage)
500 {
501 switch (formatInfo.format)
502 {
503 case GL_ALPHA:
504 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400505 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
506 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400507 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400509 return false;
510 }
511 break;
512 case GL_LUMINANCE:
513 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
514 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
515 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400516 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
517 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400518 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700519 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400520 return false;
521 }
522 break;
523 case GL_RED_EXT:
524 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
525 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
526 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
527 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
528 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400529 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
530 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400531 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700532 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400533 return false;
534 }
535 break;
536 case GL_RG_EXT:
537 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
538 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
539 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
540 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400541 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
542 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400543 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700544 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400545 return false;
546 }
547 break;
548 case GL_RGB:
549 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
550 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
551 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400552 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
553 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400554 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700555 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400556 return false;
557 }
558 break;
559 case GL_LUMINANCE_ALPHA:
560 case GL_RGBA:
561 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400562 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
563 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400564 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700565 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400566 return false;
567 }
568 break;
569 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
571 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
572 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
573 case GL_ETC1_RGB8_OES:
574 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
575 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
578 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +0300579 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
580 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
581 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
582 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Brandon Jones6cad5662017-06-14 13:25:13 -0700583 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400584 return false;
585 case GL_DEPTH_COMPONENT:
586 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700587 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400588 return false;
589 default:
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 }
593
594 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
595 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700596 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400597 return false;
598 }
599 }
600 else
601 {
602 switch (internalformat)
603 {
604 case GL_ALPHA:
605 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
606 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
607 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
608 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700609 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400610 return false;
611 }
612 break;
613 case GL_LUMINANCE:
614 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
615 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
616 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
617 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
618 colorbufferFormat != GL_BGR5_A1_ANGLEX)
619 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700620 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400621 return false;
622 }
623 break;
624 case GL_RED_EXT:
625 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
626 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
627 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
628 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
629 colorbufferFormat != GL_BGR5_A1_ANGLEX)
630 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700631 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400632 return false;
633 }
634 break;
635 case GL_RG_EXT:
636 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
637 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
638 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
639 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
640 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700641 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400642 return false;
643 }
644 break;
645 case GL_RGB:
646 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
647 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
648 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
649 colorbufferFormat != GL_BGR5_A1_ANGLEX)
650 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700651 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400652 return false;
653 }
654 break;
655 case GL_LUMINANCE_ALPHA:
656 case GL_RGBA:
657 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
658 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
659 colorbufferFormat != GL_BGR5_A1_ANGLEX)
660 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700661 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400662 return false;
663 }
664 break;
665 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
666 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
667 if (context->getExtensions().textureCompressionDXT1)
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 else
673 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700674 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400675 return false;
676 }
677 break;
678 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
679 if (context->getExtensions().textureCompressionDXT3)
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 else
685 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700686 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400687 return false;
688 }
689 break;
690 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
691 if (context->getExtensions().textureCompressionDXT5)
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 else
697 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700698 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400699 return false;
700 }
701 break;
702 case GL_ETC1_RGB8_OES:
703 if (context->getExtensions().compressedETC1RGB8Texture)
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 else
709 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500710 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400711 return false;
712 }
713 break;
714 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
715 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
716 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
717 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
718 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
719 if (context->getExtensions().lossyETCDecode)
720 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500721 context->handleError(InvalidOperation()
722 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400723 return false;
724 }
725 else
726 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500727 context->handleError(InvalidEnum()
728 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400729 return false;
730 }
731 break;
732 case GL_DEPTH_COMPONENT:
733 case GL_DEPTH_COMPONENT16:
734 case GL_DEPTH_COMPONENT32_OES:
735 case GL_DEPTH_STENCIL_OES:
736 case GL_DEPTH24_STENCIL8_OES:
737 if (context->getExtensions().depthTextures)
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 else
743 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500744 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400745 return false;
746 }
747 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500748 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400749 return false;
750 }
751 }
752
753 // If width or height is zero, it is a no-op. Return false without setting an error.
754 return (width > 0 && height > 0);
755}
756
757bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
758{
759 switch (cap)
760 {
761 // EXT_multisample_compatibility
762 case GL_MULTISAMPLE_EXT:
763 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
764 return context->getExtensions().multisampleCompatibility;
765
766 case GL_CULL_FACE:
767 case GL_POLYGON_OFFSET_FILL:
768 case GL_SAMPLE_ALPHA_TO_COVERAGE:
769 case GL_SAMPLE_COVERAGE:
770 case GL_SCISSOR_TEST:
771 case GL_STENCIL_TEST:
772 case GL_DEPTH_TEST:
773 case GL_BLEND:
774 case GL_DITHER:
775 return true;
776
777 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
778 case GL_RASTERIZER_DISCARD:
779 return (context->getClientMajorVersion() >= 3);
780
781 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
782 case GL_DEBUG_OUTPUT:
783 return context->getExtensions().debug;
784
785 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
786 return queryOnly && context->getExtensions().bindGeneratesResource;
787
788 case GL_CLIENT_ARRAYS_ANGLE:
789 return queryOnly && context->getExtensions().clientArrays;
790
791 case GL_FRAMEBUFFER_SRGB_EXT:
792 return context->getExtensions().sRGBWriteControl;
793
794 case GL_SAMPLE_MASK:
795 return context->getClientVersion() >= Version(3, 1);
796
Geoff Langb433e872017-10-05 14:01:47 -0400797 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400798 return queryOnly && context->getExtensions().robustResourceInitialization;
799
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700800 // GLES1 emulation: GLES1-specific caps
801 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700802 case GL_VERTEX_ARRAY:
803 case GL_NORMAL_ARRAY:
804 case GL_COLOR_ARRAY:
805 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700806 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700807 case GL_LIGHTING:
808 case GL_LIGHT0:
809 case GL_LIGHT1:
810 case GL_LIGHT2:
811 case GL_LIGHT3:
812 case GL_LIGHT4:
813 case GL_LIGHT5:
814 case GL_LIGHT6:
815 case GL_LIGHT7:
816 case GL_NORMALIZE:
817 case GL_RESCALE_NORMAL:
818 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700819 case GL_CLIP_PLANE0:
820 case GL_CLIP_PLANE1:
821 case GL_CLIP_PLANE2:
822 case GL_CLIP_PLANE3:
823 case GL_CLIP_PLANE4:
824 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700825 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700826 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700827 case GL_LINE_SMOOTH:
828 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700829 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700830 case GL_POINT_SIZE_ARRAY_OES:
831 return context->getClientVersion() < Version(2, 0) &&
832 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700833 case GL_TEXTURE_CUBE_MAP:
834 return context->getClientVersion() < Version(2, 0) &&
835 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700836 case GL_POINT_SPRITE_OES:
837 return context->getClientVersion() < Version(2, 0) &&
838 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400839 default:
840 return false;
841 }
842}
843
Geoff Langfc32e8b2017-05-31 14:16:59 -0400844// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
845// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400846bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400847{
848 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400849 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
850 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400851 {
852 return true;
853 }
854
855 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
856 if (c >= 9 && c <= 13)
857 {
858 return true;
859 }
860
861 return false;
862}
863
Geoff Langcab92ee2017-07-19 17:32:07 -0400864bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400865{
Geoff Langa71a98e2017-06-19 15:15:00 -0400866 for (size_t i = 0; i < len; i++)
867 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400868 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400869 {
870 return false;
871 }
872 }
873
874 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400875}
876
Geoff Langcab92ee2017-07-19 17:32:07 -0400877bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
878{
879 enum class ParseState
880 {
881 // Have not seen an ASCII non-whitespace character yet on
882 // this line. Possible that we might see a preprocessor
883 // directive.
884 BEGINING_OF_LINE,
885
886 // Have seen at least one ASCII non-whitespace character
887 // on this line.
888 MIDDLE_OF_LINE,
889
890 // Handling a preprocessor directive. Passes through all
891 // characters up to the end of the line. Disables comment
892 // processing.
893 IN_PREPROCESSOR_DIRECTIVE,
894
895 // Handling a single-line comment. The comment text is
896 // replaced with a single space.
897 IN_SINGLE_LINE_COMMENT,
898
899 // Handling a multi-line comment. Newlines are passed
900 // through to preserve line numbers.
901 IN_MULTI_LINE_COMMENT
902 };
903
904 ParseState state = ParseState::BEGINING_OF_LINE;
905 size_t pos = 0;
906
907 while (pos < len)
908 {
909 char c = str[pos];
910 char next = pos + 1 < len ? str[pos + 1] : 0;
911
912 // Check for newlines
913 if (c == '\n' || c == '\r')
914 {
915 if (state != ParseState::IN_MULTI_LINE_COMMENT)
916 {
917 state = ParseState::BEGINING_OF_LINE;
918 }
919
920 pos++;
921 continue;
922 }
923
924 switch (state)
925 {
926 case ParseState::BEGINING_OF_LINE:
927 if (c == ' ')
928 {
929 // Maintain the BEGINING_OF_LINE state until a non-space is seen
930 pos++;
931 }
932 else if (c == '#')
933 {
934 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
935 pos++;
936 }
937 else
938 {
939 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
940 state = ParseState::MIDDLE_OF_LINE;
941 }
942 break;
943
944 case ParseState::MIDDLE_OF_LINE:
945 if (c == '/' && next == '/')
946 {
947 state = ParseState::IN_SINGLE_LINE_COMMENT;
948 pos++;
949 }
950 else if (c == '/' && next == '*')
951 {
952 state = ParseState::IN_MULTI_LINE_COMMENT;
953 pos++;
954 }
955 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
956 {
957 // Skip line continuation characters
958 }
959 else if (!IsValidESSLCharacter(c))
960 {
961 return false;
962 }
963 pos++;
964 break;
965
966 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700967 // Line-continuation characters may not be permitted.
968 // Otherwise, just pass it through. Do not parse comments in this state.
969 if (!lineContinuationAllowed && c == '\\')
970 {
971 return false;
972 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400973 pos++;
974 break;
975
976 case ParseState::IN_SINGLE_LINE_COMMENT:
977 // Line-continuation characters are processed before comment processing.
978 // Advance string if a new line character is immediately behind
979 // line-continuation character.
980 if (c == '\\' && (next == '\n' || next == '\r'))
981 {
982 pos++;
983 }
984 pos++;
985 break;
986
987 case ParseState::IN_MULTI_LINE_COMMENT:
988 if (c == '*' && next == '/')
989 {
990 state = ParseState::MIDDLE_OF_LINE;
991 pos++;
992 }
993 pos++;
994 break;
995 }
996 }
997
998 return true;
999}
1000
Jamie Madill5b772312018-03-08 20:28:32 -05001001bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001002{
1003 ASSERT(context->isWebGL());
1004
1005 // WebGL 1.0 [Section 6.16] GLSL Constructs
1006 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1007 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1008 {
1009 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1010 return false;
1011 }
1012
1013 return true;
1014}
1015
Jamie Madill5b772312018-03-08 20:28:32 -05001016bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001017{
1018 ASSERT(context->isWebGL());
1019
1020 if (context->isWebGL1() && length > 256)
1021 {
1022 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1023 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1024 // locations.
1025 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1026
1027 return false;
1028 }
1029 else if (length > 1024)
1030 {
1031 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1032 // uniform and attribute locations.
1033 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1034 return false;
1035 }
1036
1037 return true;
1038}
1039
Jamie Madill007530e2017-12-28 14:27:04 -05001040bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1041{
1042 if (!context->getExtensions().pathRendering)
1043 {
1044 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1045 return false;
1046 }
1047
1048 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1049 {
1050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1051 return false;
1052 }
1053 return true;
1054}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001055
1056bool ValidBlendFunc(const Context *context, GLenum val)
1057{
1058 const gl::Extensions &ext = context->getExtensions();
1059
1060 // these are always valid for src and dst.
1061 switch (val)
1062 {
1063 case GL_ZERO:
1064 case GL_ONE:
1065 case GL_SRC_COLOR:
1066 case GL_ONE_MINUS_SRC_COLOR:
1067 case GL_DST_COLOR:
1068 case GL_ONE_MINUS_DST_COLOR:
1069 case GL_SRC_ALPHA:
1070 case GL_ONE_MINUS_SRC_ALPHA:
1071 case GL_DST_ALPHA:
1072 case GL_ONE_MINUS_DST_ALPHA:
1073 case GL_CONSTANT_COLOR:
1074 case GL_ONE_MINUS_CONSTANT_COLOR:
1075 case GL_CONSTANT_ALPHA:
1076 case GL_ONE_MINUS_CONSTANT_ALPHA:
1077 return true;
1078
1079 // EXT_blend_func_extended.
1080 case GL_SRC1_COLOR_EXT:
1081 case GL_SRC1_ALPHA_EXT:
1082 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1083 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1084 case GL_SRC_ALPHA_SATURATE_EXT:
1085 return ext.blendFuncExtended;
1086
1087 default:
1088 return false;
1089 }
1090}
1091
1092bool ValidSrcBlendFunc(const Context *context, GLenum val)
1093{
1094 if (ValidBlendFunc(context, val))
1095 return true;
1096
1097 if (val == GL_SRC_ALPHA_SATURATE)
1098 return true;
1099
1100 return false;
1101}
1102
1103bool ValidDstBlendFunc(const Context *context, GLenum val)
1104{
1105 if (ValidBlendFunc(context, val))
1106 return true;
1107
1108 if (val == GL_SRC_ALPHA_SATURATE)
1109 {
1110 if (context->getClientMajorVersion() >= 3)
1111 return true;
1112 }
1113
1114 return false;
1115}
1116
Jamie Madillac66f982018-10-09 18:30:01 -04001117void RecordBindTextureTypeError(Context *context, TextureType target)
1118{
1119 ASSERT(!context->getStateCache().isValidBindTextureType(target));
1120
1121 switch (target)
1122 {
1123 case TextureType::Rectangle:
1124 ASSERT(!context->getExtensions().textureRectangle);
1125 context->handleError(InvalidEnum()
1126 << "Context does not support GL_ANGLE_texture_rectangle");
1127 break;
1128
1129 case TextureType::_3D:
1130 case TextureType::_2DArray:
1131 ASSERT(context->getClientMajorVersion() < 3);
1132 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
1133 break;
1134
1135 case TextureType::_2DMultisample:
Yizhou Jiang7818a852018-09-06 15:02:04 +08001136 ASSERT(context->getClientVersion() < Version(3, 1) &&
1137 !context->getExtensions().textureMultisample);
1138 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleTextureExtensionOrES31Required);
Jamie Madillac66f982018-10-09 18:30:01 -04001139 break;
1140
1141 case TextureType::_2DMultisampleArray:
1142 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
1143 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
1144 break;
1145
1146 case TextureType::External:
1147 ASSERT(!context->getExtensions().eglImageExternal &&
1148 !context->getExtensions().eglStreamConsumerExternal);
1149 context->handleError(InvalidEnum() << "External texture extension not enabled");
1150 break;
1151
1152 default:
1153 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
1154 }
1155}
Jamie Madillc29968b2016-01-20 11:17:23 -05001156} // anonymous namespace
1157
Geoff Langff5b2d52016-09-07 11:32:23 -04001158bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001159 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001160 GLint level,
1161 GLenum internalformat,
1162 bool isCompressed,
1163 bool isSubImage,
1164 GLint xoffset,
1165 GLint yoffset,
1166 GLsizei width,
1167 GLsizei height,
1168 GLint border,
1169 GLenum format,
1170 GLenum type,
1171 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001172 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001173{
Jamie Madill6f38f822014-06-06 17:12:20 -04001174 if (!ValidTexture2DDestinationTarget(context, target))
1175 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001176 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001177 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001178 }
1179
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001180 TextureType texType = TextureTargetToType(target);
1181 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001182 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001183 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001184 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001185 }
1186
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001187 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001188 {
1189 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1190 return false;
1191 }
1192
1193 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001194 std::numeric_limits<GLsizei>::max() - yoffset < height)
1195 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001196 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001197 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001198 }
1199
Geoff Lang6e898aa2017-06-02 11:17:26 -04001200 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1201 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1202 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1203 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1204 // case.
1205 bool nonEqualFormatsAllowed =
1206 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1207 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1208
1209 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001210 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001211 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001212 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001213 }
1214
Geoff Langaae65a42014-05-26 12:43:44 -04001215 const gl::Caps &caps = context->getCaps();
1216
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001217 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001218 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001219 case TextureType::_2D:
1220 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1221 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1222 {
1223 context->handleError(InvalidValue());
1224 return false;
1225 }
1226 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001227
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001228 case TextureType::Rectangle:
1229 ASSERT(level == 0);
1230 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1231 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1232 {
1233 context->handleError(InvalidValue());
1234 return false;
1235 }
1236 if (isCompressed)
1237 {
1238 context->handleError(InvalidEnum()
1239 << "Rectangle texture cannot have a compressed format.");
1240 return false;
1241 }
1242 break;
1243
1244 case TextureType::CubeMap:
1245 if (!isSubImage && width != height)
1246 {
1247 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1248 return false;
1249 }
1250
1251 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1252 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1253 {
1254 context->handleError(InvalidValue());
1255 return false;
1256 }
1257 break;
1258
1259 default:
1260 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001261 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001262 }
1263
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001264 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001265 if (!texture)
1266 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001267 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001268 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001269 }
1270
Geoff Langa9be0dc2014-12-17 12:34:40 -05001271 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001272 {
Geoff Langca271392017-04-05 12:30:00 -04001273 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1274 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001275 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001276 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001277 return false;
1278 }
1279
Geoff Langa9be0dc2014-12-17 12:34:40 -05001280 if (format != GL_NONE)
1281 {
Geoff Langca271392017-04-05 12:30:00 -04001282 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1283 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001284 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001285 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001286 return false;
1287 }
1288 }
1289
1290 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1291 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1292 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001293 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001294 return false;
1295 }
Geoff Langfb052642017-10-24 13:42:09 -04001296
1297 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001298 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001299 {
1300 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1301 return false;
1302 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001303 }
1304 else
1305 {
Geoff Lang69cce582015-09-17 13:20:36 -04001306 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001307 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001308 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001309 return false;
1310 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001311 }
1312
1313 // Verify zero border
1314 if (border != 0)
1315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001316 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001317 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001318 }
1319
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001320 if (isCompressed)
1321 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001322 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001323 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1324 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001325
1326 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1327
1328 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329 {
Geoff Lange88e4542018-05-03 15:05:57 -04001330 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1331 return false;
1332 }
1333
1334 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1335 context->getExtensions()))
1336 {
1337 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1338 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001339 }
Geoff Lang966c9402017-04-18 12:38:27 -04001340
1341 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001342 {
Geoff Lange88e4542018-05-03 15:05:57 -04001343 // From the OES_compressed_ETC1_RGB8_texture spec:
1344 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1345 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1346 // ETC1_RGB8_OES.
1347 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1348 {
1349 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1350 return false;
1351 }
1352
Geoff Lang966c9402017-04-18 12:38:27 -04001353 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1354 height, texture->getWidth(target, level),
1355 texture->getHeight(target, level)))
1356 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001357 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001358 return false;
1359 }
1360
1361 if (format != actualInternalFormat)
1362 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001363 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001364 return false;
1365 }
1366 }
1367 else
1368 {
1369 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1370 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001371 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001372 return false;
1373 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001374 }
1375 }
1376 else
1377 {
1378 // validate <type> by itself (used as secondary key below)
1379 switch (type)
1380 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001381 case GL_UNSIGNED_BYTE:
1382 case GL_UNSIGNED_SHORT_5_6_5:
1383 case GL_UNSIGNED_SHORT_4_4_4_4:
1384 case GL_UNSIGNED_SHORT_5_5_5_1:
1385 case GL_UNSIGNED_SHORT:
1386 case GL_UNSIGNED_INT:
1387 case GL_UNSIGNED_INT_24_8_OES:
1388 case GL_HALF_FLOAT_OES:
1389 case GL_FLOAT:
1390 break;
1391 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001392 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001393 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001394 }
1395
1396 // validate <format> + <type> combinations
1397 // - invalid <format> -> sets INVALID_ENUM
1398 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1399 switch (format)
1400 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001401 case GL_ALPHA:
1402 case GL_LUMINANCE:
1403 case GL_LUMINANCE_ALPHA:
1404 switch (type)
1405 {
1406 case GL_UNSIGNED_BYTE:
1407 case GL_FLOAT:
1408 case GL_HALF_FLOAT_OES:
1409 break;
1410 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001411 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001412 return false;
1413 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001414 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001415 case GL_RED:
1416 case GL_RG:
1417 if (!context->getExtensions().textureRG)
1418 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001419 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001420 return false;
1421 }
1422 switch (type)
1423 {
1424 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001425 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001426 case GL_FLOAT:
1427 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001428 if (!context->getExtensions().textureFloat)
1429 {
1430 context->handleError(InvalidEnum());
1431 return false;
1432 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 break;
1434 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001435 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001436 return false;
1437 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001438 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001439 case GL_RGB:
1440 switch (type)
1441 {
1442 case GL_UNSIGNED_BYTE:
1443 case GL_UNSIGNED_SHORT_5_6_5:
1444 case GL_FLOAT:
1445 case GL_HALF_FLOAT_OES:
1446 break;
1447 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001448 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001449 return false;
1450 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001451 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001452 case GL_RGBA:
1453 switch (type)
1454 {
1455 case GL_UNSIGNED_BYTE:
1456 case GL_UNSIGNED_SHORT_4_4_4_4:
1457 case GL_UNSIGNED_SHORT_5_5_5_1:
1458 case GL_FLOAT:
1459 case GL_HALF_FLOAT_OES:
1460 break;
1461 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001462 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001463 return false;
1464 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001465 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001466 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001467 if (!context->getExtensions().textureFormatBGRA8888)
1468 {
1469 context->handleError(InvalidEnum());
1470 return false;
1471 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001472 switch (type)
1473 {
1474 case GL_UNSIGNED_BYTE:
1475 break;
1476 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001477 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001478 return false;
1479 }
1480 break;
1481 case GL_SRGB_EXT:
1482 case GL_SRGB_ALPHA_EXT:
1483 if (!context->getExtensions().sRGB)
1484 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001485 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001486 return false;
1487 }
1488 switch (type)
1489 {
1490 case GL_UNSIGNED_BYTE:
1491 break;
1492 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001493 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001494 return false;
1495 }
1496 break;
1497 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1498 // handled below
1499 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1500 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1501 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1502 break;
1503 case GL_DEPTH_COMPONENT:
1504 switch (type)
1505 {
1506 case GL_UNSIGNED_SHORT:
1507 case GL_UNSIGNED_INT:
1508 break;
1509 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001510 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001511 return false;
1512 }
1513 break;
1514 case GL_DEPTH_STENCIL_OES:
1515 switch (type)
1516 {
1517 case GL_UNSIGNED_INT_24_8_OES:
1518 break;
1519 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001520 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001521 return false;
1522 }
1523 break;
1524 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001525 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001526 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001527 }
1528
1529 switch (format)
1530 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001531 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1532 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1533 if (context->getExtensions().textureCompressionDXT1)
1534 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001535 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001536 return false;
1537 }
1538 else
1539 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001540 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001541 return false;
1542 }
1543 break;
1544 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1545 if (context->getExtensions().textureCompressionDXT3)
1546 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001547 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001548 return false;
1549 }
1550 else
1551 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001552 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001553 return false;
1554 }
1555 break;
1556 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1557 if (context->getExtensions().textureCompressionDXT5)
1558 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001559 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001560 return false;
1561 }
1562 else
1563 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001564 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001565 return false;
1566 }
1567 break;
1568 case GL_ETC1_RGB8_OES:
1569 if (context->getExtensions().compressedETC1RGB8Texture)
1570 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001571 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001572 return false;
1573 }
1574 else
1575 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001576 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001577 return false;
1578 }
1579 break;
1580 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001581 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1582 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1583 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1584 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001585 if (context->getExtensions().lossyETCDecode)
1586 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001587 context->handleError(InvalidOperation()
1588 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001589 return false;
1590 }
1591 else
1592 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001593 context->handleError(InvalidEnum()
1594 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001595 return false;
1596 }
1597 break;
1598 case GL_DEPTH_COMPONENT:
1599 case GL_DEPTH_STENCIL_OES:
1600 if (!context->getExtensions().depthTextures)
1601 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001602 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001603 return false;
1604 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001605 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001606 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001607 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001608 return false;
1609 }
1610 // OES_depth_texture supports loading depth data and multiple levels,
1611 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001612 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001613 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001614 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1615 return false;
1616 }
1617 if (level != 0)
1618 {
1619 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001620 return false;
1621 }
1622 break;
1623 default:
1624 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001625 }
1626
Geoff Lang6e898aa2017-06-02 11:17:26 -04001627 if (!isSubImage)
1628 {
1629 switch (internalformat)
1630 {
1631 case GL_RGBA32F:
1632 if (!context->getExtensions().colorBufferFloatRGBA)
1633 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001634 context->handleError(InvalidValue()
1635 << "Sized GL_RGBA32F internal format requires "
1636 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001637 return false;
1638 }
1639 if (type != GL_FLOAT)
1640 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001641 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001642 return false;
1643 }
1644 if (format != GL_RGBA)
1645 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001647 return false;
1648 }
1649 break;
1650
1651 case GL_RGB32F:
1652 if (!context->getExtensions().colorBufferFloatRGB)
1653 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001654 context->handleError(InvalidValue()
1655 << "Sized GL_RGB32F internal format requires "
1656 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001657 return false;
1658 }
1659 if (type != GL_FLOAT)
1660 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001661 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001662 return false;
1663 }
1664 if (format != GL_RGB)
1665 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001666 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001667 return false;
1668 }
1669 break;
1670
1671 default:
1672 break;
1673 }
1674 }
1675
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001676 if (type == GL_FLOAT)
1677 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001678 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001679 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001680 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001681 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001682 }
1683 }
1684 else if (type == GL_HALF_FLOAT_OES)
1685 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001686 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001687 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001688 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001689 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001690 }
1691 }
1692 }
1693
Geoff Langdbcced82017-06-06 15:55:54 -04001694 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001695 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001696 imageSize))
1697 {
1698 return false;
1699 }
1700
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001701 return true;
1702}
1703
He Yunchaoced53ae2016-11-29 15:00:51 +08001704bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001705 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001706 GLsizei levels,
1707 GLenum internalformat,
1708 GLsizei width,
1709 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001710{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001711 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1712 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001713 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001714 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001715 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001716 }
1717
1718 if (width < 1 || height < 1 || levels < 1)
1719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001720 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001721 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001722 }
1723
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001724 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001725 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001726 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001727 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001728 }
1729
1730 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1731 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001732 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001733 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001734 }
1735
Geoff Langca271392017-04-05 12:30:00 -04001736 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001737 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001739 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001740 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001741 }
1742
Geoff Langaae65a42014-05-26 12:43:44 -04001743 const gl::Caps &caps = context->getCaps();
1744
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001745 switch (target)
1746 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001747 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001748 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1749 static_cast<GLuint>(height) > caps.max2DTextureSize)
1750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001751 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001752 return false;
1753 }
1754 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001755 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001756 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1757 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1758 {
1759 context->handleError(InvalidValue());
1760 return false;
1761 }
1762 if (formatInfo.compressed)
1763 {
1764 context->handleError(InvalidEnum()
1765 << "Rectangle texture cannot have a compressed format.");
1766 return false;
1767 }
1768 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001769 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001770 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1771 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1772 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001773 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001774 return false;
1775 }
1776 break;
1777 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001778 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001779 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001780 }
1781
Geoff Langc0b9ef42014-07-02 10:02:37 -04001782 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001783 {
1784 if (!gl::isPow2(width) || !gl::isPow2(height))
1785 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001786 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001787 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001788 }
1789 }
1790
1791 switch (internalformat)
1792 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001793 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1794 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1795 if (!context->getExtensions().textureCompressionDXT1)
1796 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001797 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001798 return false;
1799 }
1800 break;
1801 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1802 if (!context->getExtensions().textureCompressionDXT3)
1803 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001804 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001805 return false;
1806 }
1807 break;
1808 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1809 if (!context->getExtensions().textureCompressionDXT5)
1810 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001811 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001812 return false;
1813 }
1814 break;
1815 case GL_ETC1_RGB8_OES:
1816 if (!context->getExtensions().compressedETC1RGB8Texture)
1817 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001818 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001819 return false;
1820 }
1821 break;
1822 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001823 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1824 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1825 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1826 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001827 if (!context->getExtensions().lossyETCDecode)
1828 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001829 context->handleError(InvalidEnum()
1830 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001831 return false;
1832 }
1833 break;
1834 case GL_RGBA32F_EXT:
1835 case GL_RGB32F_EXT:
1836 case GL_ALPHA32F_EXT:
1837 case GL_LUMINANCE32F_EXT:
1838 case GL_LUMINANCE_ALPHA32F_EXT:
1839 if (!context->getExtensions().textureFloat)
1840 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001841 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001842 return false;
1843 }
1844 break;
1845 case GL_RGBA16F_EXT:
1846 case GL_RGB16F_EXT:
1847 case GL_ALPHA16F_EXT:
1848 case GL_LUMINANCE16F_EXT:
1849 case GL_LUMINANCE_ALPHA16F_EXT:
1850 if (!context->getExtensions().textureHalfFloat)
1851 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001852 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001853 return false;
1854 }
1855 break;
1856 case GL_R8_EXT:
1857 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001858 if (!context->getExtensions().textureRG)
1859 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001860 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001861 return false;
1862 }
1863 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001864 case GL_R16F_EXT:
1865 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001866 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1867 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001868 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001869 return false;
1870 }
1871 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001872 case GL_R32F_EXT:
1873 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001874 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001875 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001876 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001877 return false;
1878 }
1879 break;
1880 case GL_DEPTH_COMPONENT16:
1881 case GL_DEPTH_COMPONENT32_OES:
1882 case GL_DEPTH24_STENCIL8_OES:
1883 if (!context->getExtensions().depthTextures)
1884 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001885 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001886 return false;
1887 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001888 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001889 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001890 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001891 return false;
1892 }
1893 // ANGLE_depth_texture only supports 1-level textures
1894 if (levels != 1)
1895 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001896 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001897 return false;
1898 }
1899 break;
1900 default:
1901 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001902 }
1903
Geoff Lang691e58c2014-12-19 17:03:25 -05001904 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001905 if (!texture || texture->id() == 0)
1906 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001907 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001908 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001909 }
1910
Geoff Lang69cce582015-09-17 13:20:36 -04001911 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001912 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001913 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001914 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001915 }
1916
1917 return true;
1918}
1919
He Yunchaoced53ae2016-11-29 15:00:51 +08001920bool ValidateDiscardFramebufferEXT(Context *context,
1921 GLenum target,
1922 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001923 const GLenum *attachments)
1924{
Jamie Madillc29968b2016-01-20 11:17:23 -05001925 if (!context->getExtensions().discardFramebuffer)
1926 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001927 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001928 return false;
1929 }
1930
Austin Kinross08332632015-05-05 13:35:47 -07001931 bool defaultFramebuffer = false;
1932
1933 switch (target)
1934 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001935 case GL_FRAMEBUFFER:
1936 defaultFramebuffer =
1937 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1938 break;
1939 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001940 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001941 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001942 }
1943
He Yunchaoced53ae2016-11-29 15:00:51 +08001944 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1945 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001946}
1947
Austin Kinrossbc781f32015-10-26 09:27:38 -07001948bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1949{
1950 if (!context->getExtensions().vertexArrayObject)
1951 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001952 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001953 return false;
1954 }
1955
1956 return ValidateBindVertexArrayBase(context, array);
1957}
1958
Jamie Madilld7576732017-08-26 18:49:50 -04001959bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001960{
1961 if (!context->getExtensions().vertexArrayObject)
1962 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001963 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001964 return false;
1965 }
1966
Olli Etuaho41997e72016-03-10 13:38:39 +02001967 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001968}
1969
Jamie Madilld7576732017-08-26 18:49:50 -04001970bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001971{
1972 if (!context->getExtensions().vertexArrayObject)
1973 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001974 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001975 return false;
1976 }
1977
Olli Etuaho41997e72016-03-10 13:38:39 +02001978 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001979}
1980
Jamie Madilld7576732017-08-26 18:49:50 -04001981bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001982{
1983 if (!context->getExtensions().vertexArrayObject)
1984 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001985 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001986 return false;
1987 }
1988
1989 return true;
1990}
Geoff Langc5629752015-12-07 16:29:04 -05001991
1992bool ValidateProgramBinaryOES(Context *context,
1993 GLuint program,
1994 GLenum binaryFormat,
1995 const void *binary,
1996 GLint length)
1997{
1998 if (!context->getExtensions().getProgramBinary)
1999 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002000 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002001 return false;
2002 }
2003
2004 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2005}
2006
2007bool ValidateGetProgramBinaryOES(Context *context,
2008 GLuint program,
2009 GLsizei bufSize,
2010 GLsizei *length,
2011 GLenum *binaryFormat,
2012 void *binary)
2013{
2014 if (!context->getExtensions().getProgramBinary)
2015 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002016 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002017 return false;
2018 }
2019
2020 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2021}
Geoff Lange102fee2015-12-10 11:23:30 -05002022
Geoff Lang70d0f492015-12-10 17:45:46 -05002023static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2024{
2025 switch (source)
2026 {
2027 case GL_DEBUG_SOURCE_API:
2028 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2029 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2030 case GL_DEBUG_SOURCE_OTHER:
2031 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2032 return !mustBeThirdPartyOrApplication;
2033
2034 case GL_DEBUG_SOURCE_THIRD_PARTY:
2035 case GL_DEBUG_SOURCE_APPLICATION:
2036 return true;
2037
2038 default:
2039 return false;
2040 }
2041}
2042
2043static bool ValidDebugType(GLenum type)
2044{
2045 switch (type)
2046 {
2047 case GL_DEBUG_TYPE_ERROR:
2048 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2049 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2050 case GL_DEBUG_TYPE_PERFORMANCE:
2051 case GL_DEBUG_TYPE_PORTABILITY:
2052 case GL_DEBUG_TYPE_OTHER:
2053 case GL_DEBUG_TYPE_MARKER:
2054 case GL_DEBUG_TYPE_PUSH_GROUP:
2055 case GL_DEBUG_TYPE_POP_GROUP:
2056 return true;
2057
2058 default:
2059 return false;
2060 }
2061}
2062
2063static bool ValidDebugSeverity(GLenum severity)
2064{
2065 switch (severity)
2066 {
2067 case GL_DEBUG_SEVERITY_HIGH:
2068 case GL_DEBUG_SEVERITY_MEDIUM:
2069 case GL_DEBUG_SEVERITY_LOW:
2070 case GL_DEBUG_SEVERITY_NOTIFICATION:
2071 return true;
2072
2073 default:
2074 return false;
2075 }
2076}
2077
Geoff Lange102fee2015-12-10 11:23:30 -05002078bool ValidateDebugMessageControlKHR(Context *context,
2079 GLenum source,
2080 GLenum type,
2081 GLenum severity,
2082 GLsizei count,
2083 const GLuint *ids,
2084 GLboolean enabled)
2085{
2086 if (!context->getExtensions().debug)
2087 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002088 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002089 return false;
2090 }
2091
Geoff Lang70d0f492015-12-10 17:45:46 -05002092 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2093 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002094 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002095 return false;
2096 }
2097
2098 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2099 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002100 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002101 return false;
2102 }
2103
2104 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2105 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002106 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002107 return false;
2108 }
2109
2110 if (count > 0)
2111 {
2112 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2113 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002114 context->handleError(
2115 InvalidOperation()
2116 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002117 return false;
2118 }
2119
2120 if (severity != GL_DONT_CARE)
2121 {
Jamie Madill437fa652016-05-03 15:13:24 -04002122 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002123 InvalidOperation()
2124 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002125 return false;
2126 }
2127 }
2128
Geoff Lange102fee2015-12-10 11:23:30 -05002129 return true;
2130}
2131
2132bool ValidateDebugMessageInsertKHR(Context *context,
2133 GLenum source,
2134 GLenum type,
2135 GLuint id,
2136 GLenum severity,
2137 GLsizei length,
2138 const GLchar *buf)
2139{
2140 if (!context->getExtensions().debug)
2141 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002142 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002143 return false;
2144 }
2145
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002146 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002147 {
2148 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2149 // not generate an error.
2150 return false;
2151 }
2152
2153 if (!ValidDebugSeverity(severity))
2154 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002155 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002156 return false;
2157 }
2158
2159 if (!ValidDebugType(type))
2160 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002161 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002162 return false;
2163 }
2164
2165 if (!ValidDebugSource(source, true))
2166 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002167 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002168 return false;
2169 }
2170
2171 size_t messageLength = (length < 0) ? strlen(buf) : length;
2172 if (messageLength > context->getExtensions().maxDebugMessageLength)
2173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002174 context->handleError(InvalidValue()
2175 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002176 return false;
2177 }
2178
Geoff Lange102fee2015-12-10 11:23:30 -05002179 return true;
2180}
2181
2182bool ValidateDebugMessageCallbackKHR(Context *context,
2183 GLDEBUGPROCKHR callback,
2184 const void *userParam)
2185{
2186 if (!context->getExtensions().debug)
2187 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002188 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002189 return false;
2190 }
2191
Geoff Lange102fee2015-12-10 11:23:30 -05002192 return true;
2193}
2194
2195bool ValidateGetDebugMessageLogKHR(Context *context,
2196 GLuint count,
2197 GLsizei bufSize,
2198 GLenum *sources,
2199 GLenum *types,
2200 GLuint *ids,
2201 GLenum *severities,
2202 GLsizei *lengths,
2203 GLchar *messageLog)
2204{
2205 if (!context->getExtensions().debug)
2206 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002207 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002208 return false;
2209 }
2210
Geoff Lang70d0f492015-12-10 17:45:46 -05002211 if (bufSize < 0 && messageLog != nullptr)
2212 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002213 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002214 return false;
2215 }
2216
Geoff Lange102fee2015-12-10 11:23:30 -05002217 return true;
2218}
2219
2220bool ValidatePushDebugGroupKHR(Context *context,
2221 GLenum source,
2222 GLuint id,
2223 GLsizei length,
2224 const GLchar *message)
2225{
2226 if (!context->getExtensions().debug)
2227 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002228 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002229 return false;
2230 }
2231
Geoff Lang70d0f492015-12-10 17:45:46 -05002232 if (!ValidDebugSource(source, true))
2233 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002234 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002235 return false;
2236 }
2237
2238 size_t messageLength = (length < 0) ? strlen(message) : length;
2239 if (messageLength > context->getExtensions().maxDebugMessageLength)
2240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002241 context->handleError(InvalidValue()
2242 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002243 return false;
2244 }
2245
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002246 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002247 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2248 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002249 context
2250 ->handleError(StackOverflow()
2251 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002252 return false;
2253 }
2254
Geoff Lange102fee2015-12-10 11:23:30 -05002255 return true;
2256}
2257
2258bool ValidatePopDebugGroupKHR(Context *context)
2259{
2260 if (!context->getExtensions().debug)
2261 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002262 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002263 return false;
2264 }
2265
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002266 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002267 if (currentStackSize <= 1)
2268 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002269 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002270 return false;
2271 }
2272
2273 return true;
2274}
2275
2276static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2277{
2278 switch (identifier)
2279 {
2280 case GL_BUFFER:
2281 if (context->getBuffer(name) == nullptr)
2282 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002283 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002284 return false;
2285 }
2286 return true;
2287
2288 case GL_SHADER:
2289 if (context->getShader(name) == nullptr)
2290 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002291 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002292 return false;
2293 }
2294 return true;
2295
2296 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002297 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002298 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002299 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002300 return false;
2301 }
2302 return true;
2303
2304 case GL_VERTEX_ARRAY:
2305 if (context->getVertexArray(name) == nullptr)
2306 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002307 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002308 return false;
2309 }
2310 return true;
2311
2312 case GL_QUERY:
2313 if (context->getQuery(name) == nullptr)
2314 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002315 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002316 return false;
2317 }
2318 return true;
2319
2320 case GL_TRANSFORM_FEEDBACK:
2321 if (context->getTransformFeedback(name) == nullptr)
2322 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002323 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002324 return false;
2325 }
2326 return true;
2327
2328 case GL_SAMPLER:
2329 if (context->getSampler(name) == nullptr)
2330 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002331 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002332 return false;
2333 }
2334 return true;
2335
2336 case GL_TEXTURE:
2337 if (context->getTexture(name) == nullptr)
2338 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002339 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002340 return false;
2341 }
2342 return true;
2343
2344 case GL_RENDERBUFFER:
2345 if (context->getRenderbuffer(name) == nullptr)
2346 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002347 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002348 return false;
2349 }
2350 return true;
2351
2352 case GL_FRAMEBUFFER:
2353 if (context->getFramebuffer(name) == nullptr)
2354 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002355 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 return false;
2357 }
2358 return true;
2359
2360 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002361 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002362 return false;
2363 }
Geoff Lange102fee2015-12-10 11:23:30 -05002364}
2365
Martin Radev9d901792016-07-15 15:58:58 +03002366static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2367{
2368 size_t labelLength = 0;
2369
2370 if (length < 0)
2371 {
2372 if (label != nullptr)
2373 {
2374 labelLength = strlen(label);
2375 }
2376 }
2377 else
2378 {
2379 labelLength = static_cast<size_t>(length);
2380 }
2381
2382 if (labelLength > context->getExtensions().maxLabelLength)
2383 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002384 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002385 return false;
2386 }
2387
2388 return true;
2389}
2390
Geoff Lange102fee2015-12-10 11:23:30 -05002391bool ValidateObjectLabelKHR(Context *context,
2392 GLenum identifier,
2393 GLuint name,
2394 GLsizei length,
2395 const GLchar *label)
2396{
2397 if (!context->getExtensions().debug)
2398 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002400 return false;
2401 }
2402
Geoff Lang70d0f492015-12-10 17:45:46 -05002403 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2404 {
2405 return false;
2406 }
2407
Martin Radev9d901792016-07-15 15:58:58 +03002408 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002409 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002410 return false;
2411 }
2412
Geoff Lange102fee2015-12-10 11:23:30 -05002413 return true;
2414}
2415
2416bool ValidateGetObjectLabelKHR(Context *context,
2417 GLenum identifier,
2418 GLuint name,
2419 GLsizei bufSize,
2420 GLsizei *length,
2421 GLchar *label)
2422{
2423 if (!context->getExtensions().debug)
2424 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002425 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002426 return false;
2427 }
2428
Geoff Lang70d0f492015-12-10 17:45:46 -05002429 if (bufSize < 0)
2430 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002431 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002432 return false;
2433 }
2434
2435 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2436 {
2437 return false;
2438 }
2439
Martin Radev9d901792016-07-15 15:58:58 +03002440 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002441}
2442
2443static bool ValidateObjectPtrName(Context *context, const void *ptr)
2444{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002445 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002447 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002448 return false;
2449 }
2450
Geoff Lange102fee2015-12-10 11:23:30 -05002451 return true;
2452}
2453
2454bool ValidateObjectPtrLabelKHR(Context *context,
2455 const void *ptr,
2456 GLsizei length,
2457 const GLchar *label)
2458{
2459 if (!context->getExtensions().debug)
2460 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002461 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002462 return false;
2463 }
2464
Geoff Lang70d0f492015-12-10 17:45:46 -05002465 if (!ValidateObjectPtrName(context, ptr))
2466 {
2467 return false;
2468 }
2469
Martin Radev9d901792016-07-15 15:58:58 +03002470 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002471 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002472 return false;
2473 }
2474
Geoff Lange102fee2015-12-10 11:23:30 -05002475 return true;
2476}
2477
2478bool ValidateGetObjectPtrLabelKHR(Context *context,
2479 const void *ptr,
2480 GLsizei bufSize,
2481 GLsizei *length,
2482 GLchar *label)
2483{
2484 if (!context->getExtensions().debug)
2485 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002486 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002487 return false;
2488 }
2489
Geoff Lang70d0f492015-12-10 17:45:46 -05002490 if (bufSize < 0)
2491 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002492 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002493 return false;
2494 }
2495
2496 if (!ValidateObjectPtrName(context, ptr))
2497 {
2498 return false;
2499 }
2500
Martin Radev9d901792016-07-15 15:58:58 +03002501 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002502}
2503
2504bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2505{
2506 if (!context->getExtensions().debug)
2507 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002509 return false;
2510 }
2511
Geoff Lang70d0f492015-12-10 17:45:46 -05002512 // TODO: represent this in Context::getQueryParameterInfo.
2513 switch (pname)
2514 {
2515 case GL_DEBUG_CALLBACK_FUNCTION:
2516 case GL_DEBUG_CALLBACK_USER_PARAM:
2517 break;
2518
2519 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002520 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002521 return false;
2522 }
2523
Geoff Lange102fee2015-12-10 11:23:30 -05002524 return true;
2525}
Jamie Madillc29968b2016-01-20 11:17:23 -05002526
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002527bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2528 GLenum pname,
2529 GLsizei bufSize,
2530 GLsizei *length,
2531 void **params)
2532{
2533 UNIMPLEMENTED();
2534 return false;
2535}
2536
Jamie Madillc29968b2016-01-20 11:17:23 -05002537bool ValidateBlitFramebufferANGLE(Context *context,
2538 GLint srcX0,
2539 GLint srcY0,
2540 GLint srcX1,
2541 GLint srcY1,
2542 GLint dstX0,
2543 GLint dstY0,
2544 GLint dstX1,
2545 GLint dstY1,
2546 GLbitfield mask,
2547 GLenum filter)
2548{
2549 if (!context->getExtensions().framebufferBlit)
2550 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002551 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002552 return false;
2553 }
2554
2555 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2556 {
2557 // TODO(jmadill): Determine if this should be available on other implementations.
Olli Etuahof0e3c192018-08-15 13:37:21 +03002558 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002559 return false;
2560 }
2561
2562 if (filter == GL_LINEAR)
2563 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002564 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002565 return false;
2566 }
2567
Jamie Madill51f40ec2016-06-15 14:06:00 -04002568 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2569 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002570
2571 if (mask & GL_COLOR_BUFFER_BIT)
2572 {
2573 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2574 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2575
2576 if (readColorAttachment && drawColorAttachment)
2577 {
2578 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002579 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002580 readColorAttachment->type() != GL_RENDERBUFFER &&
2581 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2582 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002583 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2584 BlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002585 return false;
2586 }
2587
Geoff Langa15472a2015-08-11 11:48:03 -04002588 for (size_t drawbufferIdx = 0;
2589 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002590 {
Geoff Langa15472a2015-08-11 11:48:03 -04002591 const FramebufferAttachment *attachment =
2592 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2593 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002594 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002595 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002596 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002597 attachment->type() != GL_RENDERBUFFER &&
2598 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2599 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002600 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2601 BlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002602 return false;
2603 }
2604
2605 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002606 if (!Format::EquivalentForBlit(attachment->getFormat(),
2607 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002608 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002609 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2610 BlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002611 return false;
2612 }
2613 }
2614 }
2615
Jamie Madill427064d2018-04-13 16:20:34 -04002616 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002617 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002618 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2619 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2620 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002621 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2622 BlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002623 return false;
2624 }
2625 }
2626 }
2627
2628 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2629 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2630 for (size_t i = 0; i < 2; i++)
2631 {
2632 if (mask & masks[i])
2633 {
2634 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002635 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002636 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002637 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002638
2639 if (readBuffer && drawBuffer)
2640 {
2641 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2642 dstX0, dstY0, dstX1, dstY1))
2643 {
2644 // only whole-buffer copies are permitted
Olli Etuahof0e3c192018-08-15 13:37:21 +03002645 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2646 BlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002647 return false;
2648 }
2649
2650 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2651 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002652 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2653 BlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002654 return false;
2655 }
2656 }
2657 }
2658 }
2659
2660 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2661 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002662}
Jamie Madillc29968b2016-01-20 11:17:23 -05002663
Jamie Madill5b772312018-03-08 20:28:32 -05002664bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002665{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002666 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002667 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002668
Jamie Madill427064d2018-04-13 16:20:34 -04002669 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002670 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002671 return false;
2672 }
2673
2674 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2675 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002676 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002677 return false;
2678 }
2679
Olli Etuaho94c91a92018-07-19 15:10:24 +03002680 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002681 {
2682 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2683 GL_SIGNED_NORMALIZED};
2684
Corentin Wallez59c41592017-07-11 13:19:54 -04002685 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002686 drawBufferIdx++)
2687 {
2688 if (!ValidateWebGLFramebufferAttachmentClearType(
2689 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2690 {
2691 return false;
2692 }
2693 }
2694 }
2695
Olli Etuaho94c91a92018-07-19 15:10:24 +03002696 if (extensions.multiview && extensions.disjointTimerQuery)
2697 {
2698 const State &state = context->getGLState();
2699 Framebuffer *framebuffer = state.getDrawFramebuffer();
2700 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2701 {
2702 context->handleError(InvalidOperation() << "There is an active query for target "
2703 "GL_TIME_ELAPSED_EXT when the number of "
2704 "views in the active draw framebuffer is "
2705 "greater than 1.");
2706 return false;
2707 }
2708 }
2709
Jamie Madillc29968b2016-01-20 11:17:23 -05002710 return true;
2711}
2712
Jamie Madill5b772312018-03-08 20:28:32 -05002713bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002714{
2715 if (!context->getExtensions().drawBuffers)
2716 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002717 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002718 return false;
2719 }
2720
2721 return ValidateDrawBuffersBase(context, n, bufs);
2722}
2723
Jamie Madill73a84962016-02-12 09:27:23 -05002724bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002725 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002726 GLint level,
2727 GLint internalformat,
2728 GLsizei width,
2729 GLsizei height,
2730 GLint border,
2731 GLenum format,
2732 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002733 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002734{
Martin Radev1be913c2016-07-11 17:59:16 +03002735 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002736 {
2737 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002738 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002739 }
2740
Martin Radev1be913c2016-07-11 17:59:16 +03002741 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002742 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002743 0, 0, width, height, 1, border, format, type, -1,
2744 pixels);
2745}
2746
Brandon Jones416aaf92018-04-10 08:10:16 -07002747bool ValidateTexImage2DRobustANGLE(Context *context,
2748 TextureTarget target,
2749 GLint level,
2750 GLint internalformat,
2751 GLsizei width,
2752 GLsizei height,
2753 GLint border,
2754 GLenum format,
2755 GLenum type,
2756 GLsizei bufSize,
2757 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002758{
2759 if (!ValidateRobustEntryPoint(context, bufSize))
2760 {
2761 return false;
2762 }
2763
2764 if (context->getClientMajorVersion() < 3)
2765 {
2766 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2767 0, 0, width, height, border, format, type, bufSize,
2768 pixels);
2769 }
2770
2771 ASSERT(context->getClientMajorVersion() >= 3);
2772 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2773 0, 0, width, height, 1, border, format, type, bufSize,
2774 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002775}
2776
2777bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002778 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002779 GLint level,
2780 GLint xoffset,
2781 GLint yoffset,
2782 GLsizei width,
2783 GLsizei height,
2784 GLenum format,
2785 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002786 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002787{
2788
Martin Radev1be913c2016-07-11 17:59:16 +03002789 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002790 {
2791 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002792 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002793 }
2794
Martin Radev1be913c2016-07-11 17:59:16 +03002795 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002796 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002797 yoffset, 0, width, height, 1, 0, format, type, -1,
2798 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002799}
2800
Geoff Langc52f6f12016-10-14 10:18:00 -04002801bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002802 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002803 GLint level,
2804 GLint xoffset,
2805 GLint yoffset,
2806 GLsizei width,
2807 GLsizei height,
2808 GLenum format,
2809 GLenum type,
2810 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002811 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002812{
2813 if (!ValidateRobustEntryPoint(context, bufSize))
2814 {
2815 return false;
2816 }
2817
2818 if (context->getClientMajorVersion() < 3)
2819 {
2820 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2821 yoffset, width, height, 0, format, type, bufSize,
2822 pixels);
2823 }
2824
2825 ASSERT(context->getClientMajorVersion() >= 3);
2826 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2827 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2828 pixels);
2829}
2830
Jamie Madill73a84962016-02-12 09:27:23 -05002831bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002832 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002833 GLint level,
2834 GLenum internalformat,
2835 GLsizei width,
2836 GLsizei height,
2837 GLint border,
2838 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002839 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002840{
Martin Radev1be913c2016-07-11 17:59:16 +03002841 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002842 {
2843 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002844 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002845 {
2846 return false;
2847 }
2848 }
2849 else
2850 {
Martin Radev1be913c2016-07-11 17:59:16 +03002851 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002852 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002853 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002854 data))
2855 {
2856 return false;
2857 }
2858 }
2859
Geoff Langca271392017-04-05 12:30:00 -04002860 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002861
2862 GLuint blockSize = 0;
2863 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002864 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002865 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002866 return false;
2867 }
2868
Jamie Madillca2ff382018-07-11 09:01:17 -04002869 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002870 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002871 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002872 return false;
2873 }
2874
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002875 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002876 {
2877 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2878 return false;
2879 }
2880
Jamie Madill73a84962016-02-12 09:27:23 -05002881 return true;
2882}
2883
Corentin Wallezb2931602017-04-11 15:58:57 -04002884bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002885 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002886 GLint level,
2887 GLenum internalformat,
2888 GLsizei width,
2889 GLsizei height,
2890 GLint border,
2891 GLsizei imageSize,
2892 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002893 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002894{
2895 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2896 {
2897 return false;
2898 }
2899
2900 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2901 border, imageSize, data);
2902}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002903
Corentin Wallezb2931602017-04-11 15:58:57 -04002904bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002905 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002906 GLint level,
2907 GLint xoffset,
2908 GLint yoffset,
2909 GLsizei width,
2910 GLsizei height,
2911 GLenum format,
2912 GLsizei imageSize,
2913 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002914 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002915{
2916 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2917 {
2918 return false;
2919 }
2920
2921 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2922 format, imageSize, data);
2923}
2924
Jamie Madill73a84962016-02-12 09:27:23 -05002925bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002926 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002927 GLint level,
2928 GLint xoffset,
2929 GLint yoffset,
2930 GLsizei width,
2931 GLsizei height,
2932 GLenum format,
2933 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002934 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002935{
Martin Radev1be913c2016-07-11 17:59:16 +03002936 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002937 {
2938 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002939 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002940 {
2941 return false;
2942 }
2943 }
2944 else
2945 {
Martin Radev1be913c2016-07-11 17:59:16 +03002946 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002947 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002948 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002949 data))
2950 {
2951 return false;
2952 }
2953 }
2954
Geoff Langca271392017-04-05 12:30:00 -04002955 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002956 GLuint blockSize = 0;
2957 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002958 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002959 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002960 return false;
2961 }
2962
Jamie Madillca2ff382018-07-11 09:01:17 -04002963 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002964 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002965 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002966 return false;
2967 }
2968
2969 return true;
2970}
2971
Corentin Wallez336129f2017-10-17 15:55:40 -04002972bool ValidateGetBufferPointervOES(Context *context,
2973 BufferBinding target,
2974 GLenum pname,
2975 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002976{
Geoff Lang496c02d2016-10-20 11:38:11 -07002977 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002978}
2979
Corentin Wallez336129f2017-10-17 15:55:40 -04002980bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002981{
2982 if (!context->getExtensions().mapBuffer)
2983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002984 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002985 return false;
2986 }
2987
Corentin Walleze4477002017-12-01 14:39:58 -05002988 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002989 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002990 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002991 return false;
2992 }
2993
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002994 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002995
2996 if (buffer == nullptr)
2997 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002998 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002999 return false;
3000 }
3001
3002 if (access != GL_WRITE_ONLY_OES)
3003 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003004 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003005 return false;
3006 }
3007
3008 if (buffer->isMapped())
3009 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003010 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003011 return false;
3012 }
3013
Geoff Lang79f71042017-08-14 16:43:43 -04003014 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003015}
3016
Corentin Wallez336129f2017-10-17 15:55:40 -04003017bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003018{
3019 if (!context->getExtensions().mapBuffer)
3020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003021 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003022 return false;
3023 }
3024
3025 return ValidateUnmapBufferBase(context, target);
3026}
3027
3028bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003029 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003030 GLintptr offset,
3031 GLsizeiptr length,
3032 GLbitfield access)
3033{
3034 if (!context->getExtensions().mapBufferRange)
3035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003036 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003037 return false;
3038 }
3039
3040 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3041}
3042
Corentin Wallez336129f2017-10-17 15:55:40 -04003043bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003044{
3045 Buffer *buffer = context->getGLState().getTargetBuffer(target);
3046 ASSERT(buffer != nullptr);
3047
3048 // Check if this buffer is currently being used as a transform feedback output buffer
3049 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3050 if (transformFeedback != nullptr && transformFeedback->isActive())
3051 {
3052 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3053 {
3054 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3055 if (transformFeedbackBuffer.get() == buffer)
3056 {
3057 context->handleError(InvalidOperation()
3058 << "Buffer is currently bound for transform feedback.");
3059 return false;
3060 }
3061 }
3062 }
3063
James Darpiniane8a93c62018-01-04 18:02:24 -08003064 if (context->getExtensions().webglCompatibility &&
3065 buffer->isBoundForTransformFeedbackAndOtherUse())
3066 {
3067 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
3068 return false;
3069 }
3070
Geoff Lang79f71042017-08-14 16:43:43 -04003071 return true;
3072}
3073
Olli Etuaho4f667482016-03-30 15:56:35 +03003074bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003075 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003076 GLintptr offset,
3077 GLsizeiptr length)
3078{
3079 if (!context->getExtensions().mapBufferRange)
3080 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003081 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003082 return false;
3083 }
3084
3085 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3086}
3087
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003088bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05003089{
Jamie Madillac66f982018-10-09 18:30:01 -04003090 if (!context->getStateCache().isValidBindTextureType(target))
Ian Ewell54f87462016-03-10 13:47:21 -05003091 {
Jamie Madillac66f982018-10-09 18:30:01 -04003092 RecordBindTextureTypeError(context, target);
3093 return false;
Ian Ewell54f87462016-03-10 13:47:21 -05003094 }
3095
Jamie Madill0fdb9562018-09-17 17:18:43 -04003096 if (texture == 0)
3097 {
3098 return true;
3099 }
3100
3101 Texture *textureObject = context->getTexture(texture);
3102 if (textureObject && textureObject->getType() != target)
3103 {
3104 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
3105 return false;
3106 }
3107
3108 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3109 !context->isTextureGenerated(texture))
3110 {
3111 context->handleError(InvalidOperation() << "Texture was not generated");
3112 return false;
3113 }
3114
Ian Ewell54f87462016-03-10 13:47:21 -05003115 return true;
3116}
3117
Geoff Langd8605522016-04-13 10:19:12 -04003118bool ValidateBindUniformLocationCHROMIUM(Context *context,
3119 GLuint program,
3120 GLint location,
3121 const GLchar *name)
3122{
3123 if (!context->getExtensions().bindUniformLocation)
3124 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003125 context->handleError(InvalidOperation()
3126 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003127 return false;
3128 }
3129
3130 Program *programObject = GetValidProgram(context, program);
3131 if (!programObject)
3132 {
3133 return false;
3134 }
3135
3136 if (location < 0)
3137 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003138 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003139 return false;
3140 }
3141
3142 const Caps &caps = context->getCaps();
3143 if (static_cast<size_t>(location) >=
3144 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3145 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003146 context->handleError(InvalidValue() << "Location must be less than "
3147 "(MAX_VERTEX_UNIFORM_VECTORS + "
3148 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003149 return false;
3150 }
3151
Geoff Langfc32e8b2017-05-31 14:16:59 -04003152 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3153 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003154 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003156 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003157 return false;
3158 }
3159
Geoff Langd8605522016-04-13 10:19:12 -04003160 if (strncmp(name, "gl_", 3) == 0)
3161 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003162 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003163 return false;
3164 }
3165
3166 return true;
3167}
3168
Jamie Madille2e406c2016-06-02 13:04:10 -04003169bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003170{
3171 if (!context->getExtensions().framebufferMixedSamples)
3172 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003173 context->handleError(InvalidOperation()
3174 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003175 return false;
3176 }
3177 switch (components)
3178 {
3179 case GL_RGB:
3180 case GL_RGBA:
3181 case GL_ALPHA:
3182 case GL_NONE:
3183 break;
3184 default:
3185 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003186 InvalidEnum()
3187 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003188 return false;
3189 }
3190
3191 return true;
3192}
3193
Sami Väisänene45e53b2016-05-25 10:36:04 +03003194// CHROMIUM_path_rendering
3195
Jamie Madill007530e2017-12-28 14:27:04 -05003196bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003197{
Jamie Madill007530e2017-12-28 14:27:04 -05003198 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003199 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003200 return false;
3201 }
Jamie Madill007530e2017-12-28 14:27:04 -05003202
Sami Väisänene45e53b2016-05-25 10:36:04 +03003203 if (matrix == nullptr)
3204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003205 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003206 return false;
3207 }
Jamie Madill007530e2017-12-28 14:27:04 -05003208
Sami Väisänene45e53b2016-05-25 10:36:04 +03003209 return true;
3210}
3211
Jamie Madill007530e2017-12-28 14:27:04 -05003212bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003213{
Jamie Madill007530e2017-12-28 14:27:04 -05003214 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003215}
3216
Jamie Madill007530e2017-12-28 14:27:04 -05003217bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003218{
3219 if (!context->getExtensions().pathRendering)
3220 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003221 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003222 return false;
3223 }
3224
3225 // range = 0 is undefined in NV_path_rendering.
3226 // we add stricter semantic check here and require a non zero positive range.
3227 if (range <= 0)
3228 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003229 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003230 return false;
3231 }
3232
3233 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3234 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003235 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003236 return false;
3237 }
3238
3239 return true;
3240}
3241
Jamie Madill007530e2017-12-28 14:27:04 -05003242bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003243{
3244 if (!context->getExtensions().pathRendering)
3245 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003246 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003247 return false;
3248 }
3249
3250 // range = 0 is undefined in NV_path_rendering.
3251 // we add stricter semantic check here and require a non zero positive range.
3252 if (range <= 0)
3253 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003254 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003255 return false;
3256 }
3257
3258 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3259 checkedRange += range;
3260
3261 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3262 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003263 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003264 return false;
3265 }
3266 return true;
3267}
3268
Jamie Madill007530e2017-12-28 14:27:04 -05003269bool ValidatePathCommandsCHROMIUM(Context *context,
3270 GLuint path,
3271 GLsizei numCommands,
3272 const GLubyte *commands,
3273 GLsizei numCoords,
3274 GLenum coordType,
3275 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003276{
3277 if (!context->getExtensions().pathRendering)
3278 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003279 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280 return false;
3281 }
Brandon Jones59770802018-04-02 13:18:42 -07003282 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003283 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003284 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003285 return false;
3286 }
3287
3288 if (numCommands < 0)
3289 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003290 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003291 return false;
3292 }
3293 else if (numCommands > 0)
3294 {
3295 if (!commands)
3296 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003297 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003298 return false;
3299 }
3300 }
3301
3302 if (numCoords < 0)
3303 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003304 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003305 return false;
3306 }
3307 else if (numCoords > 0)
3308 {
3309 if (!coords)
3310 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003311 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003312 return false;
3313 }
3314 }
3315
3316 std::uint32_t coordTypeSize = 0;
3317 switch (coordType)
3318 {
3319 case GL_BYTE:
3320 coordTypeSize = sizeof(GLbyte);
3321 break;
3322
3323 case GL_UNSIGNED_BYTE:
3324 coordTypeSize = sizeof(GLubyte);
3325 break;
3326
3327 case GL_SHORT:
3328 coordTypeSize = sizeof(GLshort);
3329 break;
3330
3331 case GL_UNSIGNED_SHORT:
3332 coordTypeSize = sizeof(GLushort);
3333 break;
3334
3335 case GL_FLOAT:
3336 coordTypeSize = sizeof(GLfloat);
3337 break;
3338
3339 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003340 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003341 return false;
3342 }
3343
3344 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3345 checkedSize += (coordTypeSize * numCoords);
3346 if (!checkedSize.IsValid())
3347 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003348 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003349 return false;
3350 }
3351
3352 // early return skips command data validation when it doesn't exist.
3353 if (!commands)
3354 return true;
3355
3356 GLsizei expectedNumCoords = 0;
3357 for (GLsizei i = 0; i < numCommands; ++i)
3358 {
3359 switch (commands[i])
3360 {
3361 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3362 break;
3363 case GL_MOVE_TO_CHROMIUM:
3364 case GL_LINE_TO_CHROMIUM:
3365 expectedNumCoords += 2;
3366 break;
3367 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3368 expectedNumCoords += 4;
3369 break;
3370 case GL_CUBIC_CURVE_TO_CHROMIUM:
3371 expectedNumCoords += 6;
3372 break;
3373 case GL_CONIC_CURVE_TO_CHROMIUM:
3374 expectedNumCoords += 5;
3375 break;
3376 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003377 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003378 return false;
3379 }
3380 }
3381 if (expectedNumCoords != numCoords)
3382 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003383 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003384 return false;
3385 }
3386
3387 return true;
3388}
3389
Jamie Madill007530e2017-12-28 14:27:04 -05003390bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003391{
3392 if (!context->getExtensions().pathRendering)
3393 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003394 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003395 return false;
3396 }
Brandon Jones59770802018-04-02 13:18:42 -07003397 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003398 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003400 return false;
3401 }
3402
3403 switch (pname)
3404 {
3405 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3406 if (value < 0.0f)
3407 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003408 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003409 return false;
3410 }
3411 break;
3412 case GL_PATH_END_CAPS_CHROMIUM:
3413 switch (static_cast<GLenum>(value))
3414 {
3415 case GL_FLAT_CHROMIUM:
3416 case GL_SQUARE_CHROMIUM:
3417 case GL_ROUND_CHROMIUM:
3418 break;
3419 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003420 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003421 return false;
3422 }
3423 break;
3424 case GL_PATH_JOIN_STYLE_CHROMIUM:
3425 switch (static_cast<GLenum>(value))
3426 {
3427 case GL_MITER_REVERT_CHROMIUM:
3428 case GL_BEVEL_CHROMIUM:
3429 case GL_ROUND_CHROMIUM:
3430 break;
3431 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003432 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003433 return false;
3434 }
Nico Weber41b072b2018-02-09 10:01:32 -05003435 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003436 case GL_PATH_MITER_LIMIT_CHROMIUM:
3437 if (value < 0.0f)
3438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003439 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003440 return false;
3441 }
3442 break;
3443
3444 case GL_PATH_STROKE_BOUND_CHROMIUM:
3445 // no errors, only clamping.
3446 break;
3447
3448 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003449 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003450 return false;
3451 }
3452 return true;
3453}
3454
Jamie Madill007530e2017-12-28 14:27:04 -05003455bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3456{
3457 // TODO(jmadill): Use proper clamping cast.
3458 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3459}
3460
3461bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003462{
3463 if (!context->getExtensions().pathRendering)
3464 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003465 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003466 return false;
3467 }
3468
Brandon Jones59770802018-04-02 13:18:42 -07003469 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003470 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003471 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003472 return false;
3473 }
3474 if (!value)
3475 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003476 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003477 return false;
3478 }
3479
3480 switch (pname)
3481 {
3482 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3483 case GL_PATH_END_CAPS_CHROMIUM:
3484 case GL_PATH_JOIN_STYLE_CHROMIUM:
3485 case GL_PATH_MITER_LIMIT_CHROMIUM:
3486 case GL_PATH_STROKE_BOUND_CHROMIUM:
3487 break;
3488
3489 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003490 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003491 return false;
3492 }
3493
3494 return true;
3495}
3496
Jamie Madill007530e2017-12-28 14:27:04 -05003497bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3498{
3499 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3500 reinterpret_cast<GLfloat *>(value));
3501}
3502
3503bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003504{
3505 if (!context->getExtensions().pathRendering)
3506 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003507 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003508 return false;
3509 }
3510
3511 switch (func)
3512 {
3513 case GL_NEVER:
3514 case GL_ALWAYS:
3515 case GL_LESS:
3516 case GL_LEQUAL:
3517 case GL_EQUAL:
3518 case GL_GEQUAL:
3519 case GL_GREATER:
3520 case GL_NOTEQUAL:
3521 break;
3522 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003523 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003524 return false;
3525 }
3526
3527 return true;
3528}
3529
3530// Note that the spec specifies that for the path drawing commands
3531// if the path object is not an existing path object the command
3532// does nothing and no error is generated.
3533// However if the path object exists but has not been specified any
3534// commands then an error is generated.
3535
Jamie Madill007530e2017-12-28 14:27:04 -05003536bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003537{
3538 if (!context->getExtensions().pathRendering)
3539 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003540 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003541 return false;
3542 }
Brandon Jones59770802018-04-02 13:18:42 -07003543 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003544 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003545 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546 return false;
3547 }
3548
3549 switch (fillMode)
3550 {
3551 case GL_COUNT_UP_CHROMIUM:
3552 case GL_COUNT_DOWN_CHROMIUM:
3553 break;
3554 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003555 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003556 return false;
3557 }
3558
3559 if (!isPow2(mask + 1))
3560 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003561 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003562 return false;
3563 }
3564
3565 return true;
3566}
3567
Jamie Madill007530e2017-12-28 14:27:04 -05003568bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003569{
3570 if (!context->getExtensions().pathRendering)
3571 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003572 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003573 return false;
3574 }
Brandon Jones59770802018-04-02 13:18:42 -07003575 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003576 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003577 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003578 return false;
3579 }
3580
3581 return true;
3582}
3583
Brandon Jonesd1049182018-03-28 10:02:20 -07003584bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3585{
3586 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3587}
3588
3589bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3590{
3591 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3592}
3593
Jamie Madill007530e2017-12-28 14:27:04 -05003594bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003595{
3596 if (!context->getExtensions().pathRendering)
3597 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003598 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003599 return false;
3600 }
Brandon Jones59770802018-04-02 13:18:42 -07003601 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003602 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003603 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003604 return false;
3605 }
3606
3607 switch (coverMode)
3608 {
3609 case GL_CONVEX_HULL_CHROMIUM:
3610 case GL_BOUNDING_BOX_CHROMIUM:
3611 break;
3612 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003613 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003614 return false;
3615 }
3616 return true;
3617}
3618
Jamie Madill007530e2017-12-28 14:27:04 -05003619bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3620 GLuint path,
3621 GLenum fillMode,
3622 GLuint mask,
3623 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003624{
Jamie Madill007530e2017-12-28 14:27:04 -05003625 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3626 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003627}
3628
Jamie Madill007530e2017-12-28 14:27:04 -05003629bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3630 GLuint path,
3631 GLint reference,
3632 GLuint mask,
3633 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003634{
Jamie Madill007530e2017-12-28 14:27:04 -05003635 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3636 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003637}
3638
Brandon Jonesd1049182018-03-28 10:02:20 -07003639bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003640{
3641 if (!context->getExtensions().pathRendering)
3642 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003643 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003644 return false;
3645 }
3646 return true;
3647}
3648
Jamie Madill007530e2017-12-28 14:27:04 -05003649bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3650 GLsizei numPaths,
3651 GLenum pathNameType,
3652 const void *paths,
3653 GLuint pathBase,
3654 GLenum coverMode,
3655 GLenum transformType,
3656 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003657{
3658 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3659 transformType, transformValues))
3660 return false;
3661
3662 switch (coverMode)
3663 {
3664 case GL_CONVEX_HULL_CHROMIUM:
3665 case GL_BOUNDING_BOX_CHROMIUM:
3666 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3667 break;
3668 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003670 return false;
3671 }
3672
3673 return true;
3674}
3675
Jamie Madill007530e2017-12-28 14:27:04 -05003676bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3677 GLsizei numPaths,
3678 GLenum pathNameType,
3679 const void *paths,
3680 GLuint pathBase,
3681 GLenum coverMode,
3682 GLenum transformType,
3683 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003684{
3685 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3686 transformType, transformValues))
3687 return false;
3688
3689 switch (coverMode)
3690 {
3691 case GL_CONVEX_HULL_CHROMIUM:
3692 case GL_BOUNDING_BOX_CHROMIUM:
3693 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3694 break;
3695 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003696 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003697 return false;
3698 }
3699
3700 return true;
3701}
3702
Jamie Madill007530e2017-12-28 14:27:04 -05003703bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3704 GLsizei numPaths,
3705 GLenum pathNameType,
3706 const void *paths,
3707 GLuint pathBase,
3708 GLenum fillMode,
3709 GLuint mask,
3710 GLenum transformType,
3711 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003712{
3713
3714 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3715 transformType, transformValues))
3716 return false;
3717
3718 switch (fillMode)
3719 {
3720 case GL_COUNT_UP_CHROMIUM:
3721 case GL_COUNT_DOWN_CHROMIUM:
3722 break;
3723 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003724 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003725 return false;
3726 }
3727 if (!isPow2(mask + 1))
3728 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003729 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003730 return false;
3731 }
3732 return true;
3733}
3734
Jamie Madill007530e2017-12-28 14:27:04 -05003735bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3736 GLsizei numPaths,
3737 GLenum pathNameType,
3738 const void *paths,
3739 GLuint pathBase,
3740 GLint reference,
3741 GLuint mask,
3742 GLenum transformType,
3743 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003744{
3745 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3746 transformType, transformValues))
3747 return false;
3748
3749 // no more validation here.
3750
3751 return true;
3752}
3753
Jamie Madill007530e2017-12-28 14:27:04 -05003754bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3755 GLsizei numPaths,
3756 GLenum pathNameType,
3757 const void *paths,
3758 GLuint pathBase,
3759 GLenum fillMode,
3760 GLuint mask,
3761 GLenum coverMode,
3762 GLenum transformType,
3763 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003764{
3765 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3766 transformType, transformValues))
3767 return false;
3768
3769 switch (coverMode)
3770 {
3771 case GL_CONVEX_HULL_CHROMIUM:
3772 case GL_BOUNDING_BOX_CHROMIUM:
3773 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3774 break;
3775 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003776 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003777 return false;
3778 }
3779
3780 switch (fillMode)
3781 {
3782 case GL_COUNT_UP_CHROMIUM:
3783 case GL_COUNT_DOWN_CHROMIUM:
3784 break;
3785 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003786 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003787 return false;
3788 }
3789 if (!isPow2(mask + 1))
3790 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003791 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003792 return false;
3793 }
3794
3795 return true;
3796}
3797
Jamie Madill007530e2017-12-28 14:27:04 -05003798bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3799 GLsizei numPaths,
3800 GLenum pathNameType,
3801 const void *paths,
3802 GLuint pathBase,
3803 GLint reference,
3804 GLuint mask,
3805 GLenum coverMode,
3806 GLenum transformType,
3807 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003808{
3809 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3810 transformType, transformValues))
3811 return false;
3812
3813 switch (coverMode)
3814 {
3815 case GL_CONVEX_HULL_CHROMIUM:
3816 case GL_BOUNDING_BOX_CHROMIUM:
3817 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3818 break;
3819 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003820 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003821 return false;
3822 }
3823
3824 return true;
3825}
3826
Jamie Madill007530e2017-12-28 14:27:04 -05003827bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3828 GLuint program,
3829 GLint location,
3830 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003831{
3832 if (!context->getExtensions().pathRendering)
3833 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003834 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003835 return false;
3836 }
3837
3838 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3839 if (location >= MaxLocation)
3840 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003841 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003842 return false;
3843 }
3844
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003845 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003846 if (!programObject)
3847 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003848 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003849 return false;
3850 }
3851
3852 if (!name)
3853 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003854 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003855 return false;
3856 }
3857
3858 if (angle::BeginsWith(name, "gl_"))
3859 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003860 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003861 return false;
3862 }
3863
3864 return true;
3865}
3866
Jamie Madill007530e2017-12-28 14:27:04 -05003867bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3868 GLuint program,
3869 GLint location,
3870 GLenum genMode,
3871 GLint components,
3872 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003873{
3874 if (!context->getExtensions().pathRendering)
3875 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003876 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003877 return false;
3878 }
3879
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003880 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003881 if (!programObject || programObject->isFlaggedForDeletion())
3882 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003883 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003884 return false;
3885 }
3886
3887 if (!programObject->isLinked())
3888 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003889 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003890 return false;
3891 }
3892
3893 switch (genMode)
3894 {
3895 case GL_NONE:
3896 if (components != 0)
3897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003898 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003899 return false;
3900 }
3901 break;
3902
3903 case GL_OBJECT_LINEAR_CHROMIUM:
3904 case GL_EYE_LINEAR_CHROMIUM:
3905 case GL_CONSTANT_CHROMIUM:
3906 if (components < 1 || components > 4)
3907 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003908 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003909 return false;
3910 }
3911 if (!coeffs)
3912 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003913 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003914 return false;
3915 }
3916 break;
3917
3918 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003919 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003920 return false;
3921 }
3922
3923 // If the location is -1 then the command is silently ignored
3924 // and no further validation is needed.
3925 if (location == -1)
3926 return true;
3927
jchen103fd614d2018-08-13 12:21:58 +08003928 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003929
3930 if (!binding.valid)
3931 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003932 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003933 return false;
3934 }
3935
3936 if (binding.type != GL_NONE)
3937 {
3938 GLint expectedComponents = 0;
3939 switch (binding.type)
3940 {
3941 case GL_FLOAT:
3942 expectedComponents = 1;
3943 break;
3944 case GL_FLOAT_VEC2:
3945 expectedComponents = 2;
3946 break;
3947 case GL_FLOAT_VEC3:
3948 expectedComponents = 3;
3949 break;
3950 case GL_FLOAT_VEC4:
3951 expectedComponents = 4;
3952 break;
3953 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003954 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003955 InvalidOperation()
3956 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003957 return false;
3958 }
3959 if (expectedComponents != components && genMode != GL_NONE)
3960 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003961 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003962 return false;
3963 }
3964 }
3965 return true;
3966}
3967
Geoff Lang97073d12016-04-20 10:42:34 -07003968bool ValidateCopyTextureCHROMIUM(Context *context,
3969 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003970 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003971 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003972 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003973 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003974 GLint internalFormat,
3975 GLenum destType,
3976 GLboolean unpackFlipY,
3977 GLboolean unpackPremultiplyAlpha,
3978 GLboolean unpackUnmultiplyAlpha)
3979{
3980 if (!context->getExtensions().copyTexture)
3981 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003982 context->handleError(InvalidOperation()
3983 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003984 return false;
3985 }
3986
Geoff Lang4f0e0032017-05-01 16:04:35 -04003987 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003988 if (source == nullptr)
3989 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003990 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003991 return false;
3992 }
3993
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003994 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003995 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07003996 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003997 return false;
3998 }
3999
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004000 TextureType sourceType = source->getType();
4001 ASSERT(sourceType != TextureType::CubeMap);
4002 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004003
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004004 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004006 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004007 return false;
4008 }
4009
Geoff Lang4f0e0032017-05-01 16:04:35 -04004010 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4011 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4012 if (sourceWidth == 0 || sourceHeight == 0)
4013 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004014 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004015 return false;
4016 }
4017
4018 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4019 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004021 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
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
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004039 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), 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
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004045 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004046 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004047 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004048 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004049 return false;
4050 }
4051
Geoff Lang97073d12016-04-20 10:42:34 -07004052 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4053 {
Geoff Lang97073d12016-04-20 10:42:34 -07004054 return false;
4055 }
4056
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004057 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004058 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004059 context->handleError(
4060 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004061 return false;
4062 }
4063
Geoff Lang97073d12016-04-20 10:42:34 -07004064 if (dest->getImmutableFormat())
4065 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004066 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07004067 return false;
4068 }
4069
4070 return true;
4071}
4072
4073bool ValidateCopySubTextureCHROMIUM(Context *context,
4074 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004075 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004076 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004077 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004078 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004079 GLint xoffset,
4080 GLint yoffset,
4081 GLint x,
4082 GLint y,
4083 GLsizei width,
4084 GLsizei height,
4085 GLboolean unpackFlipY,
4086 GLboolean unpackPremultiplyAlpha,
4087 GLboolean unpackUnmultiplyAlpha)
4088{
4089 if (!context->getExtensions().copyTexture)
4090 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004091 context->handleError(InvalidOperation()
4092 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004093 return false;
4094 }
4095
Geoff Lang4f0e0032017-05-01 16:04:35 -04004096 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004097 if (source == nullptr)
4098 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004099 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004100 return false;
4101 }
4102
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004103 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004104 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004105 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004106 return false;
4107 }
4108
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004109 TextureType sourceType = source->getType();
4110 ASSERT(sourceType != TextureType::CubeMap);
4111 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004112
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004113 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004114 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004115 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004116 return false;
4117 }
4118
4119 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4120 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004121 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004122 context->handleError(InvalidValue()
4123 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004124 return false;
4125 }
4126
4127 if (x < 0 || y < 0)
4128 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004129 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004130 return false;
4131 }
4132
4133 if (width < 0 || height < 0)
4134 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004135 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004136 return false;
4137 }
4138
Geoff Lang4f0e0032017-05-01 16:04:35 -04004139 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4140 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004141 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004142 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004143 return false;
4144 }
4145
Geoff Lang4f0e0032017-05-01 16:04:35 -04004146 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4147 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004148 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004149 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004150 return false;
4151 }
4152
Geoff Lang63458a32017-10-30 15:16:53 -04004153 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4154 {
4155 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4156 return false;
4157 }
4158
Geoff Lang4f0e0032017-05-01 16:04:35 -04004159 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004160 if (dest == nullptr)
4161 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004162 context->handleError(InvalidValue()
4163 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004164 return false;
4165 }
4166
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004167 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004168 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004169 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004170 return false;
4171 }
4172
Brandon Jones28783792018-03-05 09:37:32 -08004173 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4174 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004175 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004176 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004177 return false;
4178 }
4179
Geoff Lang4f0e0032017-05-01 16:04:35 -04004180 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4181 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004182 context
4183 ->handleError(InvalidOperation()
4184 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004185 return false;
4186 }
4187
4188 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4189 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004190 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004191 context->handleError(InvalidOperation()
4192 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004193 return false;
4194 }
4195
4196 if (xoffset < 0 || yoffset < 0)
4197 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004198 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004199 return false;
4200 }
4201
Geoff Lang4f0e0032017-05-01 16:04:35 -04004202 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4203 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004205 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004206 return false;
4207 }
4208
4209 return true;
4210}
4211
Geoff Lang47110bf2016-04-20 11:13:22 -07004212bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4213{
4214 if (!context->getExtensions().copyCompressedTexture)
4215 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004216 context->handleError(InvalidOperation()
4217 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004218 return false;
4219 }
4220
4221 const gl::Texture *source = context->getTexture(sourceId);
4222 if (source == nullptr)
4223 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004224 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004225 return false;
4226 }
4227
Corentin Wallez99d492c2018-02-27 15:17:10 -05004228 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004230 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004231 return false;
4232 }
4233
Corentin Wallez99d492c2018-02-27 15:17:10 -05004234 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4235 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004236 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004237 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004238 return false;
4239 }
4240
Corentin Wallez99d492c2018-02-27 15:17:10 -05004241 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004242 if (!sourceFormat.info->compressed)
4243 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004244 context->handleError(InvalidOperation()
4245 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004246 return false;
4247 }
4248
4249 const gl::Texture *dest = context->getTexture(destId);
4250 if (dest == nullptr)
4251 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004252 context->handleError(InvalidValue()
4253 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004254 return false;
4255 }
4256
Corentin Wallez99d492c2018-02-27 15:17:10 -05004257 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004258 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004259 context->handleError(InvalidValue()
4260 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004261 return false;
4262 }
4263
4264 if (dest->getImmutableFormat())
4265 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004266 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004267 return false;
4268 }
4269
4270 return true;
4271}
4272
Jiawei Shao385b3e02018-03-21 09:43:28 +08004273bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004274{
4275 switch (type)
4276 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004277 case ShaderType::Vertex:
4278 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004279 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004280
Jiawei Shao385b3e02018-03-21 09:43:28 +08004281 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004282 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004283 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004284 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004285 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004286 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004287 break;
4288
Jiawei Shao385b3e02018-03-21 09:43:28 +08004289 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004290 if (!context->getExtensions().geometryShader)
4291 {
4292 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4293 return false;
4294 }
4295 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004296 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004297 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004298 return false;
4299 }
Jamie Madill29639852016-09-02 15:00:09 -04004300
4301 return true;
4302}
4303
Jamie Madill5b772312018-03-08 20:28:32 -05004304bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004305 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004306 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004307 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004308 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004309{
4310 if (size < 0)
4311 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004312 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004313 return false;
4314 }
4315
4316 switch (usage)
4317 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004318 case BufferUsage::StreamDraw:
4319 case BufferUsage::StaticDraw:
4320 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004321 break;
4322
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004323 case BufferUsage::StreamRead:
4324 case BufferUsage::StaticRead:
4325 case BufferUsage::DynamicRead:
4326 case BufferUsage::StreamCopy:
4327 case BufferUsage::StaticCopy:
4328 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004329 if (context->getClientMajorVersion() < 3)
4330 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004331 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004332 return false;
4333 }
4334 break;
4335
4336 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004337 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004338 return false;
4339 }
4340
Corentin Walleze4477002017-12-01 14:39:58 -05004341 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004342 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004343 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004344 return false;
4345 }
4346
4347 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4348
4349 if (!buffer)
4350 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004351 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004352 return false;
4353 }
4354
James Darpiniane8a93c62018-01-04 18:02:24 -08004355 if (context->getExtensions().webglCompatibility &&
4356 buffer->isBoundForTransformFeedbackAndOtherUse())
4357 {
4358 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4359 return false;
4360 }
4361
Jamie Madill29639852016-09-02 15:00:09 -04004362 return true;
4363}
4364
Jamie Madill5b772312018-03-08 20:28:32 -05004365bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004366 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004367 GLintptr offset,
4368 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004369 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004370{
Brandon Jones6cad5662017-06-14 13:25:13 -07004371 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004372 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004373 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4374 return false;
4375 }
4376
4377 if (offset < 0)
4378 {
4379 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004380 return false;
4381 }
4382
Corentin Walleze4477002017-12-01 14:39:58 -05004383 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004384 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004385 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004386 return false;
4387 }
4388
4389 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4390
4391 if (!buffer)
4392 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004394 return false;
4395 }
4396
4397 if (buffer->isMapped())
4398 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004399 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004400 return false;
4401 }
4402
James Darpiniane8a93c62018-01-04 18:02:24 -08004403 if (context->getExtensions().webglCompatibility &&
4404 buffer->isBoundForTransformFeedbackAndOtherUse())
4405 {
4406 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4407 return false;
4408 }
4409
Jamie Madill29639852016-09-02 15:00:09 -04004410 // Check for possible overflow of size + offset
4411 angle::CheckedNumeric<size_t> checkedSize(size);
4412 checkedSize += offset;
4413 if (!checkedSize.IsValid())
4414 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004415 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004416 return false;
4417 }
4418
4419 if (size + offset > buffer->getSize())
4420 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004421 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004422 return false;
4423 }
4424
Martin Radev4c4c8e72016-08-04 12:25:34 +03004425 return true;
4426}
4427
Geoff Lang111a99e2017-10-17 10:58:41 -04004428bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004429{
Geoff Langc339c4e2016-11-29 10:37:36 -05004430 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004431 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004432 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004433 return false;
4434 }
4435
Geoff Lang111a99e2017-10-17 10:58:41 -04004436 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004437 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004438 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004439 return false;
4440 }
4441
4442 return true;
4443}
4444
Jamie Madill5b772312018-03-08 20:28:32 -05004445bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004446{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004447 if (context->getClientMajorVersion() < 2)
4448 {
4449 return ValidateMultitextureUnit(context, texture);
4450 }
4451
Jamie Madillef300b12016-10-07 15:12:09 -04004452 if (texture < GL_TEXTURE0 ||
4453 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4454 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004455 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004456 return false;
4457 }
4458
4459 return true;
4460}
4461
Jamie Madill5b772312018-03-08 20:28:32 -05004462bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004463{
4464 Program *programObject = GetValidProgram(context, program);
4465 if (!programObject)
4466 {
4467 return false;
4468 }
4469
4470 Shader *shaderObject = GetValidShader(context, shader);
4471 if (!shaderObject)
4472 {
4473 return false;
4474 }
4475
Jiawei Shao385b3e02018-03-21 09:43:28 +08004476 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004477 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004478 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4479 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004480 }
4481
4482 return true;
4483}
4484
Jamie Madill5b772312018-03-08 20:28:32 -05004485bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004486{
4487 if (index >= MAX_VERTEX_ATTRIBS)
4488 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004489 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004490 return false;
4491 }
4492
4493 if (strncmp(name, "gl_", 3) == 0)
4494 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004495 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004496 return false;
4497 }
4498
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004499 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004500 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004501 const size_t length = strlen(name);
4502
4503 if (!IsValidESSLString(name, length))
4504 {
4505 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4506 // for shader-related entry points
4507 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4508 return false;
4509 }
4510
4511 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4512 {
4513 return false;
4514 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004515 }
4516
Jamie Madill01a80ee2016-11-07 12:06:18 -05004517 return GetValidProgram(context, program) != nullptr;
4518}
4519
Jamie Madill5b772312018-03-08 20:28:32 -05004520bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004521{
Geoff Lange8afa902017-09-27 15:00:43 -04004522 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004523 {
Jamie Madilla139f012018-10-10 16:13:03 -04004524 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004525 return false;
4526 }
4527
4528 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4529 !context->isFramebufferGenerated(framebuffer))
4530 {
Jamie Madilla139f012018-10-10 16:13:03 -04004531 context->validationError(GL_INVALID_OPERATION, kErrorObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004532 return false;
4533 }
4534
4535 return true;
4536}
4537
Jamie Madill5b772312018-03-08 20:28:32 -05004538bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004539{
4540 if (target != GL_RENDERBUFFER)
4541 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004542 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004543 return false;
4544 }
4545
4546 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4547 !context->isRenderbufferGenerated(renderbuffer))
4548 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004549 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004550 return false;
4551 }
4552
4553 return true;
4554}
4555
Jamie Madill5b772312018-03-08 20:28:32 -05004556static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004557{
4558 switch (mode)
4559 {
4560 case GL_FUNC_ADD:
4561 case GL_FUNC_SUBTRACT:
4562 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004563 return true;
4564
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004565 case GL_MIN:
4566 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004567 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004568
4569 default:
4570 return false;
4571 }
4572}
4573
Jamie Madill5b772312018-03-08 20:28:32 -05004574bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004575{
4576 return true;
4577}
4578
Jamie Madill5b772312018-03-08 20:28:32 -05004579bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004580{
Geoff Lang50cac572017-09-26 17:37:43 -04004581 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004582 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004583 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004584 return false;
4585 }
4586
4587 return true;
4588}
4589
Jamie Madill5b772312018-03-08 20:28:32 -05004590bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004591{
Geoff Lang50cac572017-09-26 17:37:43 -04004592 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004593 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004594 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004595 return false;
4596 }
4597
Geoff Lang50cac572017-09-26 17:37:43 -04004598 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004599 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004600 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004601 return false;
4602 }
4603
4604 return true;
4605}
4606
Jamie Madill5b772312018-03-08 20:28:32 -05004607bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004608{
4609 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4610}
4611
Jamie Madill5b772312018-03-08 20:28:32 -05004612bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004613 GLenum srcRGB,
4614 GLenum dstRGB,
4615 GLenum srcAlpha,
4616 GLenum dstAlpha)
4617{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004618 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004619 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004620 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004621 return false;
4622 }
4623
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004624 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004625 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004626 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004627 return false;
4628 }
4629
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004630 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004631 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004632 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004633 return false;
4634 }
4635
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004636 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004637 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004638 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004639 return false;
4640 }
4641
Frank Henigman146e8a12017-03-02 23:22:37 -05004642 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4643 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004644 {
4645 bool constantColorUsed =
4646 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4647 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4648
4649 bool constantAlphaUsed =
4650 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4651 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4652
4653 if (constantColorUsed && constantAlphaUsed)
4654 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004655 const char *msg;
4656 if (context->getExtensions().webglCompatibility)
4657 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004658 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004659 }
4660 else
4661 {
4662 msg =
4663 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4664 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4665 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004666 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004667 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004668 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004669 return false;
4670 }
4671 }
4672
4673 return true;
4674}
4675
Geoff Langc339c4e2016-11-29 10:37:36 -05004676bool ValidateGetString(Context *context, GLenum name)
4677{
4678 switch (name)
4679 {
4680 case GL_VENDOR:
4681 case GL_RENDERER:
4682 case GL_VERSION:
4683 case GL_SHADING_LANGUAGE_VERSION:
4684 case GL_EXTENSIONS:
4685 break;
4686
4687 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4688 if (!context->getExtensions().requestExtension)
4689 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004690 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004691 return false;
4692 }
4693 break;
4694
4695 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004696 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004697 return false;
4698 }
4699
4700 return true;
4701}
4702
Jamie Madill5b772312018-03-08 20:28:32 -05004703bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004704{
4705 if (width <= 0.0f || isNaN(width))
4706 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004707 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004708 return false;
4709 }
4710
4711 return true;
4712}
4713
Jamie Madill5b772312018-03-08 20:28:32 -05004714bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004715 GLuint index,
4716 GLint size,
4717 GLenum type,
4718 GLboolean normalized,
4719 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004720 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004721{
Shao80957d92017-02-20 21:25:59 +08004722 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004723 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004724 return false;
4725 }
4726
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004727 if (stride < 0)
4728 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004729 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004730 return false;
4731 }
4732
Shao80957d92017-02-20 21:25:59 +08004733 const Caps &caps = context->getCaps();
4734 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004735 {
Shao80957d92017-02-20 21:25:59 +08004736 if (stride > caps.maxVertexAttribStride)
4737 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004738 context->handleError(InvalidValue()
4739 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004740 return false;
4741 }
4742
4743 if (index >= caps.maxVertexAttribBindings)
4744 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004745 context->handleError(InvalidValue()
4746 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004747 return false;
4748 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004749 }
4750
4751 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4752 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4753 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4754 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004755 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4756 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004757 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4758 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004759 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004760 context
4761 ->handleError(InvalidOperation()
4762 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004763 return false;
4764 }
4765
4766 if (context->getExtensions().webglCompatibility)
4767 {
4768 // WebGL 1.0 [Section 6.14] Fixed point support
4769 // The WebGL API does not support the GL_FIXED data type.
4770 if (type == GL_FIXED)
4771 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004772 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004773 return false;
4774 }
4775
Geoff Lang2d62ab72017-03-23 16:54:40 -04004776 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004777 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004778 return false;
4779 }
4780 }
4781
4782 return true;
4783}
4784
Jamie Madill5b772312018-03-08 20:28:32 -05004785bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004786{
4787 if (context->getExtensions().webglCompatibility && zNear > zFar)
4788 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004789 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004790 return false;
4791 }
4792
4793 return true;
4794}
4795
Jamie Madill5b772312018-03-08 20:28:32 -05004796bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004797 GLenum target,
4798 GLenum internalformat,
4799 GLsizei width,
4800 GLsizei height)
4801{
4802 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4803 height);
4804}
4805
Jamie Madill5b772312018-03-08 20:28:32 -05004806bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004807 GLenum target,
4808 GLsizei samples,
4809 GLenum internalformat,
4810 GLsizei width,
4811 GLsizei height)
4812{
4813 if (!context->getExtensions().framebufferMultisample)
4814 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004815 context->handleError(InvalidOperation()
4816 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004817 return false;
4818 }
4819
4820 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4821 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4822 // generated.
4823 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4824 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004825 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004826 return false;
4827 }
4828
4829 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4830 // the specified storage. This is different than ES 3.0 in which a sample number higher
4831 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4832 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4833 if (context->getClientMajorVersion() >= 3)
4834 {
4835 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4836 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4837 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004838 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004839 return false;
4840 }
4841 }
4842
4843 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4844 width, height);
4845}
4846
Jamie Madill5b772312018-03-08 20:28:32 -05004847bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004848{
Geoff Lange8afa902017-09-27 15:00:43 -04004849 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004850 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004851 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004852 return false;
4853 }
4854
4855 return true;
4856}
4857
Jamie Madill5b772312018-03-08 20:28:32 -05004858bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004859{
4860 return true;
4861}
4862
Jamie Madill5b772312018-03-08 20:28:32 -05004863bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004864{
4865 return true;
4866}
4867
Jamie Madill5b772312018-03-08 20:28:32 -05004868bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004869{
4870 return true;
4871}
4872
Jamie Madill5b772312018-03-08 20:28:32 -05004873bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004874 GLboolean red,
4875 GLboolean green,
4876 GLboolean blue,
4877 GLboolean alpha)
4878{
4879 return true;
4880}
4881
Jamie Madill5b772312018-03-08 20:28:32 -05004882bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004883{
4884 return true;
4885}
4886
Jamie Madill5b772312018-03-08 20:28:32 -05004887bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004888{
4889 return true;
4890}
4891
Jamie Madill5b772312018-03-08 20:28:32 -05004892bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004893{
4894 switch (mode)
4895 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004896 case CullFaceMode::Front:
4897 case CullFaceMode::Back:
4898 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004899 break;
4900
4901 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004902 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004903 return false;
4904 }
4905
4906 return true;
4907}
4908
Jamie Madill5b772312018-03-08 20:28:32 -05004909bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004910{
4911 if (program == 0)
4912 {
4913 return false;
4914 }
4915
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004916 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004917 {
4918 if (context->getShader(program))
4919 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004920 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004921 return false;
4922 }
4923 else
4924 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004925 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004926 return false;
4927 }
4928 }
4929
4930 return true;
4931}
4932
Jamie Madill5b772312018-03-08 20:28:32 -05004933bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004934{
4935 if (shader == 0)
4936 {
4937 return false;
4938 }
4939
4940 if (!context->getShader(shader))
4941 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004942 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004943 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004944 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004945 return false;
4946 }
4947 else
4948 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004949 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004950 return false;
4951 }
4952 }
4953
4954 return true;
4955}
4956
Jamie Madill5b772312018-03-08 20:28:32 -05004957bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004958{
4959 switch (func)
4960 {
4961 case GL_NEVER:
4962 case GL_ALWAYS:
4963 case GL_LESS:
4964 case GL_LEQUAL:
4965 case GL_EQUAL:
4966 case GL_GREATER:
4967 case GL_GEQUAL:
4968 case GL_NOTEQUAL:
4969 break;
4970
4971 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004972 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004973 return false;
4974 }
4975
4976 return true;
4977}
4978
Jamie Madill5b772312018-03-08 20:28:32 -05004979bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004980{
4981 return true;
4982}
4983
Jamie Madill5b772312018-03-08 20:28:32 -05004984bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004985{
4986 Program *programObject = GetValidProgram(context, program);
4987 if (!programObject)
4988 {
4989 return false;
4990 }
4991
4992 Shader *shaderObject = GetValidShader(context, shader);
4993 if (!shaderObject)
4994 {
4995 return false;
4996 }
4997
Jiawei Shao385b3e02018-03-21 09:43:28 +08004998 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004999 if (attachedShader != shaderObject)
5000 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005001 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005002 return false;
5003 }
5004
5005 return true;
5006}
5007
Jamie Madill5b772312018-03-08 20:28:32 -05005008bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005009{
5010 if (index >= MAX_VERTEX_ATTRIBS)
5011 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005012 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005013 return false;
5014 }
5015
5016 return true;
5017}
5018
Jamie Madill5b772312018-03-08 20:28:32 -05005019bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005020{
5021 if (index >= MAX_VERTEX_ATTRIBS)
5022 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005023 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005024 return false;
5025 }
5026
5027 return true;
5028}
5029
Jamie Madill5b772312018-03-08 20:28:32 -05005030bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005031{
5032 return true;
5033}
5034
Jamie Madill5b772312018-03-08 20:28:32 -05005035bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005036{
5037 return true;
5038}
5039
Jamie Madill5b772312018-03-08 20:28:32 -05005040bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005041{
5042 switch (mode)
5043 {
5044 case GL_CW:
5045 case GL_CCW:
5046 break;
5047 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005048 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005049 return false;
5050 }
5051
5052 return true;
5053}
5054
Jamie Madill5b772312018-03-08 20:28:32 -05005055bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005056 GLuint program,
5057 GLuint index,
5058 GLsizei bufsize,
5059 GLsizei *length,
5060 GLint *size,
5061 GLenum *type,
5062 GLchar *name)
5063{
5064 if (bufsize < 0)
5065 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005066 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005067 return false;
5068 }
5069
5070 Program *programObject = GetValidProgram(context, program);
5071
5072 if (!programObject)
5073 {
5074 return false;
5075 }
5076
5077 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5078 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005079 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005080 return false;
5081 }
5082
5083 return true;
5084}
5085
Jamie Madill5b772312018-03-08 20:28:32 -05005086bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005087 GLuint program,
5088 GLuint index,
5089 GLsizei bufsize,
5090 GLsizei *length,
5091 GLint *size,
5092 GLenum *type,
5093 GLchar *name)
5094{
5095 if (bufsize < 0)
5096 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005097 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005098 return false;
5099 }
5100
5101 Program *programObject = GetValidProgram(context, program);
5102
5103 if (!programObject)
5104 {
5105 return false;
5106 }
5107
5108 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5109 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005110 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005111 return false;
5112 }
5113
5114 return true;
5115}
5116
Jamie Madill5b772312018-03-08 20:28:32 -05005117bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005118 GLuint program,
5119 GLsizei maxcount,
5120 GLsizei *count,
5121 GLuint *shaders)
5122{
5123 if (maxcount < 0)
5124 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005125 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005126 return false;
5127 }
5128
5129 Program *programObject = GetValidProgram(context, program);
5130
5131 if (!programObject)
5132 {
5133 return false;
5134 }
5135
5136 return true;
5137}
5138
Jamie Madill5b772312018-03-08 20:28:32 -05005139bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005140{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005141 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5142 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005143 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005144 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005145 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005146 return false;
5147 }
5148
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149 Program *programObject = GetValidProgram(context, program);
5150
5151 if (!programObject)
5152 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005153 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005154 return false;
5155 }
5156
5157 if (!programObject->isLinked())
5158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005160 return false;
5161 }
5162
5163 return true;
5164}
5165
Jamie Madill5b772312018-03-08 20:28:32 -05005166bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005167{
5168 GLenum nativeType;
5169 unsigned int numParams = 0;
5170 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5171}
5172
Jamie Madill5b772312018-03-08 20:28:32 -05005173bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005174{
5175 return true;
5176}
5177
Jamie Madill5b772312018-03-08 20:28:32 -05005178bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005179{
5180 GLenum nativeType;
5181 unsigned int numParams = 0;
5182 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5183}
5184
Jamie Madill5b772312018-03-08 20:28:32 -05005185bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005186{
5187 GLenum nativeType;
5188 unsigned int numParams = 0;
5189 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5190}
5191
Jamie Madill5b772312018-03-08 20:28:32 -05005192bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005193 GLuint program,
5194 GLsizei bufsize,
5195 GLsizei *length,
5196 GLchar *infolog)
5197{
5198 if (bufsize < 0)
5199 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005200 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005201 return false;
5202 }
5203
5204 Program *programObject = GetValidProgram(context, program);
5205 if (!programObject)
5206 {
5207 return false;
5208 }
5209
5210 return true;
5211}
5212
Jamie Madill5b772312018-03-08 20:28:32 -05005213bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005214 GLuint shader,
5215 GLsizei bufsize,
5216 GLsizei *length,
5217 GLchar *infolog)
5218{
5219 if (bufsize < 0)
5220 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005221 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005222 return false;
5223 }
5224
5225 Shader *shaderObject = GetValidShader(context, shader);
5226 if (!shaderObject)
5227 {
5228 return false;
5229 }
5230
5231 return true;
5232}
5233
Jamie Madill5b772312018-03-08 20:28:32 -05005234bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005235 GLenum shadertype,
5236 GLenum precisiontype,
5237 GLint *range,
5238 GLint *precision)
5239{
5240 switch (shadertype)
5241 {
5242 case GL_VERTEX_SHADER:
5243 case GL_FRAGMENT_SHADER:
5244 break;
5245 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005246 context->handleError(InvalidOperation()
5247 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005248 return false;
5249 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005250 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005251 return false;
5252 }
5253
5254 switch (precisiontype)
5255 {
5256 case GL_LOW_FLOAT:
5257 case GL_MEDIUM_FLOAT:
5258 case GL_HIGH_FLOAT:
5259 case GL_LOW_INT:
5260 case GL_MEDIUM_INT:
5261 case GL_HIGH_INT:
5262 break;
5263
5264 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005265 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005266 return false;
5267 }
5268
5269 return true;
5270}
5271
Jamie Madill5b772312018-03-08 20:28:32 -05005272bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005273 GLuint shader,
5274 GLsizei bufsize,
5275 GLsizei *length,
5276 GLchar *source)
5277{
5278 if (bufsize < 0)
5279 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005280 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005281 return false;
5282 }
5283
5284 Shader *shaderObject = GetValidShader(context, shader);
5285 if (!shaderObject)
5286 {
5287 return false;
5288 }
5289
5290 return true;
5291}
5292
Jamie Madill5b772312018-03-08 20:28:32 -05005293bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005294{
5295 if (strstr(name, "gl_") == name)
5296 {
5297 return false;
5298 }
5299
Geoff Langfc32e8b2017-05-31 14:16:59 -04005300 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5301 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005302 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005303 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005304 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005305 return false;
5306 }
5307
Jamie Madillc1d770e2017-04-13 17:31:24 -04005308 Program *programObject = GetValidProgram(context, program);
5309
5310 if (!programObject)
5311 {
5312 return false;
5313 }
5314
5315 if (!programObject->isLinked())
5316 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005317 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005318 return false;
5319 }
5320
5321 return true;
5322}
5323
Jamie Madill5b772312018-03-08 20:28:32 -05005324bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005325{
5326 switch (mode)
5327 {
5328 case GL_FASTEST:
5329 case GL_NICEST:
5330 case GL_DONT_CARE:
5331 break;
5332
5333 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005334 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005335 return false;
5336 }
5337
5338 switch (target)
5339 {
5340 case GL_GENERATE_MIPMAP_HINT:
5341 break;
5342
Geoff Lange7bd2182017-06-16 16:13:13 -04005343 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5344 if (context->getClientVersion() < ES_3_0 &&
5345 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005346 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005347 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005348 return false;
5349 }
5350 break;
5351
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005352 case GL_PERSPECTIVE_CORRECTION_HINT:
5353 case GL_POINT_SMOOTH_HINT:
5354 case GL_LINE_SMOOTH_HINT:
5355 case GL_FOG_HINT:
5356 if (context->getClientMajorVersion() >= 2)
5357 {
5358 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5359 return false;
5360 }
5361 break;
5362
Jamie Madillc1d770e2017-04-13 17:31:24 -04005363 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005364 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005365 return false;
5366 }
5367
5368 return true;
5369}
5370
Jamie Madill5b772312018-03-08 20:28:32 -05005371bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005372{
5373 return true;
5374}
5375
Jamie Madill5b772312018-03-08 20:28:32 -05005376bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005377{
5378 return true;
5379}
5380
Jamie Madill5b772312018-03-08 20:28:32 -05005381bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005382{
5383 return true;
5384}
5385
Jamie Madill5b772312018-03-08 20:28:32 -05005386bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005387{
5388 return true;
5389}
5390
Jamie Madill5b772312018-03-08 20:28:32 -05005391bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005392{
5393 return true;
5394}
5395
Jamie Madill5b772312018-03-08 20:28:32 -05005396bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397{
5398 return true;
5399}
5400
Jamie Madill5b772312018-03-08 20:28:32 -05005401bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005402{
5403 if (context->getClientMajorVersion() < 3)
5404 {
5405 switch (pname)
5406 {
5407 case GL_UNPACK_IMAGE_HEIGHT:
5408 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005409 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005410 return false;
5411
5412 case GL_UNPACK_ROW_LENGTH:
5413 case GL_UNPACK_SKIP_ROWS:
5414 case GL_UNPACK_SKIP_PIXELS:
5415 if (!context->getExtensions().unpackSubimage)
5416 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005417 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005418 return false;
5419 }
5420 break;
5421
5422 case GL_PACK_ROW_LENGTH:
5423 case GL_PACK_SKIP_ROWS:
5424 case GL_PACK_SKIP_PIXELS:
5425 if (!context->getExtensions().packSubimage)
5426 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005427 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005428 return false;
5429 }
5430 break;
5431 }
5432 }
5433
5434 if (param < 0)
5435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005436 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005437 return false;
5438 }
5439
5440 switch (pname)
5441 {
5442 case GL_UNPACK_ALIGNMENT:
5443 if (param != 1 && param != 2 && param != 4 && param != 8)
5444 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005445 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005446 return false;
5447 }
5448 break;
5449
5450 case GL_PACK_ALIGNMENT:
5451 if (param != 1 && param != 2 && param != 4 && param != 8)
5452 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005453 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005454 return false;
5455 }
5456 break;
5457
5458 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005459 if (!context->getExtensions().packReverseRowOrder)
5460 {
5461 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5462 }
5463 break;
5464
Jamie Madillc1d770e2017-04-13 17:31:24 -04005465 case GL_UNPACK_ROW_LENGTH:
5466 case GL_UNPACK_IMAGE_HEIGHT:
5467 case GL_UNPACK_SKIP_IMAGES:
5468 case GL_UNPACK_SKIP_ROWS:
5469 case GL_UNPACK_SKIP_PIXELS:
5470 case GL_PACK_ROW_LENGTH:
5471 case GL_PACK_SKIP_ROWS:
5472 case GL_PACK_SKIP_PIXELS:
5473 break;
5474
5475 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005476 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477 return false;
5478 }
5479
5480 return true;
5481}
5482
Jamie Madill5b772312018-03-08 20:28:32 -05005483bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005484{
5485 return true;
5486}
5487
Jamie Madill5b772312018-03-08 20:28:32 -05005488bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005489{
5490 return true;
5491}
5492
Jamie Madill5b772312018-03-08 20:28:32 -05005493bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494{
5495 return true;
5496}
5497
Jamie Madill5b772312018-03-08 20:28:32 -05005498bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005499{
5500 if (width < 0 || height < 0)
5501 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005502 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005503 return false;
5504 }
5505
5506 return true;
5507}
5508
Jamie Madill5b772312018-03-08 20:28:32 -05005509bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005510 GLsizei n,
5511 const GLuint *shaders,
5512 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005513 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005514 GLsizei length)
5515{
5516 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5517 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5518 shaderBinaryFormats.end())
5519 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005520 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005521 return false;
5522 }
5523
5524 return true;
5525}
5526
Jamie Madill5b772312018-03-08 20:28:32 -05005527bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005528 GLuint shader,
5529 GLsizei count,
5530 const GLchar *const *string,
5531 const GLint *length)
5532{
5533 if (count < 0)
5534 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005535 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005536 return false;
5537 }
5538
Geoff Langfc32e8b2017-05-31 14:16:59 -04005539 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5540 // shader-related entry points
5541 if (context->getExtensions().webglCompatibility)
5542 {
5543 for (GLsizei i = 0; i < count; i++)
5544 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005545 size_t len =
5546 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005547
5548 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005549 if (!IsValidESSLShaderSourceString(string[i], len,
5550 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005552 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005553 return false;
5554 }
5555 }
5556 }
5557
Jamie Madillc1d770e2017-04-13 17:31:24 -04005558 Shader *shaderObject = GetValidShader(context, shader);
5559 if (!shaderObject)
5560 {
5561 return false;
5562 }
5563
5564 return true;
5565}
5566
Jamie Madill5b772312018-03-08 20:28:32 -05005567bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005568{
5569 if (!IsValidStencilFunc(func))
5570 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005571 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005572 return false;
5573 }
5574
5575 return true;
5576}
5577
Jamie Madill5b772312018-03-08 20:28:32 -05005578bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005579{
5580 if (!IsValidStencilFace(face))
5581 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005582 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005583 return false;
5584 }
5585
5586 if (!IsValidStencilFunc(func))
5587 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005588 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005589 return false;
5590 }
5591
5592 return true;
5593}
5594
Jamie Madill5b772312018-03-08 20:28:32 -05005595bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596{
5597 return true;
5598}
5599
Jamie Madill5b772312018-03-08 20:28:32 -05005600bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005601{
5602 if (!IsValidStencilFace(face))
5603 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005604 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005605 return false;
5606 }
5607
5608 return true;
5609}
5610
Jamie Madill5b772312018-03-08 20:28:32 -05005611bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005612{
5613 if (!IsValidStencilOp(fail))
5614 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005615 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005616 return false;
5617 }
5618
5619 if (!IsValidStencilOp(zfail))
5620 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005621 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005622 return false;
5623 }
5624
5625 if (!IsValidStencilOp(zpass))
5626 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005627 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005628 return false;
5629 }
5630
5631 return true;
5632}
5633
Jamie Madill5b772312018-03-08 20:28:32 -05005634bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005635 GLenum face,
5636 GLenum fail,
5637 GLenum zfail,
5638 GLenum zpass)
5639{
5640 if (!IsValidStencilFace(face))
5641 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005642 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005643 return false;
5644 }
5645
5646 return ValidateStencilOp(context, fail, zfail, zpass);
5647}
5648
Jamie Madill5b772312018-03-08 20:28:32 -05005649bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650{
5651 return ValidateUniform(context, GL_FLOAT, location, 1);
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655{
5656 return ValidateUniform(context, GL_FLOAT, location, count);
5657}
5658
Jamie Madill5b772312018-03-08 20:28:32 -05005659bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005660{
5661 return ValidateUniform1iv(context, location, 1, &x);
5662}
5663
Jamie Madill5b772312018-03-08 20:28:32 -05005664bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005665{
5666 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670{
5671 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5672}
5673
Jamie Madill5b772312018-03-08 20:28:32 -05005674bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675{
5676 return ValidateUniform(context, GL_INT_VEC2, location, count);
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005680{
5681 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5682}
5683
Jamie Madill5b772312018-03-08 20:28:32 -05005684bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005685{
5686 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5687}
5688
Jamie Madill5b772312018-03-08 20:28:32 -05005689bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005690{
5691 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5692}
5693
Jamie Madill5b772312018-03-08 20:28:32 -05005694bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005695{
5696 return ValidateUniform(context, GL_INT_VEC3, location, count);
5697}
5698
Jamie Madill5b772312018-03-08 20:28:32 -05005699bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005700{
5701 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5702}
5703
Jamie Madill5b772312018-03-08 20:28:32 -05005704bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005705{
5706 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5707}
5708
Jamie Madill5b772312018-03-08 20:28:32 -05005709bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005710{
5711 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5712}
5713
Jamie Madill5b772312018-03-08 20:28:32 -05005714bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005715{
5716 return ValidateUniform(context, GL_INT_VEC4, location, count);
5717}
5718
Jamie Madill5b772312018-03-08 20:28:32 -05005719bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005720 GLint location,
5721 GLsizei count,
5722 GLboolean transpose,
5723 const GLfloat *value)
5724{
5725 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5726}
5727
Jamie Madill5b772312018-03-08 20:28:32 -05005728bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005729 GLint location,
5730 GLsizei count,
5731 GLboolean transpose,
5732 const GLfloat *value)
5733{
5734 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5735}
5736
Jamie Madill5b772312018-03-08 20:28:32 -05005737bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005738 GLint location,
5739 GLsizei count,
5740 GLboolean transpose,
5741 const GLfloat *value)
5742{
5743 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5744}
5745
Jamie Madill5b772312018-03-08 20:28:32 -05005746bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005747{
5748 Program *programObject = GetValidProgram(context, program);
5749
5750 if (!programObject)
5751 {
5752 return false;
5753 }
5754
5755 return true;
5756}
5757
Jamie Madill5b772312018-03-08 20:28:32 -05005758bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005759{
5760 return ValidateVertexAttribIndex(context, index);
5761}
5762
Jamie Madill5b772312018-03-08 20:28:32 -05005763bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005764{
5765 return ValidateVertexAttribIndex(context, index);
5766}
5767
Jamie Madill5b772312018-03-08 20:28:32 -05005768bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005769{
5770 return ValidateVertexAttribIndex(context, index);
5771}
5772
Jamie Madill5b772312018-03-08 20:28:32 -05005773bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005774{
5775 return ValidateVertexAttribIndex(context, index);
5776}
5777
Jamie Madill5b772312018-03-08 20:28:32 -05005778bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005779{
5780 return ValidateVertexAttribIndex(context, index);
5781}
5782
Jamie Madill5b772312018-03-08 20:28:32 -05005783bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005784{
5785 return ValidateVertexAttribIndex(context, index);
5786}
5787
Jamie Madill5b772312018-03-08 20:28:32 -05005788bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005789 GLuint index,
5790 GLfloat x,
5791 GLfloat y,
5792 GLfloat z,
5793 GLfloat w)
5794{
5795 return ValidateVertexAttribIndex(context, index);
5796}
5797
Jamie Madill5b772312018-03-08 20:28:32 -05005798bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005799{
5800 return ValidateVertexAttribIndex(context, index);
5801}
5802
Jamie Madill5b772312018-03-08 20:28:32 -05005803bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005804{
5805 if (width < 0 || height < 0)
5806 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005807 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005808 return false;
5809 }
5810
5811 return true;
5812}
5813
Jamie Madill5b772312018-03-08 20:28:32 -05005814bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005815 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005816 GLsizei count,
5817 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005818 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005819{
5820 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5821}
5822
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005823bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005824 GLenum target,
5825 GLenum attachment,
5826 GLenum pname,
5827 GLint *params)
5828{
5829 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5830 nullptr);
5831}
5832
Jamie Madill5b772312018-03-08 20:28:32 -05005833bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005834{
5835 return ValidateGetProgramivBase(context, program, pname, nullptr);
5836}
5837
Jamie Madill5b772312018-03-08 20:28:32 -05005838bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005839 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005840 GLint level,
5841 GLenum internalformat,
5842 GLint x,
5843 GLint y,
5844 GLsizei width,
5845 GLsizei height,
5846 GLint border)
5847{
5848 if (context->getClientMajorVersion() < 3)
5849 {
5850 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5851 0, x, y, width, height, border);
5852 }
5853
5854 ASSERT(context->getClientMajorVersion() == 3);
5855 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5856 0, x, y, width, height, border);
5857}
5858
5859bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005860 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005861 GLint level,
5862 GLint xoffset,
5863 GLint yoffset,
5864 GLint x,
5865 GLint y,
5866 GLsizei width,
5867 GLsizei height)
5868{
5869 if (context->getClientMajorVersion() < 3)
5870 {
5871 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5872 yoffset, x, y, width, height, 0);
5873 }
5874
5875 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5876 yoffset, 0, x, y, width, height, 0);
5877}
5878
5879bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5880{
5881 return ValidateGenOrDelete(context, n);
5882}
5883
5884bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5885{
5886 return ValidateGenOrDelete(context, n);
5887}
5888
5889bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5890{
5891 return ValidateGenOrDelete(context, n);
5892}
5893
5894bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5895{
5896 return ValidateGenOrDelete(context, n);
5897}
5898
5899bool ValidateDisable(Context *context, GLenum cap)
5900{
5901 if (!ValidCap(context, cap, false))
5902 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005903 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005904 return false;
5905 }
5906
5907 return true;
5908}
5909
5910bool ValidateEnable(Context *context, GLenum cap)
5911{
5912 if (!ValidCap(context, cap, false))
5913 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005914 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005915 return false;
5916 }
5917
5918 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5919 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5920 {
5921 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005922 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005923
5924 // We also output an error message to the debugger window if tracing is active, so that
5925 // developers can see the error message.
5926 ERR() << errorMessage;
5927 return false;
5928 }
5929
5930 return true;
5931}
5932
5933bool ValidateFramebufferRenderbuffer(Context *context,
5934 GLenum target,
5935 GLenum attachment,
5936 GLenum renderbuffertarget,
5937 GLuint renderbuffer)
5938{
Geoff Lange8afa902017-09-27 15:00:43 -04005939 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005940 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005941 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5942 return false;
5943 }
5944
5945 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5946 {
5947 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005948 return false;
5949 }
5950
5951 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5952 renderbuffertarget, renderbuffer);
5953}
5954
5955bool ValidateFramebufferTexture2D(Context *context,
5956 GLenum target,
5957 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005958 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005959 GLuint texture,
5960 GLint level)
5961{
5962 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5963 // extension
5964 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5965 level != 0)
5966 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005967 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005968 return false;
5969 }
5970
5971 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5972 {
5973 return false;
5974 }
5975
5976 if (texture != 0)
5977 {
5978 gl::Texture *tex = context->getTexture(texture);
5979 ASSERT(tex);
5980
5981 const gl::Caps &caps = context->getCaps();
5982
5983 switch (textarget)
5984 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005985 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005986 {
5987 if (level > gl::log2(caps.max2DTextureSize))
5988 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005989 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005990 return false;
5991 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005992 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005993 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005994 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005995 return false;
5996 }
5997 }
5998 break;
5999
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006000 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006001 {
6002 if (level != 0)
6003 {
6004 context->handleError(InvalidValue());
6005 return false;
6006 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006007 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006008 {
6009 context->handleError(InvalidOperation()
6010 << "Textarget must match the texture target type.");
6011 return false;
6012 }
6013 }
6014 break;
6015
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006016 case TextureTarget::CubeMapNegativeX:
6017 case TextureTarget::CubeMapNegativeY:
6018 case TextureTarget::CubeMapNegativeZ:
6019 case TextureTarget::CubeMapPositiveX:
6020 case TextureTarget::CubeMapPositiveY:
6021 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006022 {
6023 if (level > gl::log2(caps.maxCubeMapTextureSize))
6024 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006025 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006026 return false;
6027 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006028 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006029 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006030 context->handleError(InvalidOperation()
6031 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006032 return false;
6033 }
6034 }
6035 break;
6036
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006037 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006038 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006039 if (context->getClientVersion() < ES_3_1 &&
6040 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006041 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006042 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
6043 MultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006044 return false;
6045 }
6046
6047 if (level != 0)
6048 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006049 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006050 return false;
6051 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006052 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006053 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006054 context->handleError(InvalidOperation()
6055 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006056 return false;
6057 }
6058 }
6059 break;
6060
6061 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006062 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006063 return false;
6064 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006065 }
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
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006090bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006091{
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
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006116 TextureTarget baseTarget = (target == TextureType::CubeMap)
6117 ? TextureTarget::CubeMapPositiveX
6118 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006119 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6120 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6121 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006122 {
6123 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6124 return false;
6125 }
6126
Geoff Lang536eca12017-09-13 11:23:35 -04006127 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6128 bool formatUnsized = !format.sized;
6129 bool formatColorRenderableAndFilterable =
6130 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006131 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006132 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006133 {
Geoff Lang536eca12017-09-13 11:23:35 -04006134 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006135 return false;
6136 }
6137
Geoff Lang536eca12017-09-13 11:23:35 -04006138 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6139 // generation
6140 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6141 {
6142 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6143 return false;
6144 }
6145
Jiange2c00842018-07-13 16:50:49 +08006146 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6147 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6148 if (context->getClientVersion() < Version(3, 0) && 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 Wallezf0e89be2017-11-08 14:00:32 -08006159 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6160 target == TextureType::CubeMap);
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
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006166 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006167 {
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
Jamie Madill5b772312018-03-08 20:28:32 -05006175bool ValidateGetBufferParameteriv(Context *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
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006196bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006197{
6198 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6199}
6200
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006201bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006202{
6203 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6204}
6205
Till Rathmannb8543632018-10-02 19:46:14 +02006206bool ValidateGetTexParameterIivOES(Context *context,
6207 TextureType target,
6208 GLenum pname,
6209 GLint *params)
6210{
6211 if (context->getClientMajorVersion() < 3)
6212 {
6213 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6214 return false;
6215 }
6216 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6217}
6218
6219bool ValidateGetTexParameterIuivOES(Context *context,
6220 TextureType target,
6221 GLenum pname,
6222 GLuint *params)
6223{
6224 if (context->getClientMajorVersion() < 3)
6225 {
6226 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6227 return false;
6228 }
6229 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6230}
6231
Jamie Madillbe849e42017-05-02 15:49:00 -04006232bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6233{
6234 return ValidateGetUniformBase(context, program, location);
6235}
6236
6237bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6238{
6239 return ValidateGetUniformBase(context, program, location);
6240}
6241
6242bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6243{
6244 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6245}
6246
6247bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6248{
6249 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6250}
6251
6252bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6253{
6254 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6255}
6256
6257bool ValidateIsEnabled(Context *context, GLenum cap)
6258{
6259 if (!ValidCap(context, cap, true))
6260 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006261 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006262 return false;
6263 }
6264
6265 return true;
6266}
6267
6268bool ValidateLinkProgram(Context *context, GLuint program)
6269{
6270 if (context->hasActiveTransformFeedback(program))
6271 {
6272 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006273 context->handleError(InvalidOperation() << "Cannot link program while program is "
6274 "associated with an active transform "
6275 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006276 return false;
6277 }
6278
6279 Program *programObject = GetValidProgram(context, program);
6280 if (!programObject)
6281 {
6282 return false;
6283 }
6284
6285 return true;
6286}
6287
Jamie Madill4928b7c2017-06-20 12:57:39 -04006288bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006289 GLint x,
6290 GLint y,
6291 GLsizei width,
6292 GLsizei height,
6293 GLenum format,
6294 GLenum type,
6295 void *pixels)
6296{
6297 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6298 nullptr, pixels);
6299}
6300
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006301bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006302{
Till Rathmannb8543632018-10-02 19:46:14 +02006303 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006304}
6305
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006306bool ValidateTexParameterfv(Context *context,
6307 TextureType target,
6308 GLenum pname,
6309 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006310{
Till Rathmannb8543632018-10-02 19:46:14 +02006311 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006312}
6313
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006314bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006315{
Till Rathmannb8543632018-10-02 19:46:14 +02006316 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006317}
6318
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006319bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006320{
Till Rathmannb8543632018-10-02 19:46:14 +02006321 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6322}
6323
6324bool ValidateTexParameterIivOES(Context *context,
6325 TextureType target,
6326 GLenum pname,
6327 const GLint *params)
6328{
6329 if (context->getClientMajorVersion() < 3)
6330 {
6331 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6332 return false;
6333 }
6334 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6335}
6336
6337bool ValidateTexParameterIuivOES(Context *context,
6338 TextureType target,
6339 GLenum pname,
6340 const GLuint *params)
6341{
6342 if (context->getClientMajorVersion() < 3)
6343 {
6344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6345 return false;
6346 }
6347 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006348}
6349
6350bool ValidateUseProgram(Context *context, GLuint program)
6351{
6352 if (program != 0)
6353 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006354 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006355 if (!programObject)
6356 {
6357 // ES 3.1.0 section 7.3 page 72
6358 if (context->getShader(program))
6359 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006360 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006361 return false;
6362 }
6363 else
6364 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006365 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006366 return false;
6367 }
6368 }
6369 if (!programObject->isLinked())
6370 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006371 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006372 return false;
6373 }
6374 }
6375 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6376 {
6377 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006378 context
6379 ->handleError(InvalidOperation()
6380 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006381 return false;
6382 }
6383
6384 return true;
6385}
6386
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006387bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6388{
6389 if (!context->getExtensions().fence)
6390 {
6391 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6392 return false;
6393 }
6394
6395 if (n < 0)
6396 {
6397 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6398 return false;
6399 }
6400
6401 return true;
6402}
6403
6404bool ValidateFinishFenceNV(Context *context, GLuint fence)
6405{
6406 if (!context->getExtensions().fence)
6407 {
6408 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6409 return false;
6410 }
6411
6412 FenceNV *fenceObject = context->getFenceNV(fence);
6413
6414 if (fenceObject == nullptr)
6415 {
6416 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6417 return false;
6418 }
6419
6420 if (!fenceObject->isSet())
6421 {
6422 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6423 return false;
6424 }
6425
6426 return true;
6427}
6428
6429bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6430{
6431 if (!context->getExtensions().fence)
6432 {
6433 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6434 return false;
6435 }
6436
6437 if (n < 0)
6438 {
6439 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6440 return false;
6441 }
6442
6443 return true;
6444}
6445
6446bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6447{
6448 if (!context->getExtensions().fence)
6449 {
6450 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6451 return false;
6452 }
6453
6454 FenceNV *fenceObject = context->getFenceNV(fence);
6455
6456 if (fenceObject == nullptr)
6457 {
6458 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6459 return false;
6460 }
6461
6462 if (!fenceObject->isSet())
6463 {
6464 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6465 return false;
6466 }
6467
6468 switch (pname)
6469 {
6470 case GL_FENCE_STATUS_NV:
6471 case GL_FENCE_CONDITION_NV:
6472 break;
6473
6474 default:
6475 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6476 return false;
6477 }
6478
6479 return true;
6480}
6481
6482bool ValidateGetGraphicsResetStatusEXT(Context *context)
6483{
6484 if (!context->getExtensions().robustness)
6485 {
6486 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6487 return false;
6488 }
6489
6490 return true;
6491}
6492
6493bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6494 GLuint shader,
6495 GLsizei bufsize,
6496 GLsizei *length,
6497 GLchar *source)
6498{
6499 if (!context->getExtensions().translatedShaderSource)
6500 {
6501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6502 return false;
6503 }
6504
6505 if (bufsize < 0)
6506 {
6507 context->handleError(InvalidValue());
6508 return false;
6509 }
6510
6511 Shader *shaderObject = context->getShader(shader);
6512
6513 if (!shaderObject)
6514 {
6515 context->handleError(InvalidOperation());
6516 return false;
6517 }
6518
6519 return true;
6520}
6521
6522bool ValidateIsFenceNV(Context *context, GLuint fence)
6523{
6524 if (!context->getExtensions().fence)
6525 {
6526 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6527 return false;
6528 }
6529
6530 return true;
6531}
6532
Jamie Madill007530e2017-12-28 14:27:04 -05006533bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6534{
6535 if (!context->getExtensions().fence)
6536 {
6537 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6538 return false;
6539 }
6540
6541 if (condition != GL_ALL_COMPLETED_NV)
6542 {
6543 context->handleError(InvalidEnum());
6544 return false;
6545 }
6546
6547 FenceNV *fenceObject = context->getFenceNV(fence);
6548
6549 if (fenceObject == nullptr)
6550 {
6551 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6552 return false;
6553 }
6554
6555 return true;
6556}
6557
6558bool ValidateTestFenceNV(Context *context, GLuint fence)
6559{
6560 if (!context->getExtensions().fence)
6561 {
6562 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6563 return false;
6564 }
6565
6566 FenceNV *fenceObject = context->getFenceNV(fence);
6567
6568 if (fenceObject == nullptr)
6569 {
6570 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6571 return false;
6572 }
6573
6574 if (fenceObject->isSet() != GL_TRUE)
6575 {
6576 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6577 return false;
6578 }
6579
6580 return true;
6581}
6582
6583bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006584 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006585 GLsizei levels,
6586 GLenum internalformat,
6587 GLsizei width,
6588 GLsizei height)
6589{
6590 if (!context->getExtensions().textureStorage)
6591 {
6592 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6593 return false;
6594 }
6595
6596 if (context->getClientMajorVersion() < 3)
6597 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006598 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006599 height);
6600 }
6601
6602 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006603 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006604 1);
6605}
6606
6607bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6608{
6609 if (!context->getExtensions().instancedArrays)
6610 {
6611 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6612 return false;
6613 }
6614
6615 if (index >= MAX_VERTEX_ATTRIBS)
6616 {
6617 context->handleError(InvalidValue());
6618 return false;
6619 }
6620
6621 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6622 {
6623 if (index == 0 && divisor != 0)
6624 {
6625 const char *errorMessage =
6626 "The current context doesn't support setting a non-zero divisor on the "
6627 "attribute with index zero. "
6628 "Please reorder the attributes in your vertex shader so that attribute zero "
6629 "can have a zero divisor.";
6630 context->handleError(InvalidOperation() << errorMessage);
6631
6632 // We also output an error message to the debugger window if tracing is active, so
6633 // that developers can see the error message.
6634 ERR() << errorMessage;
6635 return false;
6636 }
6637 }
6638
6639 return true;
6640}
6641
6642bool ValidateTexImage3DOES(Context *context,
6643 GLenum target,
6644 GLint level,
6645 GLenum internalformat,
6646 GLsizei width,
6647 GLsizei height,
6648 GLsizei depth,
6649 GLint border,
6650 GLenum format,
6651 GLenum type,
6652 const void *pixels)
6653{
6654 UNIMPLEMENTED(); // FIXME
6655 return false;
6656}
6657
6658bool ValidatePopGroupMarkerEXT(Context *context)
6659{
6660 if (!context->getExtensions().debugMarker)
6661 {
6662 // The debug marker calls should not set error state
6663 // However, it seems reasonable to set an error state if the extension is not enabled
6664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6665 return false;
6666 }
6667
6668 return true;
6669}
6670
Jamie Madillfa920eb2018-01-04 11:45:50 -05006671bool ValidateTexStorage1DEXT(Context *context,
6672 GLenum target,
6673 GLsizei levels,
6674 GLenum internalformat,
6675 GLsizei width)
6676{
6677 UNIMPLEMENTED();
6678 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6679 return false;
6680}
6681
6682bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006683 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006684 GLsizei levels,
6685 GLenum internalformat,
6686 GLsizei width,
6687 GLsizei height,
6688 GLsizei depth)
6689{
6690 if (!context->getExtensions().textureStorage)
6691 {
6692 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6693 return false;
6694 }
6695
6696 if (context->getClientMajorVersion() < 3)
6697 {
6698 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6699 return false;
6700 }
6701
6702 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6703 depth);
6704}
6705
jchen1082af6202018-06-22 10:59:52 +08006706bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6707{
6708 if (!context->getExtensions().parallelShaderCompile)
6709 {
6710 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6711 return false;
6712 }
6713 return true;
6714}
6715
Jamie Madillc29968b2016-01-20 11:17:23 -05006716} // namespace gl