blob: cef4d2644f86aea9d8ac50fa22d4760b8110cf8e [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 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 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 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madill5b772312018-03-08 20:28:32 -0500458bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700795 // GLES1 emulation: GLES1-specific caps
796 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700797 case GL_VERTEX_ARRAY:
798 case GL_NORMAL_ARRAY:
799 case GL_COLOR_ARRAY:
800 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700801 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700802 case GL_LIGHTING:
803 case GL_LIGHT0:
804 case GL_LIGHT1:
805 case GL_LIGHT2:
806 case GL_LIGHT3:
807 case GL_LIGHT4:
808 case GL_LIGHT5:
809 case GL_LIGHT6:
810 case GL_LIGHT7:
811 case GL_NORMALIZE:
812 case GL_RESCALE_NORMAL:
813 case GL_COLOR_MATERIAL:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700814 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700815 case GL_POINT_SIZE_ARRAY_OES:
816 return context->getClientVersion() < Version(2, 0) &&
817 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700818 case GL_TEXTURE_CUBE_MAP:
819 return context->getClientVersion() < Version(2, 0) &&
820 context->getExtensions().textureCubeMap;
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700821
Jamie Madillbe849e42017-05-02 15:49:00 -0400822 default:
823 return false;
824 }
825}
826
Geoff Langfc32e8b2017-05-31 14:16:59 -0400827// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
828// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400829bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400830{
831 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400832 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
833 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400834 {
835 return true;
836 }
837
838 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
839 if (c >= 9 && c <= 13)
840 {
841 return true;
842 }
843
844 return false;
845}
846
Geoff Langcab92ee2017-07-19 17:32:07 -0400847bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400848{
Geoff Langa71a98e2017-06-19 15:15:00 -0400849 for (size_t i = 0; i < len; i++)
850 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400851 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400852 {
853 return false;
854 }
855 }
856
857 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400858}
859
Geoff Langcab92ee2017-07-19 17:32:07 -0400860bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
861{
862 enum class ParseState
863 {
864 // Have not seen an ASCII non-whitespace character yet on
865 // this line. Possible that we might see a preprocessor
866 // directive.
867 BEGINING_OF_LINE,
868
869 // Have seen at least one ASCII non-whitespace character
870 // on this line.
871 MIDDLE_OF_LINE,
872
873 // Handling a preprocessor directive. Passes through all
874 // characters up to the end of the line. Disables comment
875 // processing.
876 IN_PREPROCESSOR_DIRECTIVE,
877
878 // Handling a single-line comment. The comment text is
879 // replaced with a single space.
880 IN_SINGLE_LINE_COMMENT,
881
882 // Handling a multi-line comment. Newlines are passed
883 // through to preserve line numbers.
884 IN_MULTI_LINE_COMMENT
885 };
886
887 ParseState state = ParseState::BEGINING_OF_LINE;
888 size_t pos = 0;
889
890 while (pos < len)
891 {
892 char c = str[pos];
893 char next = pos + 1 < len ? str[pos + 1] : 0;
894
895 // Check for newlines
896 if (c == '\n' || c == '\r')
897 {
898 if (state != ParseState::IN_MULTI_LINE_COMMENT)
899 {
900 state = ParseState::BEGINING_OF_LINE;
901 }
902
903 pos++;
904 continue;
905 }
906
907 switch (state)
908 {
909 case ParseState::BEGINING_OF_LINE:
910 if (c == ' ')
911 {
912 // Maintain the BEGINING_OF_LINE state until a non-space is seen
913 pos++;
914 }
915 else if (c == '#')
916 {
917 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
918 pos++;
919 }
920 else
921 {
922 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
923 state = ParseState::MIDDLE_OF_LINE;
924 }
925 break;
926
927 case ParseState::MIDDLE_OF_LINE:
928 if (c == '/' && next == '/')
929 {
930 state = ParseState::IN_SINGLE_LINE_COMMENT;
931 pos++;
932 }
933 else if (c == '/' && next == '*')
934 {
935 state = ParseState::IN_MULTI_LINE_COMMENT;
936 pos++;
937 }
938 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
939 {
940 // Skip line continuation characters
941 }
942 else if (!IsValidESSLCharacter(c))
943 {
944 return false;
945 }
946 pos++;
947 break;
948
949 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700950 // Line-continuation characters may not be permitted.
951 // Otherwise, just pass it through. Do not parse comments in this state.
952 if (!lineContinuationAllowed && c == '\\')
953 {
954 return false;
955 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400956 pos++;
957 break;
958
959 case ParseState::IN_SINGLE_LINE_COMMENT:
960 // Line-continuation characters are processed before comment processing.
961 // Advance string if a new line character is immediately behind
962 // line-continuation character.
963 if (c == '\\' && (next == '\n' || next == '\r'))
964 {
965 pos++;
966 }
967 pos++;
968 break;
969
970 case ParseState::IN_MULTI_LINE_COMMENT:
971 if (c == '*' && next == '/')
972 {
973 state = ParseState::MIDDLE_OF_LINE;
974 pos++;
975 }
976 pos++;
977 break;
978 }
979 }
980
981 return true;
982}
983
Jamie Madill5b772312018-03-08 20:28:32 -0500984bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700985{
986 ASSERT(context->isWebGL());
987
988 // WebGL 1.0 [Section 6.16] GLSL Constructs
989 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
990 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
991 {
992 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
993 return false;
994 }
995
996 return true;
997}
998
Jamie Madill5b772312018-03-08 20:28:32 -0500999bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001000{
1001 ASSERT(context->isWebGL());
1002
1003 if (context->isWebGL1() && length > 256)
1004 {
1005 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1006 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1007 // locations.
1008 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1009
1010 return false;
1011 }
1012 else if (length > 1024)
1013 {
1014 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1015 // uniform and attribute locations.
1016 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1017 return false;
1018 }
1019
1020 return true;
1021}
1022
Jamie Madill007530e2017-12-28 14:27:04 -05001023bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1024{
1025 if (!context->getExtensions().pathRendering)
1026 {
1027 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1028 return false;
1029 }
1030
1031 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1032 {
1033 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1034 return false;
1035 }
1036 return true;
1037}
Jamie Madillc29968b2016-01-20 11:17:23 -05001038} // anonymous namespace
1039
Geoff Langff5b2d52016-09-07 11:32:23 -04001040bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001041 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001042 GLint level,
1043 GLenum internalformat,
1044 bool isCompressed,
1045 bool isSubImage,
1046 GLint xoffset,
1047 GLint yoffset,
1048 GLsizei width,
1049 GLsizei height,
1050 GLint border,
1051 GLenum format,
1052 GLenum type,
1053 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001054 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001055{
Jamie Madill6f38f822014-06-06 17:12:20 -04001056 if (!ValidTexture2DDestinationTarget(context, target))
1057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001058 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001059 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001060 }
1061
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001062 TextureType texType = TextureTargetToType(target);
1063 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001065 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001066 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001067 }
1068
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001069 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001070 {
1071 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1072 return false;
1073 }
1074
1075 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001076 std::numeric_limits<GLsizei>::max() - yoffset < height)
1077 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001078 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001079 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001080 }
1081
Geoff Lang6e898aa2017-06-02 11:17:26 -04001082 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1083 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1084 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1085 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1086 // case.
1087 bool nonEqualFormatsAllowed =
1088 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1089 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1090
1091 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001092 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001093 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001094 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001095 }
1096
Geoff Langaae65a42014-05-26 12:43:44 -04001097 const gl::Caps &caps = context->getCaps();
1098
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001099 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001100 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001101 case TextureType::_2D:
1102 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1103 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1104 {
1105 context->handleError(InvalidValue());
1106 return false;
1107 }
1108 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001109
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001110 case TextureType::Rectangle:
1111 ASSERT(level == 0);
1112 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1113 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1114 {
1115 context->handleError(InvalidValue());
1116 return false;
1117 }
1118 if (isCompressed)
1119 {
1120 context->handleError(InvalidEnum()
1121 << "Rectangle texture cannot have a compressed format.");
1122 return false;
1123 }
1124 break;
1125
1126 case TextureType::CubeMap:
1127 if (!isSubImage && width != height)
1128 {
1129 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1130 return false;
1131 }
1132
1133 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1134 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1135 {
1136 context->handleError(InvalidValue());
1137 return false;
1138 }
1139 break;
1140
1141 default:
1142 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001143 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001144 }
1145
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001146 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001147 if (!texture)
1148 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001149 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001150 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001151 }
1152
Geoff Langa9be0dc2014-12-17 12:34:40 -05001153 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001154 {
Geoff Langca271392017-04-05 12:30:00 -04001155 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1156 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001157 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001158 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001159 return false;
1160 }
1161
Geoff Langa9be0dc2014-12-17 12:34:40 -05001162 if (format != GL_NONE)
1163 {
Geoff Langca271392017-04-05 12:30:00 -04001164 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1165 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001166 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001167 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001168 return false;
1169 }
1170 }
1171
1172 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1173 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001175 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001176 return false;
1177 }
Geoff Langfb052642017-10-24 13:42:09 -04001178
1179 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001180 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001181 {
1182 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1183 return false;
1184 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001185 }
1186 else
1187 {
Geoff Lang69cce582015-09-17 13:20:36 -04001188 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001190 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001191 return false;
1192 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001193 }
1194
1195 // Verify zero border
1196 if (border != 0)
1197 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001198 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001199 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001200 }
1201
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001202 if (isCompressed)
1203 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001204 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001205 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1206 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001207
1208 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1209
1210 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001211 {
Geoff Lange88e4542018-05-03 15:05:57 -04001212 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1213 return false;
1214 }
1215
1216 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1217 context->getExtensions()))
1218 {
1219 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1220 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001221 }
Geoff Lang966c9402017-04-18 12:38:27 -04001222
1223 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001224 {
Geoff Lange88e4542018-05-03 15:05:57 -04001225 // From the OES_compressed_ETC1_RGB8_texture spec:
1226 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1227 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1228 // ETC1_RGB8_OES.
1229 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1230 {
1231 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1232 return false;
1233 }
1234
Geoff Lang966c9402017-04-18 12:38:27 -04001235 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1236 height, texture->getWidth(target, level),
1237 texture->getHeight(target, level)))
1238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001239 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001240 return false;
1241 }
1242
1243 if (format != actualInternalFormat)
1244 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001245 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001246 return false;
1247 }
1248 }
1249 else
1250 {
1251 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1252 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001253 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001254 return false;
1255 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001256 }
1257 }
1258 else
1259 {
1260 // validate <type> by itself (used as secondary key below)
1261 switch (type)
1262 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001263 case GL_UNSIGNED_BYTE:
1264 case GL_UNSIGNED_SHORT_5_6_5:
1265 case GL_UNSIGNED_SHORT_4_4_4_4:
1266 case GL_UNSIGNED_SHORT_5_5_5_1:
1267 case GL_UNSIGNED_SHORT:
1268 case GL_UNSIGNED_INT:
1269 case GL_UNSIGNED_INT_24_8_OES:
1270 case GL_HALF_FLOAT_OES:
1271 case GL_FLOAT:
1272 break;
1273 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001274 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001275 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001276 }
1277
1278 // validate <format> + <type> combinations
1279 // - invalid <format> -> sets INVALID_ENUM
1280 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1281 switch (format)
1282 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001283 case GL_ALPHA:
1284 case GL_LUMINANCE:
1285 case GL_LUMINANCE_ALPHA:
1286 switch (type)
1287 {
1288 case GL_UNSIGNED_BYTE:
1289 case GL_FLOAT:
1290 case GL_HALF_FLOAT_OES:
1291 break;
1292 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001293 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001294 return false;
1295 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001296 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001297 case GL_RED:
1298 case GL_RG:
1299 if (!context->getExtensions().textureRG)
1300 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001301 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001302 return false;
1303 }
1304 switch (type)
1305 {
1306 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001307 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001308 case GL_FLOAT:
1309 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001310 if (!context->getExtensions().textureFloat)
1311 {
1312 context->handleError(InvalidEnum());
1313 return false;
1314 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001315 break;
1316 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001317 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001318 return false;
1319 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001320 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001321 case GL_RGB:
1322 switch (type)
1323 {
1324 case GL_UNSIGNED_BYTE:
1325 case GL_UNSIGNED_SHORT_5_6_5:
1326 case GL_FLOAT:
1327 case GL_HALF_FLOAT_OES:
1328 break;
1329 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001330 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001331 return false;
1332 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001333 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001334 case GL_RGBA:
1335 switch (type)
1336 {
1337 case GL_UNSIGNED_BYTE:
1338 case GL_UNSIGNED_SHORT_4_4_4_4:
1339 case GL_UNSIGNED_SHORT_5_5_5_1:
1340 case GL_FLOAT:
1341 case GL_HALF_FLOAT_OES:
1342 break;
1343 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001345 return false;
1346 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001347 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001348 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001349 if (!context->getExtensions().textureFormatBGRA8888)
1350 {
1351 context->handleError(InvalidEnum());
1352 return false;
1353 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001354 switch (type)
1355 {
1356 case GL_UNSIGNED_BYTE:
1357 break;
1358 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001359 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001360 return false;
1361 }
1362 break;
1363 case GL_SRGB_EXT:
1364 case GL_SRGB_ALPHA_EXT:
1365 if (!context->getExtensions().sRGB)
1366 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001367 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001368 return false;
1369 }
1370 switch (type)
1371 {
1372 case GL_UNSIGNED_BYTE:
1373 break;
1374 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001375 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001376 return false;
1377 }
1378 break;
1379 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1380 // handled below
1381 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1382 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1383 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1384 break;
1385 case GL_DEPTH_COMPONENT:
1386 switch (type)
1387 {
1388 case GL_UNSIGNED_SHORT:
1389 case GL_UNSIGNED_INT:
1390 break;
1391 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001392 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001393 return false;
1394 }
1395 break;
1396 case GL_DEPTH_STENCIL_OES:
1397 switch (type)
1398 {
1399 case GL_UNSIGNED_INT_24_8_OES:
1400 break;
1401 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001402 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001403 return false;
1404 }
1405 break;
1406 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001407 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001408 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001409 }
1410
1411 switch (format)
1412 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001413 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1414 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1415 if (context->getExtensions().textureCompressionDXT1)
1416 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001417 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001418 return false;
1419 }
1420 else
1421 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001422 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001423 return false;
1424 }
1425 break;
1426 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1427 if (context->getExtensions().textureCompressionDXT3)
1428 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001429 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001430 return false;
1431 }
1432 else
1433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001434 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001435 return false;
1436 }
1437 break;
1438 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1439 if (context->getExtensions().textureCompressionDXT5)
1440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001441 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001442 return false;
1443 }
1444 else
1445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001446 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001447 return false;
1448 }
1449 break;
1450 case GL_ETC1_RGB8_OES:
1451 if (context->getExtensions().compressedETC1RGB8Texture)
1452 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001453 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001454 return false;
1455 }
1456 else
1457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001458 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001459 return false;
1460 }
1461 break;
1462 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001463 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1464 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1465 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1466 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 if (context->getExtensions().lossyETCDecode)
1468 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001469 context->handleError(InvalidOperation()
1470 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001471 return false;
1472 }
1473 else
1474 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001475 context->handleError(InvalidEnum()
1476 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001477 return false;
1478 }
1479 break;
1480 case GL_DEPTH_COMPONENT:
1481 case GL_DEPTH_STENCIL_OES:
1482 if (!context->getExtensions().depthTextures)
1483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001484 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001485 return false;
1486 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001487 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001488 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001489 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001490 return false;
1491 }
1492 // OES_depth_texture supports loading depth data and multiple levels,
1493 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001494 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001495 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001496 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1497 return false;
1498 }
1499 if (level != 0)
1500 {
1501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001502 return false;
1503 }
1504 break;
1505 default:
1506 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001507 }
1508
Geoff Lang6e898aa2017-06-02 11:17:26 -04001509 if (!isSubImage)
1510 {
1511 switch (internalformat)
1512 {
1513 case GL_RGBA32F:
1514 if (!context->getExtensions().colorBufferFloatRGBA)
1515 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001516 context->handleError(InvalidValue()
1517 << "Sized GL_RGBA32F internal format requires "
1518 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001519 return false;
1520 }
1521 if (type != GL_FLOAT)
1522 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001523 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001524 return false;
1525 }
1526 if (format != GL_RGBA)
1527 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001528 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001529 return false;
1530 }
1531 break;
1532
1533 case GL_RGB32F:
1534 if (!context->getExtensions().colorBufferFloatRGB)
1535 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001536 context->handleError(InvalidValue()
1537 << "Sized GL_RGB32F internal format requires "
1538 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001539 return false;
1540 }
1541 if (type != GL_FLOAT)
1542 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001544 return false;
1545 }
1546 if (format != GL_RGB)
1547 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001548 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001549 return false;
1550 }
1551 break;
1552
1553 default:
1554 break;
1555 }
1556 }
1557
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001558 if (type == GL_FLOAT)
1559 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001560 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001561 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001562 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001563 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001564 }
1565 }
1566 else if (type == GL_HALF_FLOAT_OES)
1567 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001568 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001569 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001570 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001571 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001572 }
1573 }
1574 }
1575
Geoff Langdbcced82017-06-06 15:55:54 -04001576 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001577 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001578 imageSize))
1579 {
1580 return false;
1581 }
1582
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001583 return true;
1584}
1585
He Yunchaoced53ae2016-11-29 15:00:51 +08001586bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001587 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001588 GLsizei levels,
1589 GLenum internalformat,
1590 GLsizei width,
1591 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001592{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001593 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1594 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001595 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001596 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001597 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001598 }
1599
1600 if (width < 1 || height < 1 || levels < 1)
1601 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001602 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001603 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001604 }
1605
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001606 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001607 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001608 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001609 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001610 }
1611
1612 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1613 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001614 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001615 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001616 }
1617
Geoff Langca271392017-04-05 12:30:00 -04001618 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001619 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001620 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001621 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001622 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001623 }
1624
Geoff Langaae65a42014-05-26 12:43:44 -04001625 const gl::Caps &caps = context->getCaps();
1626
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001627 switch (target)
1628 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001629 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001630 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1631 static_cast<GLuint>(height) > caps.max2DTextureSize)
1632 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001633 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001634 return false;
1635 }
1636 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001637 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001638 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1639 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1640 {
1641 context->handleError(InvalidValue());
1642 return false;
1643 }
1644 if (formatInfo.compressed)
1645 {
1646 context->handleError(InvalidEnum()
1647 << "Rectangle texture cannot have a compressed format.");
1648 return false;
1649 }
1650 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001651 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001652 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1653 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1654 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001655 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001656 return false;
1657 }
1658 break;
1659 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001660 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001661 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001662 }
1663
Geoff Langc0b9ef42014-07-02 10:02:37 -04001664 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001665 {
1666 if (!gl::isPow2(width) || !gl::isPow2(height))
1667 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001668 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001669 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001670 }
1671 }
1672
1673 switch (internalformat)
1674 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001675 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1676 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1677 if (!context->getExtensions().textureCompressionDXT1)
1678 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001679 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001680 return false;
1681 }
1682 break;
1683 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1684 if (!context->getExtensions().textureCompressionDXT3)
1685 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001686 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001687 return false;
1688 }
1689 break;
1690 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1691 if (!context->getExtensions().textureCompressionDXT5)
1692 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001693 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001694 return false;
1695 }
1696 break;
1697 case GL_ETC1_RGB8_OES:
1698 if (!context->getExtensions().compressedETC1RGB8Texture)
1699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001700 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001701 return false;
1702 }
1703 break;
1704 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001705 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1706 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1707 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1708 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001709 if (!context->getExtensions().lossyETCDecode)
1710 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001711 context->handleError(InvalidEnum()
1712 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001713 return false;
1714 }
1715 break;
1716 case GL_RGBA32F_EXT:
1717 case GL_RGB32F_EXT:
1718 case GL_ALPHA32F_EXT:
1719 case GL_LUMINANCE32F_EXT:
1720 case GL_LUMINANCE_ALPHA32F_EXT:
1721 if (!context->getExtensions().textureFloat)
1722 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001723 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001724 return false;
1725 }
1726 break;
1727 case GL_RGBA16F_EXT:
1728 case GL_RGB16F_EXT:
1729 case GL_ALPHA16F_EXT:
1730 case GL_LUMINANCE16F_EXT:
1731 case GL_LUMINANCE_ALPHA16F_EXT:
1732 if (!context->getExtensions().textureHalfFloat)
1733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001734 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001735 return false;
1736 }
1737 break;
1738 case GL_R8_EXT:
1739 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001740 if (!context->getExtensions().textureRG)
1741 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001742 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001743 return false;
1744 }
1745 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001746 case GL_R16F_EXT:
1747 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001748 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1749 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001750 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001751 return false;
1752 }
1753 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001754 case GL_R32F_EXT:
1755 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001756 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001757 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001758 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001759 return false;
1760 }
1761 break;
1762 case GL_DEPTH_COMPONENT16:
1763 case GL_DEPTH_COMPONENT32_OES:
1764 case GL_DEPTH24_STENCIL8_OES:
1765 if (!context->getExtensions().depthTextures)
1766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001767 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001768 return false;
1769 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001770 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001771 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001772 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001773 return false;
1774 }
1775 // ANGLE_depth_texture only supports 1-level textures
1776 if (levels != 1)
1777 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001778 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001779 return false;
1780 }
1781 break;
1782 default:
1783 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001784 }
1785
Geoff Lang691e58c2014-12-19 17:03:25 -05001786 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001787 if (!texture || texture->id() == 0)
1788 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001789 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001790 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001791 }
1792
Geoff Lang69cce582015-09-17 13:20:36 -04001793 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001794 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001795 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001796 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001797 }
1798
1799 return true;
1800}
1801
He Yunchaoced53ae2016-11-29 15:00:51 +08001802bool ValidateDiscardFramebufferEXT(Context *context,
1803 GLenum target,
1804 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001805 const GLenum *attachments)
1806{
Jamie Madillc29968b2016-01-20 11:17:23 -05001807 if (!context->getExtensions().discardFramebuffer)
1808 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001809 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001810 return false;
1811 }
1812
Austin Kinross08332632015-05-05 13:35:47 -07001813 bool defaultFramebuffer = false;
1814
1815 switch (target)
1816 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001817 case GL_FRAMEBUFFER:
1818 defaultFramebuffer =
1819 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1820 break;
1821 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001822 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001823 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001824 }
1825
He Yunchaoced53ae2016-11-29 15:00:51 +08001826 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1827 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001828}
1829
Austin Kinrossbc781f32015-10-26 09:27:38 -07001830bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1831{
1832 if (!context->getExtensions().vertexArrayObject)
1833 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001834 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001835 return false;
1836 }
1837
1838 return ValidateBindVertexArrayBase(context, array);
1839}
1840
Jamie Madilld7576732017-08-26 18:49:50 -04001841bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001842{
1843 if (!context->getExtensions().vertexArrayObject)
1844 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001845 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001846 return false;
1847 }
1848
Olli Etuaho41997e72016-03-10 13:38:39 +02001849 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001850}
1851
Jamie Madilld7576732017-08-26 18:49:50 -04001852bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001853{
1854 if (!context->getExtensions().vertexArrayObject)
1855 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001856 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001857 return false;
1858 }
1859
Olli Etuaho41997e72016-03-10 13:38:39 +02001860 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001861}
1862
Jamie Madilld7576732017-08-26 18:49:50 -04001863bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001864{
1865 if (!context->getExtensions().vertexArrayObject)
1866 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001867 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001868 return false;
1869 }
1870
1871 return true;
1872}
Geoff Langc5629752015-12-07 16:29:04 -05001873
1874bool ValidateProgramBinaryOES(Context *context,
1875 GLuint program,
1876 GLenum binaryFormat,
1877 const void *binary,
1878 GLint length)
1879{
1880 if (!context->getExtensions().getProgramBinary)
1881 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001882 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001883 return false;
1884 }
1885
1886 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1887}
1888
1889bool ValidateGetProgramBinaryOES(Context *context,
1890 GLuint program,
1891 GLsizei bufSize,
1892 GLsizei *length,
1893 GLenum *binaryFormat,
1894 void *binary)
1895{
1896 if (!context->getExtensions().getProgramBinary)
1897 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001898 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001899 return false;
1900 }
1901
1902 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1903}
Geoff Lange102fee2015-12-10 11:23:30 -05001904
Geoff Lang70d0f492015-12-10 17:45:46 -05001905static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1906{
1907 switch (source)
1908 {
1909 case GL_DEBUG_SOURCE_API:
1910 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1911 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1912 case GL_DEBUG_SOURCE_OTHER:
1913 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1914 return !mustBeThirdPartyOrApplication;
1915
1916 case GL_DEBUG_SOURCE_THIRD_PARTY:
1917 case GL_DEBUG_SOURCE_APPLICATION:
1918 return true;
1919
1920 default:
1921 return false;
1922 }
1923}
1924
1925static bool ValidDebugType(GLenum type)
1926{
1927 switch (type)
1928 {
1929 case GL_DEBUG_TYPE_ERROR:
1930 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1931 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1932 case GL_DEBUG_TYPE_PERFORMANCE:
1933 case GL_DEBUG_TYPE_PORTABILITY:
1934 case GL_DEBUG_TYPE_OTHER:
1935 case GL_DEBUG_TYPE_MARKER:
1936 case GL_DEBUG_TYPE_PUSH_GROUP:
1937 case GL_DEBUG_TYPE_POP_GROUP:
1938 return true;
1939
1940 default:
1941 return false;
1942 }
1943}
1944
1945static bool ValidDebugSeverity(GLenum severity)
1946{
1947 switch (severity)
1948 {
1949 case GL_DEBUG_SEVERITY_HIGH:
1950 case GL_DEBUG_SEVERITY_MEDIUM:
1951 case GL_DEBUG_SEVERITY_LOW:
1952 case GL_DEBUG_SEVERITY_NOTIFICATION:
1953 return true;
1954
1955 default:
1956 return false;
1957 }
1958}
1959
Geoff Lange102fee2015-12-10 11:23:30 -05001960bool ValidateDebugMessageControlKHR(Context *context,
1961 GLenum source,
1962 GLenum type,
1963 GLenum severity,
1964 GLsizei count,
1965 const GLuint *ids,
1966 GLboolean enabled)
1967{
1968 if (!context->getExtensions().debug)
1969 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001970 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001971 return false;
1972 }
1973
Geoff Lang70d0f492015-12-10 17:45:46 -05001974 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1975 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001976 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001977 return false;
1978 }
1979
1980 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1981 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001982 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001983 return false;
1984 }
1985
1986 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1987 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001988 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001989 return false;
1990 }
1991
1992 if (count > 0)
1993 {
1994 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1995 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001996 context->handleError(
1997 InvalidOperation()
1998 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05001999 return false;
2000 }
2001
2002 if (severity != GL_DONT_CARE)
2003 {
Jamie Madill437fa652016-05-03 15:13:24 -04002004 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002005 InvalidOperation()
2006 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002007 return false;
2008 }
2009 }
2010
Geoff Lange102fee2015-12-10 11:23:30 -05002011 return true;
2012}
2013
2014bool ValidateDebugMessageInsertKHR(Context *context,
2015 GLenum source,
2016 GLenum type,
2017 GLuint id,
2018 GLenum severity,
2019 GLsizei length,
2020 const GLchar *buf)
2021{
2022 if (!context->getExtensions().debug)
2023 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002024 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002025 return false;
2026 }
2027
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002028 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002029 {
2030 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2031 // not generate an error.
2032 return false;
2033 }
2034
2035 if (!ValidDebugSeverity(severity))
2036 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002037 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002038 return false;
2039 }
2040
2041 if (!ValidDebugType(type))
2042 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002043 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002044 return false;
2045 }
2046
2047 if (!ValidDebugSource(source, true))
2048 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002049 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002050 return false;
2051 }
2052
2053 size_t messageLength = (length < 0) ? strlen(buf) : length;
2054 if (messageLength > context->getExtensions().maxDebugMessageLength)
2055 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002056 context->handleError(InvalidValue()
2057 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002058 return false;
2059 }
2060
Geoff Lange102fee2015-12-10 11:23:30 -05002061 return true;
2062}
2063
2064bool ValidateDebugMessageCallbackKHR(Context *context,
2065 GLDEBUGPROCKHR callback,
2066 const void *userParam)
2067{
2068 if (!context->getExtensions().debug)
2069 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002070 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002071 return false;
2072 }
2073
Geoff Lange102fee2015-12-10 11:23:30 -05002074 return true;
2075}
2076
2077bool ValidateGetDebugMessageLogKHR(Context *context,
2078 GLuint count,
2079 GLsizei bufSize,
2080 GLenum *sources,
2081 GLenum *types,
2082 GLuint *ids,
2083 GLenum *severities,
2084 GLsizei *lengths,
2085 GLchar *messageLog)
2086{
2087 if (!context->getExtensions().debug)
2088 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002089 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002090 return false;
2091 }
2092
Geoff Lang70d0f492015-12-10 17:45:46 -05002093 if (bufSize < 0 && messageLog != nullptr)
2094 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002095 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002096 return false;
2097 }
2098
Geoff Lange102fee2015-12-10 11:23:30 -05002099 return true;
2100}
2101
2102bool ValidatePushDebugGroupKHR(Context *context,
2103 GLenum source,
2104 GLuint id,
2105 GLsizei length,
2106 const GLchar *message)
2107{
2108 if (!context->getExtensions().debug)
2109 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002110 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002111 return false;
2112 }
2113
Geoff Lang70d0f492015-12-10 17:45:46 -05002114 if (!ValidDebugSource(source, true))
2115 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002116 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002117 return false;
2118 }
2119
2120 size_t messageLength = (length < 0) ? strlen(message) : length;
2121 if (messageLength > context->getExtensions().maxDebugMessageLength)
2122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002123 context->handleError(InvalidValue()
2124 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002125 return false;
2126 }
2127
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002128 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002129 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002131 context
2132 ->handleError(StackOverflow()
2133 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002134 return false;
2135 }
2136
Geoff Lange102fee2015-12-10 11:23:30 -05002137 return true;
2138}
2139
2140bool ValidatePopDebugGroupKHR(Context *context)
2141{
2142 if (!context->getExtensions().debug)
2143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002145 return false;
2146 }
2147
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002148 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002149 if (currentStackSize <= 1)
2150 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002151 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002152 return false;
2153 }
2154
2155 return true;
2156}
2157
2158static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2159{
2160 switch (identifier)
2161 {
2162 case GL_BUFFER:
2163 if (context->getBuffer(name) == nullptr)
2164 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002165 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002166 return false;
2167 }
2168 return true;
2169
2170 case GL_SHADER:
2171 if (context->getShader(name) == nullptr)
2172 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002173 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002174 return false;
2175 }
2176 return true;
2177
2178 case GL_PROGRAM:
2179 if (context->getProgram(name) == nullptr)
2180 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002181 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002182 return false;
2183 }
2184 return true;
2185
2186 case GL_VERTEX_ARRAY:
2187 if (context->getVertexArray(name) == nullptr)
2188 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002189 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002190 return false;
2191 }
2192 return true;
2193
2194 case GL_QUERY:
2195 if (context->getQuery(name) == nullptr)
2196 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002197 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002198 return false;
2199 }
2200 return true;
2201
2202 case GL_TRANSFORM_FEEDBACK:
2203 if (context->getTransformFeedback(name) == nullptr)
2204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002205 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002206 return false;
2207 }
2208 return true;
2209
2210 case GL_SAMPLER:
2211 if (context->getSampler(name) == nullptr)
2212 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002213 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002214 return false;
2215 }
2216 return true;
2217
2218 case GL_TEXTURE:
2219 if (context->getTexture(name) == nullptr)
2220 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002221 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002222 return false;
2223 }
2224 return true;
2225
2226 case GL_RENDERBUFFER:
2227 if (context->getRenderbuffer(name) == nullptr)
2228 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002229 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002230 return false;
2231 }
2232 return true;
2233
2234 case GL_FRAMEBUFFER:
2235 if (context->getFramebuffer(name) == nullptr)
2236 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002237 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002238 return false;
2239 }
2240 return true;
2241
2242 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002243 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002244 return false;
2245 }
Geoff Lange102fee2015-12-10 11:23:30 -05002246}
2247
Martin Radev9d901792016-07-15 15:58:58 +03002248static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2249{
2250 size_t labelLength = 0;
2251
2252 if (length < 0)
2253 {
2254 if (label != nullptr)
2255 {
2256 labelLength = strlen(label);
2257 }
2258 }
2259 else
2260 {
2261 labelLength = static_cast<size_t>(length);
2262 }
2263
2264 if (labelLength > context->getExtensions().maxLabelLength)
2265 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002266 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002267 return false;
2268 }
2269
2270 return true;
2271}
2272
Geoff Lange102fee2015-12-10 11:23:30 -05002273bool ValidateObjectLabelKHR(Context *context,
2274 GLenum identifier,
2275 GLuint name,
2276 GLsizei length,
2277 const GLchar *label)
2278{
2279 if (!context->getExtensions().debug)
2280 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002281 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002282 return false;
2283 }
2284
Geoff Lang70d0f492015-12-10 17:45:46 -05002285 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2286 {
2287 return false;
2288 }
2289
Martin Radev9d901792016-07-15 15:58:58 +03002290 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002291 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002292 return false;
2293 }
2294
Geoff Lange102fee2015-12-10 11:23:30 -05002295 return true;
2296}
2297
2298bool ValidateGetObjectLabelKHR(Context *context,
2299 GLenum identifier,
2300 GLuint name,
2301 GLsizei bufSize,
2302 GLsizei *length,
2303 GLchar *label)
2304{
2305 if (!context->getExtensions().debug)
2306 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002307 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002308 return false;
2309 }
2310
Geoff Lang70d0f492015-12-10 17:45:46 -05002311 if (bufSize < 0)
2312 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002313 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002314 return false;
2315 }
2316
2317 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2318 {
2319 return false;
2320 }
2321
Martin Radev9d901792016-07-15 15:58:58 +03002322 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002323}
2324
2325static bool ValidateObjectPtrName(Context *context, const void *ptr)
2326{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002327 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002328 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002329 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002330 return false;
2331 }
2332
Geoff Lange102fee2015-12-10 11:23:30 -05002333 return true;
2334}
2335
2336bool ValidateObjectPtrLabelKHR(Context *context,
2337 const void *ptr,
2338 GLsizei length,
2339 const GLchar *label)
2340{
2341 if (!context->getExtensions().debug)
2342 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002343 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002344 return false;
2345 }
2346
Geoff Lang70d0f492015-12-10 17:45:46 -05002347 if (!ValidateObjectPtrName(context, ptr))
2348 {
2349 return false;
2350 }
2351
Martin Radev9d901792016-07-15 15:58:58 +03002352 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002353 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002354 return false;
2355 }
2356
Geoff Lange102fee2015-12-10 11:23:30 -05002357 return true;
2358}
2359
2360bool ValidateGetObjectPtrLabelKHR(Context *context,
2361 const void *ptr,
2362 GLsizei bufSize,
2363 GLsizei *length,
2364 GLchar *label)
2365{
2366 if (!context->getExtensions().debug)
2367 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002369 return false;
2370 }
2371
Geoff Lang70d0f492015-12-10 17:45:46 -05002372 if (bufSize < 0)
2373 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002374 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002375 return false;
2376 }
2377
2378 if (!ValidateObjectPtrName(context, ptr))
2379 {
2380 return false;
2381 }
2382
Martin Radev9d901792016-07-15 15:58:58 +03002383 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002384}
2385
2386bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2387{
2388 if (!context->getExtensions().debug)
2389 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002390 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002391 return false;
2392 }
2393
Geoff Lang70d0f492015-12-10 17:45:46 -05002394 // TODO: represent this in Context::getQueryParameterInfo.
2395 switch (pname)
2396 {
2397 case GL_DEBUG_CALLBACK_FUNCTION:
2398 case GL_DEBUG_CALLBACK_USER_PARAM:
2399 break;
2400
2401 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002402 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002403 return false;
2404 }
2405
Geoff Lange102fee2015-12-10 11:23:30 -05002406 return true;
2407}
Jamie Madillc29968b2016-01-20 11:17:23 -05002408
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002409bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2410 GLenum pname,
2411 GLsizei bufSize,
2412 GLsizei *length,
2413 void **params)
2414{
2415 UNIMPLEMENTED();
2416 return false;
2417}
2418
Jamie Madillc29968b2016-01-20 11:17:23 -05002419bool ValidateBlitFramebufferANGLE(Context *context,
2420 GLint srcX0,
2421 GLint srcY0,
2422 GLint srcX1,
2423 GLint srcY1,
2424 GLint dstX0,
2425 GLint dstY0,
2426 GLint dstX1,
2427 GLint dstY1,
2428 GLbitfield mask,
2429 GLenum filter)
2430{
2431 if (!context->getExtensions().framebufferBlit)
2432 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002433 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002434 return false;
2435 }
2436
2437 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2438 {
2439 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002440 context->handleError(InvalidOperation() << "Scaling and flipping in "
2441 "BlitFramebufferANGLE not supported by this "
2442 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002443 return false;
2444 }
2445
2446 if (filter == GL_LINEAR)
2447 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002448 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002449 return false;
2450 }
2451
Jamie Madill51f40ec2016-06-15 14:06:00 -04002452 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2453 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002454
2455 if (mask & GL_COLOR_BUFFER_BIT)
2456 {
2457 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2458 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2459
2460 if (readColorAttachment && drawColorAttachment)
2461 {
2462 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002463 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002464 readColorAttachment->type() != GL_RENDERBUFFER &&
2465 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2466 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002467 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002468 return false;
2469 }
2470
Geoff Langa15472a2015-08-11 11:48:03 -04002471 for (size_t drawbufferIdx = 0;
2472 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002473 {
Geoff Langa15472a2015-08-11 11:48:03 -04002474 const FramebufferAttachment *attachment =
2475 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2476 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002477 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002478 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002479 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002480 attachment->type() != GL_RENDERBUFFER &&
2481 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2482 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002483 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002484 return false;
2485 }
2486
2487 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002488 if (!Format::EquivalentForBlit(attachment->getFormat(),
2489 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002490 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002491 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002492 return false;
2493 }
2494 }
2495 }
2496
Jamie Madill427064d2018-04-13 16:20:34 -04002497 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002498 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002499 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2500 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2501 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002502 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002503 return false;
2504 }
2505 }
2506 }
2507
2508 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2509 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2510 for (size_t i = 0; i < 2; i++)
2511 {
2512 if (mask & masks[i])
2513 {
2514 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002515 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002516 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002517 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002518
2519 if (readBuffer && drawBuffer)
2520 {
2521 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2522 dstX0, dstY0, dstX1, dstY1))
2523 {
2524 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002525 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2526 "stencil blits are supported by "
2527 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002528 return false;
2529 }
2530
2531 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2532 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002533 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002534 return false;
2535 }
2536 }
2537 }
2538 }
2539
2540 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2541 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002542}
Jamie Madillc29968b2016-01-20 11:17:23 -05002543
Jamie Madill5b772312018-03-08 20:28:32 -05002544bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002545{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002546 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002547
Jamie Madill427064d2018-04-13 16:20:34 -04002548 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002549 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002550 return false;
2551 }
2552
2553 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002555 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002556 return false;
2557 }
2558
Geoff Lang76e65652017-03-27 14:58:02 -04002559 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2560 {
2561 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2562 GL_SIGNED_NORMALIZED};
2563
Corentin Wallez59c41592017-07-11 13:19:54 -04002564 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002565 drawBufferIdx++)
2566 {
2567 if (!ValidateWebGLFramebufferAttachmentClearType(
2568 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2569 {
2570 return false;
2571 }
2572 }
2573 }
2574
Jamie Madillc29968b2016-01-20 11:17:23 -05002575 return true;
2576}
2577
Jamie Madill5b772312018-03-08 20:28:32 -05002578bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002579{
2580 if (!context->getExtensions().drawBuffers)
2581 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002582 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002583 return false;
2584 }
2585
2586 return ValidateDrawBuffersBase(context, n, bufs);
2587}
2588
Jamie Madill73a84962016-02-12 09:27:23 -05002589bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002590 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002591 GLint level,
2592 GLint internalformat,
2593 GLsizei width,
2594 GLsizei height,
2595 GLint border,
2596 GLenum format,
2597 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002598 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002599{
Martin Radev1be913c2016-07-11 17:59:16 +03002600 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002601 {
2602 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002603 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002604 }
2605
Martin Radev1be913c2016-07-11 17:59:16 +03002606 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002607 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002608 0, 0, width, height, 1, border, format, type, -1,
2609 pixels);
2610}
2611
Brandon Jones416aaf92018-04-10 08:10:16 -07002612bool ValidateTexImage2DRobustANGLE(Context *context,
2613 TextureTarget target,
2614 GLint level,
2615 GLint internalformat,
2616 GLsizei width,
2617 GLsizei height,
2618 GLint border,
2619 GLenum format,
2620 GLenum type,
2621 GLsizei bufSize,
2622 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002623{
2624 if (!ValidateRobustEntryPoint(context, bufSize))
2625 {
2626 return false;
2627 }
2628
2629 if (context->getClientMajorVersion() < 3)
2630 {
2631 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2632 0, 0, width, height, border, format, type, bufSize,
2633 pixels);
2634 }
2635
2636 ASSERT(context->getClientMajorVersion() >= 3);
2637 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2638 0, 0, width, height, 1, border, format, type, bufSize,
2639 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002640}
2641
2642bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002643 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002644 GLint level,
2645 GLint xoffset,
2646 GLint yoffset,
2647 GLsizei width,
2648 GLsizei height,
2649 GLenum format,
2650 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002651 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002652{
2653
Martin Radev1be913c2016-07-11 17:59:16 +03002654 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002655 {
2656 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002657 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002658 }
2659
Martin Radev1be913c2016-07-11 17:59:16 +03002660 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002661 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002662 yoffset, 0, width, height, 1, 0, format, type, -1,
2663 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002664}
2665
Geoff Langc52f6f12016-10-14 10:18:00 -04002666bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002667 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002668 GLint level,
2669 GLint xoffset,
2670 GLint yoffset,
2671 GLsizei width,
2672 GLsizei height,
2673 GLenum format,
2674 GLenum type,
2675 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002676 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002677{
2678 if (!ValidateRobustEntryPoint(context, bufSize))
2679 {
2680 return false;
2681 }
2682
2683 if (context->getClientMajorVersion() < 3)
2684 {
2685 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2686 yoffset, width, height, 0, format, type, bufSize,
2687 pixels);
2688 }
2689
2690 ASSERT(context->getClientMajorVersion() >= 3);
2691 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2692 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2693 pixels);
2694}
2695
Jamie Madill73a84962016-02-12 09:27:23 -05002696bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002697 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002698 GLint level,
2699 GLenum internalformat,
2700 GLsizei width,
2701 GLsizei height,
2702 GLint border,
2703 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002704 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002705{
Martin Radev1be913c2016-07-11 17:59:16 +03002706 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002707 {
2708 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002709 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002710 {
2711 return false;
2712 }
2713 }
2714 else
2715 {
Martin Radev1be913c2016-07-11 17:59:16 +03002716 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002717 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002718 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002719 data))
2720 {
2721 return false;
2722 }
2723 }
2724
Geoff Langca271392017-04-05 12:30:00 -04002725 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002726 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002727 if (blockSizeOrErr.isError())
2728 {
2729 context->handleError(blockSizeOrErr.getError());
2730 return false;
2731 }
2732
2733 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002734 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002735 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002736 return false;
2737 }
2738
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002739 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002740 {
2741 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2742 return false;
2743 }
2744
Jamie Madill73a84962016-02-12 09:27:23 -05002745 return true;
2746}
2747
Corentin Wallezb2931602017-04-11 15:58:57 -04002748bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002749 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002750 GLint level,
2751 GLenum internalformat,
2752 GLsizei width,
2753 GLsizei height,
2754 GLint border,
2755 GLsizei imageSize,
2756 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002757 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002758{
2759 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2760 {
2761 return false;
2762 }
2763
2764 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2765 border, imageSize, data);
2766}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002767
Corentin Wallezb2931602017-04-11 15:58:57 -04002768bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002769 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002770 GLint level,
2771 GLint xoffset,
2772 GLint yoffset,
2773 GLsizei width,
2774 GLsizei height,
2775 GLenum format,
2776 GLsizei imageSize,
2777 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002778 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002779{
2780 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2781 {
2782 return false;
2783 }
2784
2785 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2786 format, imageSize, data);
2787}
2788
Jamie Madill73a84962016-02-12 09:27:23 -05002789bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002790 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002791 GLint level,
2792 GLint xoffset,
2793 GLint yoffset,
2794 GLsizei width,
2795 GLsizei height,
2796 GLenum format,
2797 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002798 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002799{
Martin Radev1be913c2016-07-11 17:59:16 +03002800 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002801 {
2802 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002803 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002804 {
2805 return false;
2806 }
2807 }
2808 else
2809 {
Martin Radev1be913c2016-07-11 17:59:16 +03002810 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002811 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002812 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002813 data))
2814 {
2815 return false;
2816 }
2817 }
2818
Geoff Langca271392017-04-05 12:30:00 -04002819 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002820 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002821 if (blockSizeOrErr.isError())
2822 {
2823 context->handleError(blockSizeOrErr.getError());
2824 return false;
2825 }
2826
2827 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002828 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002829 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002830 return false;
2831 }
2832
2833 return true;
2834}
2835
Corentin Wallez336129f2017-10-17 15:55:40 -04002836bool ValidateGetBufferPointervOES(Context *context,
2837 BufferBinding target,
2838 GLenum pname,
2839 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002840{
Geoff Lang496c02d2016-10-20 11:38:11 -07002841 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002842}
2843
Corentin Wallez336129f2017-10-17 15:55:40 -04002844bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002845{
2846 if (!context->getExtensions().mapBuffer)
2847 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002848 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002849 return false;
2850 }
2851
Corentin Walleze4477002017-12-01 14:39:58 -05002852 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002853 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002854 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002855 return false;
2856 }
2857
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002858 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002859
2860 if (buffer == nullptr)
2861 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002862 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002863 return false;
2864 }
2865
2866 if (access != GL_WRITE_ONLY_OES)
2867 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002868 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002869 return false;
2870 }
2871
2872 if (buffer->isMapped())
2873 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002874 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002875 return false;
2876 }
2877
Geoff Lang79f71042017-08-14 16:43:43 -04002878 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002879}
2880
Corentin Wallez336129f2017-10-17 15:55:40 -04002881bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002882{
2883 if (!context->getExtensions().mapBuffer)
2884 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002885 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002886 return false;
2887 }
2888
2889 return ValidateUnmapBufferBase(context, target);
2890}
2891
2892bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002893 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002894 GLintptr offset,
2895 GLsizeiptr length,
2896 GLbitfield access)
2897{
2898 if (!context->getExtensions().mapBufferRange)
2899 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002900 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002901 return false;
2902 }
2903
2904 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2905}
2906
Corentin Wallez336129f2017-10-17 15:55:40 -04002907bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002908{
2909 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2910 ASSERT(buffer != nullptr);
2911
2912 // Check if this buffer is currently being used as a transform feedback output buffer
2913 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2914 if (transformFeedback != nullptr && transformFeedback->isActive())
2915 {
2916 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2917 {
2918 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2919 if (transformFeedbackBuffer.get() == buffer)
2920 {
2921 context->handleError(InvalidOperation()
2922 << "Buffer is currently bound for transform feedback.");
2923 return false;
2924 }
2925 }
2926 }
2927
James Darpiniane8a93c62018-01-04 18:02:24 -08002928 if (context->getExtensions().webglCompatibility &&
2929 buffer->isBoundForTransformFeedbackAndOtherUse())
2930 {
2931 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2932 return false;
2933 }
2934
Geoff Lang79f71042017-08-14 16:43:43 -04002935 return true;
2936}
2937
Olli Etuaho4f667482016-03-30 15:56:35 +03002938bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002939 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002940 GLintptr offset,
2941 GLsizeiptr length)
2942{
2943 if (!context->getExtensions().mapBufferRange)
2944 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002945 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002946 return false;
2947 }
2948
2949 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2950}
2951
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002952bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002953{
2954 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002955 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002956 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002957 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002958 return false;
2959 }
2960
Geoff Langf41a7152016-09-19 15:11:17 -04002961 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2962 !context->isTextureGenerated(texture))
2963 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002964 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002965 return false;
2966 }
2967
Ian Ewell54f87462016-03-10 13:47:21 -05002968 switch (target)
2969 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002970 case TextureType::_2D:
2971 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002972 break;
2973
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002974 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002975 if (!context->getExtensions().textureRectangle)
2976 {
2977 context->handleError(InvalidEnum()
2978 << "Context does not support GL_ANGLE_texture_rectangle");
2979 return false;
2980 }
2981 break;
2982
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002983 case TextureType::_3D:
2984 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002985 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002986 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002987 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002988 return false;
2989 }
2990 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002991
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002992 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04002993 if (context->getClientVersion() < Version(3, 1))
2994 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002995 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002996 return false;
2997 }
Geoff Lang3b573612016-10-31 14:08:10 -04002998 break;
2999
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003000 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003001 if (!context->getExtensions().eglImageExternal &&
3002 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003003 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003004 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003005 return false;
3006 }
3007 break;
3008 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003009 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003010 return false;
3011 }
3012
3013 return true;
3014}
3015
Geoff Langd8605522016-04-13 10:19:12 -04003016bool ValidateBindUniformLocationCHROMIUM(Context *context,
3017 GLuint program,
3018 GLint location,
3019 const GLchar *name)
3020{
3021 if (!context->getExtensions().bindUniformLocation)
3022 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003023 context->handleError(InvalidOperation()
3024 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003025 return false;
3026 }
3027
3028 Program *programObject = GetValidProgram(context, program);
3029 if (!programObject)
3030 {
3031 return false;
3032 }
3033
3034 if (location < 0)
3035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003036 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003037 return false;
3038 }
3039
3040 const Caps &caps = context->getCaps();
3041 if (static_cast<size_t>(location) >=
3042 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3043 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003044 context->handleError(InvalidValue() << "Location must be less than "
3045 "(MAX_VERTEX_UNIFORM_VECTORS + "
3046 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003047 return false;
3048 }
3049
Geoff Langfc32e8b2017-05-31 14:16:59 -04003050 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3051 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003052 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003053 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003054 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003055 return false;
3056 }
3057
Geoff Langd8605522016-04-13 10:19:12 -04003058 if (strncmp(name, "gl_", 3) == 0)
3059 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003060 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003061 return false;
3062 }
3063
3064 return true;
3065}
3066
Jamie Madille2e406c2016-06-02 13:04:10 -04003067bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003068{
3069 if (!context->getExtensions().framebufferMixedSamples)
3070 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003071 context->handleError(InvalidOperation()
3072 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003073 return false;
3074 }
3075 switch (components)
3076 {
3077 case GL_RGB:
3078 case GL_RGBA:
3079 case GL_ALPHA:
3080 case GL_NONE:
3081 break;
3082 default:
3083 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003084 InvalidEnum()
3085 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003086 return false;
3087 }
3088
3089 return true;
3090}
3091
Sami Väisänene45e53b2016-05-25 10:36:04 +03003092// CHROMIUM_path_rendering
3093
Jamie Madill007530e2017-12-28 14:27:04 -05003094bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003095{
Jamie Madill007530e2017-12-28 14:27:04 -05003096 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003097 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003098 return false;
3099 }
Jamie Madill007530e2017-12-28 14:27:04 -05003100
Sami Väisänene45e53b2016-05-25 10:36:04 +03003101 if (matrix == nullptr)
3102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003103 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003104 return false;
3105 }
Jamie Madill007530e2017-12-28 14:27:04 -05003106
Sami Väisänene45e53b2016-05-25 10:36:04 +03003107 return true;
3108}
3109
Jamie Madill007530e2017-12-28 14:27:04 -05003110bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111{
Jamie Madill007530e2017-12-28 14:27:04 -05003112 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003113}
3114
Jamie Madill007530e2017-12-28 14:27:04 -05003115bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003116{
3117 if (!context->getExtensions().pathRendering)
3118 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003119 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003120 return false;
3121 }
3122
3123 // range = 0 is undefined in NV_path_rendering.
3124 // we add stricter semantic check here and require a non zero positive range.
3125 if (range <= 0)
3126 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003127 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003128 return false;
3129 }
3130
3131 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3132 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003133 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003134 return false;
3135 }
3136
3137 return true;
3138}
3139
Jamie Madill007530e2017-12-28 14:27:04 -05003140bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003141{
3142 if (!context->getExtensions().pathRendering)
3143 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003144 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003145 return false;
3146 }
3147
3148 // range = 0 is undefined in NV_path_rendering.
3149 // we add stricter semantic check here and require a non zero positive range.
3150 if (range <= 0)
3151 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003152 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003153 return false;
3154 }
3155
3156 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3157 checkedRange += range;
3158
3159 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3160 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003161 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003162 return false;
3163 }
3164 return true;
3165}
3166
Jamie Madill007530e2017-12-28 14:27:04 -05003167bool ValidatePathCommandsCHROMIUM(Context *context,
3168 GLuint path,
3169 GLsizei numCommands,
3170 const GLubyte *commands,
3171 GLsizei numCoords,
3172 GLenum coordType,
3173 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003174{
3175 if (!context->getExtensions().pathRendering)
3176 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003177 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003178 return false;
3179 }
Brandon Jones59770802018-04-02 13:18:42 -07003180 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003182 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003183 return false;
3184 }
3185
3186 if (numCommands < 0)
3187 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003188 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003189 return false;
3190 }
3191 else if (numCommands > 0)
3192 {
3193 if (!commands)
3194 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003195 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003196 return false;
3197 }
3198 }
3199
3200 if (numCoords < 0)
3201 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003202 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003203 return false;
3204 }
3205 else if (numCoords > 0)
3206 {
3207 if (!coords)
3208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003209 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003210 return false;
3211 }
3212 }
3213
3214 std::uint32_t coordTypeSize = 0;
3215 switch (coordType)
3216 {
3217 case GL_BYTE:
3218 coordTypeSize = sizeof(GLbyte);
3219 break;
3220
3221 case GL_UNSIGNED_BYTE:
3222 coordTypeSize = sizeof(GLubyte);
3223 break;
3224
3225 case GL_SHORT:
3226 coordTypeSize = sizeof(GLshort);
3227 break;
3228
3229 case GL_UNSIGNED_SHORT:
3230 coordTypeSize = sizeof(GLushort);
3231 break;
3232
3233 case GL_FLOAT:
3234 coordTypeSize = sizeof(GLfloat);
3235 break;
3236
3237 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003238 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003239 return false;
3240 }
3241
3242 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3243 checkedSize += (coordTypeSize * numCoords);
3244 if (!checkedSize.IsValid())
3245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003246 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003247 return false;
3248 }
3249
3250 // early return skips command data validation when it doesn't exist.
3251 if (!commands)
3252 return true;
3253
3254 GLsizei expectedNumCoords = 0;
3255 for (GLsizei i = 0; i < numCommands; ++i)
3256 {
3257 switch (commands[i])
3258 {
3259 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3260 break;
3261 case GL_MOVE_TO_CHROMIUM:
3262 case GL_LINE_TO_CHROMIUM:
3263 expectedNumCoords += 2;
3264 break;
3265 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3266 expectedNumCoords += 4;
3267 break;
3268 case GL_CUBIC_CURVE_TO_CHROMIUM:
3269 expectedNumCoords += 6;
3270 break;
3271 case GL_CONIC_CURVE_TO_CHROMIUM:
3272 expectedNumCoords += 5;
3273 break;
3274 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003275 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003276 return false;
3277 }
3278 }
3279 if (expectedNumCoords != numCoords)
3280 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003281 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003282 return false;
3283 }
3284
3285 return true;
3286}
3287
Jamie Madill007530e2017-12-28 14:27:04 -05003288bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003289{
3290 if (!context->getExtensions().pathRendering)
3291 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003292 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003293 return false;
3294 }
Brandon Jones59770802018-04-02 13:18:42 -07003295 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003296 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003297 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003298 return false;
3299 }
3300
3301 switch (pname)
3302 {
3303 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3304 if (value < 0.0f)
3305 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003306 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003307 return false;
3308 }
3309 break;
3310 case GL_PATH_END_CAPS_CHROMIUM:
3311 switch (static_cast<GLenum>(value))
3312 {
3313 case GL_FLAT_CHROMIUM:
3314 case GL_SQUARE_CHROMIUM:
3315 case GL_ROUND_CHROMIUM:
3316 break;
3317 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003318 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003319 return false;
3320 }
3321 break;
3322 case GL_PATH_JOIN_STYLE_CHROMIUM:
3323 switch (static_cast<GLenum>(value))
3324 {
3325 case GL_MITER_REVERT_CHROMIUM:
3326 case GL_BEVEL_CHROMIUM:
3327 case GL_ROUND_CHROMIUM:
3328 break;
3329 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003330 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003331 return false;
3332 }
Nico Weber41b072b2018-02-09 10:01:32 -05003333 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003334 case GL_PATH_MITER_LIMIT_CHROMIUM:
3335 if (value < 0.0f)
3336 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003337 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003338 return false;
3339 }
3340 break;
3341
3342 case GL_PATH_STROKE_BOUND_CHROMIUM:
3343 // no errors, only clamping.
3344 break;
3345
3346 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003347 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003348 return false;
3349 }
3350 return true;
3351}
3352
Jamie Madill007530e2017-12-28 14:27:04 -05003353bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3354{
3355 // TODO(jmadill): Use proper clamping cast.
3356 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3357}
3358
3359bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003360{
3361 if (!context->getExtensions().pathRendering)
3362 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003363 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003364 return false;
3365 }
3366
Brandon Jones59770802018-04-02 13:18:42 -07003367 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003368 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003369 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003370 return false;
3371 }
3372 if (!value)
3373 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003374 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003375 return false;
3376 }
3377
3378 switch (pname)
3379 {
3380 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3381 case GL_PATH_END_CAPS_CHROMIUM:
3382 case GL_PATH_JOIN_STYLE_CHROMIUM:
3383 case GL_PATH_MITER_LIMIT_CHROMIUM:
3384 case GL_PATH_STROKE_BOUND_CHROMIUM:
3385 break;
3386
3387 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003388 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003389 return false;
3390 }
3391
3392 return true;
3393}
3394
Jamie Madill007530e2017-12-28 14:27:04 -05003395bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3396{
3397 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3398 reinterpret_cast<GLfloat *>(value));
3399}
3400
3401bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003402{
3403 if (!context->getExtensions().pathRendering)
3404 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003405 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003406 return false;
3407 }
3408
3409 switch (func)
3410 {
3411 case GL_NEVER:
3412 case GL_ALWAYS:
3413 case GL_LESS:
3414 case GL_LEQUAL:
3415 case GL_EQUAL:
3416 case GL_GEQUAL:
3417 case GL_GREATER:
3418 case GL_NOTEQUAL:
3419 break;
3420 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003421 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003422 return false;
3423 }
3424
3425 return true;
3426}
3427
3428// Note that the spec specifies that for the path drawing commands
3429// if the path object is not an existing path object the command
3430// does nothing and no error is generated.
3431// However if the path object exists but has not been specified any
3432// commands then an error is generated.
3433
Jamie Madill007530e2017-12-28 14:27:04 -05003434bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003435{
3436 if (!context->getExtensions().pathRendering)
3437 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003438 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003439 return false;
3440 }
Brandon Jones59770802018-04-02 13:18:42 -07003441 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003442 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003444 return false;
3445 }
3446
3447 switch (fillMode)
3448 {
3449 case GL_COUNT_UP_CHROMIUM:
3450 case GL_COUNT_DOWN_CHROMIUM:
3451 break;
3452 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003453 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003454 return false;
3455 }
3456
3457 if (!isPow2(mask + 1))
3458 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003459 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003460 return false;
3461 }
3462
3463 return true;
3464}
3465
Jamie Madill007530e2017-12-28 14:27:04 -05003466bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003467{
3468 if (!context->getExtensions().pathRendering)
3469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003470 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471 return false;
3472 }
Brandon Jones59770802018-04-02 13:18:42 -07003473 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003475 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003476 return false;
3477 }
3478
3479 return true;
3480}
3481
Brandon Jonesd1049182018-03-28 10:02:20 -07003482bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3483{
3484 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3485}
3486
3487bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3488{
3489 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3490}
3491
Jamie Madill007530e2017-12-28 14:27:04 -05003492bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003493{
3494 if (!context->getExtensions().pathRendering)
3495 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003496 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003497 return false;
3498 }
Brandon Jones59770802018-04-02 13:18:42 -07003499 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003500 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003502 return false;
3503 }
3504
3505 switch (coverMode)
3506 {
3507 case GL_CONVEX_HULL_CHROMIUM:
3508 case GL_BOUNDING_BOX_CHROMIUM:
3509 break;
3510 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003511 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003512 return false;
3513 }
3514 return true;
3515}
3516
Jamie Madill007530e2017-12-28 14:27:04 -05003517bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3518 GLuint path,
3519 GLenum fillMode,
3520 GLuint mask,
3521 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003522{
Jamie Madill007530e2017-12-28 14:27:04 -05003523 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3524 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003525}
3526
Jamie Madill007530e2017-12-28 14:27:04 -05003527bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3528 GLuint path,
3529 GLint reference,
3530 GLuint mask,
3531 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003532{
Jamie Madill007530e2017-12-28 14:27:04 -05003533 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3534 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003535}
3536
Brandon Jonesd1049182018-03-28 10:02:20 -07003537bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003538{
3539 if (!context->getExtensions().pathRendering)
3540 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003541 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542 return false;
3543 }
3544 return true;
3545}
3546
Jamie Madill007530e2017-12-28 14:27:04 -05003547bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3548 GLsizei numPaths,
3549 GLenum pathNameType,
3550 const void *paths,
3551 GLuint pathBase,
3552 GLenum coverMode,
3553 GLenum transformType,
3554 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003555{
3556 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3557 transformType, transformValues))
3558 return false;
3559
3560 switch (coverMode)
3561 {
3562 case GL_CONVEX_HULL_CHROMIUM:
3563 case GL_BOUNDING_BOX_CHROMIUM:
3564 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3565 break;
3566 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003567 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003568 return false;
3569 }
3570
3571 return true;
3572}
3573
Jamie Madill007530e2017-12-28 14:27:04 -05003574bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3575 GLsizei numPaths,
3576 GLenum pathNameType,
3577 const void *paths,
3578 GLuint pathBase,
3579 GLenum coverMode,
3580 GLenum transformType,
3581 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003582{
3583 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3584 transformType, transformValues))
3585 return false;
3586
3587 switch (coverMode)
3588 {
3589 case GL_CONVEX_HULL_CHROMIUM:
3590 case GL_BOUNDING_BOX_CHROMIUM:
3591 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3592 break;
3593 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003594 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003595 return false;
3596 }
3597
3598 return true;
3599}
3600
Jamie Madill007530e2017-12-28 14:27:04 -05003601bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3602 GLsizei numPaths,
3603 GLenum pathNameType,
3604 const void *paths,
3605 GLuint pathBase,
3606 GLenum fillMode,
3607 GLuint mask,
3608 GLenum transformType,
3609 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003610{
3611
3612 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3613 transformType, transformValues))
3614 return false;
3615
3616 switch (fillMode)
3617 {
3618 case GL_COUNT_UP_CHROMIUM:
3619 case GL_COUNT_DOWN_CHROMIUM:
3620 break;
3621 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003622 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003623 return false;
3624 }
3625 if (!isPow2(mask + 1))
3626 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003627 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003628 return false;
3629 }
3630 return true;
3631}
3632
Jamie Madill007530e2017-12-28 14:27:04 -05003633bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3634 GLsizei numPaths,
3635 GLenum pathNameType,
3636 const void *paths,
3637 GLuint pathBase,
3638 GLint reference,
3639 GLuint mask,
3640 GLenum transformType,
3641 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003642{
3643 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3644 transformType, transformValues))
3645 return false;
3646
3647 // no more validation here.
3648
3649 return true;
3650}
3651
Jamie Madill007530e2017-12-28 14:27:04 -05003652bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3653 GLsizei numPaths,
3654 GLenum pathNameType,
3655 const void *paths,
3656 GLuint pathBase,
3657 GLenum fillMode,
3658 GLuint mask,
3659 GLenum coverMode,
3660 GLenum transformType,
3661 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003662{
3663 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3664 transformType, transformValues))
3665 return false;
3666
3667 switch (coverMode)
3668 {
3669 case GL_CONVEX_HULL_CHROMIUM:
3670 case GL_BOUNDING_BOX_CHROMIUM:
3671 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3672 break;
3673 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003674 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003675 return false;
3676 }
3677
3678 switch (fillMode)
3679 {
3680 case GL_COUNT_UP_CHROMIUM:
3681 case GL_COUNT_DOWN_CHROMIUM:
3682 break;
3683 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003684 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003685 return false;
3686 }
3687 if (!isPow2(mask + 1))
3688 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003689 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003690 return false;
3691 }
3692
3693 return true;
3694}
3695
Jamie Madill007530e2017-12-28 14:27:04 -05003696bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3697 GLsizei numPaths,
3698 GLenum pathNameType,
3699 const void *paths,
3700 GLuint pathBase,
3701 GLint reference,
3702 GLuint mask,
3703 GLenum coverMode,
3704 GLenum transformType,
3705 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003706{
3707 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3708 transformType, transformValues))
3709 return false;
3710
3711 switch (coverMode)
3712 {
3713 case GL_CONVEX_HULL_CHROMIUM:
3714 case GL_BOUNDING_BOX_CHROMIUM:
3715 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3716 break;
3717 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003718 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003719 return false;
3720 }
3721
3722 return true;
3723}
3724
Jamie Madill007530e2017-12-28 14:27:04 -05003725bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3726 GLuint program,
3727 GLint location,
3728 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003729{
3730 if (!context->getExtensions().pathRendering)
3731 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003732 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003733 return false;
3734 }
3735
3736 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3737 if (location >= MaxLocation)
3738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003739 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003740 return false;
3741 }
3742
3743 const auto *programObject = context->getProgram(program);
3744 if (!programObject)
3745 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003746 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003747 return false;
3748 }
3749
3750 if (!name)
3751 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003752 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003753 return false;
3754 }
3755
3756 if (angle::BeginsWith(name, "gl_"))
3757 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003758 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003759 return false;
3760 }
3761
3762 return true;
3763}
3764
Jamie Madill007530e2017-12-28 14:27:04 -05003765bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3766 GLuint program,
3767 GLint location,
3768 GLenum genMode,
3769 GLint components,
3770 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003771{
3772 if (!context->getExtensions().pathRendering)
3773 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003774 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003775 return false;
3776 }
3777
3778 const auto *programObject = context->getProgram(program);
3779 if (!programObject || programObject->isFlaggedForDeletion())
3780 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003781 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003782 return false;
3783 }
3784
3785 if (!programObject->isLinked())
3786 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003787 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003788 return false;
3789 }
3790
3791 switch (genMode)
3792 {
3793 case GL_NONE:
3794 if (components != 0)
3795 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003796 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003797 return false;
3798 }
3799 break;
3800
3801 case GL_OBJECT_LINEAR_CHROMIUM:
3802 case GL_EYE_LINEAR_CHROMIUM:
3803 case GL_CONSTANT_CHROMIUM:
3804 if (components < 1 || components > 4)
3805 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003806 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003807 return false;
3808 }
3809 if (!coeffs)
3810 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003811 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003812 return false;
3813 }
3814 break;
3815
3816 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003817 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003818 return false;
3819 }
3820
3821 // If the location is -1 then the command is silently ignored
3822 // and no further validation is needed.
3823 if (location == -1)
3824 return true;
3825
Jamie Madillbd044ed2017-06-05 12:59:21 -04003826 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003827
3828 if (!binding.valid)
3829 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003830 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003831 return false;
3832 }
3833
3834 if (binding.type != GL_NONE)
3835 {
3836 GLint expectedComponents = 0;
3837 switch (binding.type)
3838 {
3839 case GL_FLOAT:
3840 expectedComponents = 1;
3841 break;
3842 case GL_FLOAT_VEC2:
3843 expectedComponents = 2;
3844 break;
3845 case GL_FLOAT_VEC3:
3846 expectedComponents = 3;
3847 break;
3848 case GL_FLOAT_VEC4:
3849 expectedComponents = 4;
3850 break;
3851 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003852 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003853 InvalidOperation()
3854 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003855 return false;
3856 }
3857 if (expectedComponents != components && genMode != GL_NONE)
3858 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003859 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003860 return false;
3861 }
3862 }
3863 return true;
3864}
3865
Geoff Lang97073d12016-04-20 10:42:34 -07003866bool ValidateCopyTextureCHROMIUM(Context *context,
3867 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003868 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003869 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003870 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003871 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003872 GLint internalFormat,
3873 GLenum destType,
3874 GLboolean unpackFlipY,
3875 GLboolean unpackPremultiplyAlpha,
3876 GLboolean unpackUnmultiplyAlpha)
3877{
3878 if (!context->getExtensions().copyTexture)
3879 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003880 context->handleError(InvalidOperation()
3881 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003882 return false;
3883 }
3884
Geoff Lang4f0e0032017-05-01 16:04:35 -04003885 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003886 if (source == nullptr)
3887 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003888 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003889 return false;
3890 }
3891
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003892 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003893 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003894 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003895 return false;
3896 }
3897
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003898 TextureType sourceType = source->getType();
3899 ASSERT(sourceType != TextureType::CubeMap);
3900 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003901
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003902 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003903 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003904 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003905 return false;
3906 }
3907
Geoff Lang4f0e0032017-05-01 16:04:35 -04003908 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3909 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3910 if (sourceWidth == 0 || sourceHeight == 0)
3911 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003912 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003913 return false;
3914 }
3915
3916 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3917 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003918 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003919 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003920 return false;
3921 }
3922
Geoff Lang63458a32017-10-30 15:16:53 -04003923 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3924 {
3925 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3926 return false;
3927 }
3928
Geoff Lang4f0e0032017-05-01 16:04:35 -04003929 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003930 if (dest == nullptr)
3931 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003932 context->handleError(InvalidValue()
3933 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003934 return false;
3935 }
3936
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003937 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003938 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003939 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003940 return false;
3941 }
3942
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003943 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003944 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003945 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003946 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003947 return false;
3948 }
3949
Geoff Lang97073d12016-04-20 10:42:34 -07003950 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3951 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003952 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003953 return false;
3954 }
3955
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003956 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003957 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003958 context->handleError(
3959 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003960 return false;
3961 }
3962
Geoff Lang97073d12016-04-20 10:42:34 -07003963 if (dest->getImmutableFormat())
3964 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003965 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003966 return false;
3967 }
3968
3969 return true;
3970}
3971
3972bool ValidateCopySubTextureCHROMIUM(Context *context,
3973 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003974 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003975 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003976 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003977 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003978 GLint xoffset,
3979 GLint yoffset,
3980 GLint x,
3981 GLint y,
3982 GLsizei width,
3983 GLsizei height,
3984 GLboolean unpackFlipY,
3985 GLboolean unpackPremultiplyAlpha,
3986 GLboolean unpackUnmultiplyAlpha)
3987{
3988 if (!context->getExtensions().copyTexture)
3989 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003990 context->handleError(InvalidOperation()
3991 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003992 return false;
3993 }
3994
Geoff Lang4f0e0032017-05-01 16:04:35 -04003995 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003996 if (source == nullptr)
3997 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003998 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003999 return false;
4000 }
4001
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004002 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004003 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004004 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004005 return false;
4006 }
4007
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004008 TextureType sourceType = source->getType();
4009 ASSERT(sourceType != TextureType::CubeMap);
4010 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004011
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004012 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004013 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004014 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004015 return false;
4016 }
4017
4018 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4019 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004021 context->handleError(InvalidValue()
4022 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004023 return false;
4024 }
4025
4026 if (x < 0 || y < 0)
4027 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004028 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004029 return false;
4030 }
4031
4032 if (width < 0 || height < 0)
4033 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004034 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004035 return false;
4036 }
4037
Geoff Lang4f0e0032017-05-01 16:04:35 -04004038 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4039 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004040 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004041 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004042 return false;
4043 }
4044
Geoff Lang4f0e0032017-05-01 16:04:35 -04004045 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4046 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004047 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004048 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004049 return false;
4050 }
4051
Geoff Lang63458a32017-10-30 15:16:53 -04004052 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4053 {
4054 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4055 return false;
4056 }
4057
Geoff Lang4f0e0032017-05-01 16:04:35 -04004058 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004059 if (dest == nullptr)
4060 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004061 context->handleError(InvalidValue()
4062 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004063 return false;
4064 }
4065
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004066 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004067 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004068 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004069 return false;
4070 }
4071
Brandon Jones28783792018-03-05 09:37:32 -08004072 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4073 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004075 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004076 return false;
4077 }
4078
Geoff Lang4f0e0032017-05-01 16:04:35 -04004079 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4080 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004081 context
4082 ->handleError(InvalidOperation()
4083 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004084 return false;
4085 }
4086
4087 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4088 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004089 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004090 context->handleError(InvalidOperation()
4091 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004092 return false;
4093 }
4094
4095 if (xoffset < 0 || yoffset < 0)
4096 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004097 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004098 return false;
4099 }
4100
Geoff Lang4f0e0032017-05-01 16:04:35 -04004101 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4102 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004103 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004104 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004105 return false;
4106 }
4107
4108 return true;
4109}
4110
Geoff Lang47110bf2016-04-20 11:13:22 -07004111bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4112{
4113 if (!context->getExtensions().copyCompressedTexture)
4114 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004115 context->handleError(InvalidOperation()
4116 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004117 return false;
4118 }
4119
4120 const gl::Texture *source = context->getTexture(sourceId);
4121 if (source == nullptr)
4122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004123 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004124 return false;
4125 }
4126
Corentin Wallez99d492c2018-02-27 15:17:10 -05004127 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004128 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004129 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004130 return false;
4131 }
4132
Corentin Wallez99d492c2018-02-27 15:17:10 -05004133 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4134 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004135 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004136 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004137 return false;
4138 }
4139
Corentin Wallez99d492c2018-02-27 15:17:10 -05004140 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004141 if (!sourceFormat.info->compressed)
4142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004143 context->handleError(InvalidOperation()
4144 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004145 return false;
4146 }
4147
4148 const gl::Texture *dest = context->getTexture(destId);
4149 if (dest == nullptr)
4150 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004151 context->handleError(InvalidValue()
4152 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004153 return false;
4154 }
4155
Corentin Wallez99d492c2018-02-27 15:17:10 -05004156 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004157 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004158 context->handleError(InvalidValue()
4159 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004160 return false;
4161 }
4162
4163 if (dest->getImmutableFormat())
4164 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004165 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004166 return false;
4167 }
4168
4169 return true;
4170}
4171
Jiawei Shao385b3e02018-03-21 09:43:28 +08004172bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004173{
4174 switch (type)
4175 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004176 case ShaderType::Vertex:
4177 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004178 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004179
Jiawei Shao385b3e02018-03-21 09:43:28 +08004180 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004181 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004182 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004183 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004184 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004185 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004186 break;
4187
Jiawei Shao385b3e02018-03-21 09:43:28 +08004188 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004189 if (!context->getExtensions().geometryShader)
4190 {
4191 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4192 return false;
4193 }
4194 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004195 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004196 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004197 return false;
4198 }
Jamie Madill29639852016-09-02 15:00:09 -04004199
4200 return true;
4201}
4202
Jamie Madill5b772312018-03-08 20:28:32 -05004203bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004204 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004205 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004206 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004207 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004208{
4209 if (size < 0)
4210 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004211 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004212 return false;
4213 }
4214
4215 switch (usage)
4216 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004217 case BufferUsage::StreamDraw:
4218 case BufferUsage::StaticDraw:
4219 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004220 break;
4221
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004222 case BufferUsage::StreamRead:
4223 case BufferUsage::StaticRead:
4224 case BufferUsage::DynamicRead:
4225 case BufferUsage::StreamCopy:
4226 case BufferUsage::StaticCopy:
4227 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004228 if (context->getClientMajorVersion() < 3)
4229 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004230 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004231 return false;
4232 }
4233 break;
4234
4235 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004236 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004237 return false;
4238 }
4239
Corentin Walleze4477002017-12-01 14:39:58 -05004240 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004241 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004242 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004243 return false;
4244 }
4245
4246 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4247
4248 if (!buffer)
4249 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004250 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004251 return false;
4252 }
4253
James Darpiniane8a93c62018-01-04 18:02:24 -08004254 if (context->getExtensions().webglCompatibility &&
4255 buffer->isBoundForTransformFeedbackAndOtherUse())
4256 {
4257 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4258 return false;
4259 }
4260
Jamie Madill29639852016-09-02 15:00:09 -04004261 return true;
4262}
4263
Jamie Madill5b772312018-03-08 20:28:32 -05004264bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004265 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004266 GLintptr offset,
4267 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004268 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004269{
Brandon Jones6cad5662017-06-14 13:25:13 -07004270 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004271 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004272 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4273 return false;
4274 }
4275
4276 if (offset < 0)
4277 {
4278 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004279 return false;
4280 }
4281
Corentin Walleze4477002017-12-01 14:39:58 -05004282 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004283 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004284 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004285 return false;
4286 }
4287
4288 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4289
4290 if (!buffer)
4291 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004292 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004293 return false;
4294 }
4295
4296 if (buffer->isMapped())
4297 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004298 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004299 return false;
4300 }
4301
James Darpiniane8a93c62018-01-04 18:02:24 -08004302 if (context->getExtensions().webglCompatibility &&
4303 buffer->isBoundForTransformFeedbackAndOtherUse())
4304 {
4305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4306 return false;
4307 }
4308
Jamie Madill29639852016-09-02 15:00:09 -04004309 // Check for possible overflow of size + offset
4310 angle::CheckedNumeric<size_t> checkedSize(size);
4311 checkedSize += offset;
4312 if (!checkedSize.IsValid())
4313 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004314 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004315 return false;
4316 }
4317
4318 if (size + offset > buffer->getSize())
4319 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004320 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004321 return false;
4322 }
4323
Martin Radev4c4c8e72016-08-04 12:25:34 +03004324 return true;
4325}
4326
Geoff Lang111a99e2017-10-17 10:58:41 -04004327bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004328{
Geoff Langc339c4e2016-11-29 10:37:36 -05004329 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004330 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004331 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004332 return false;
4333 }
4334
Geoff Lang111a99e2017-10-17 10:58:41 -04004335 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004336 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004337 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004338 return false;
4339 }
4340
4341 return true;
4342}
4343
Jamie Madill5b772312018-03-08 20:28:32 -05004344bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004345{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004346 if (context->getClientMajorVersion() < 2)
4347 {
4348 return ValidateMultitextureUnit(context, texture);
4349 }
4350
Jamie Madillef300b12016-10-07 15:12:09 -04004351 if (texture < GL_TEXTURE0 ||
4352 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4353 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004354 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004355 return false;
4356 }
4357
4358 return true;
4359}
4360
Jamie Madill5b772312018-03-08 20:28:32 -05004361bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004362{
4363 Program *programObject = GetValidProgram(context, program);
4364 if (!programObject)
4365 {
4366 return false;
4367 }
4368
4369 Shader *shaderObject = GetValidShader(context, shader);
4370 if (!shaderObject)
4371 {
4372 return false;
4373 }
4374
Jiawei Shao385b3e02018-03-21 09:43:28 +08004375 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004376 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004377 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4378 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004379 }
4380
4381 return true;
4382}
4383
Jamie Madill5b772312018-03-08 20:28:32 -05004384bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004385{
4386 if (index >= MAX_VERTEX_ATTRIBS)
4387 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004388 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004389 return false;
4390 }
4391
4392 if (strncmp(name, "gl_", 3) == 0)
4393 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004394 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004395 return false;
4396 }
4397
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004398 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004399 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004400 const size_t length = strlen(name);
4401
4402 if (!IsValidESSLString(name, length))
4403 {
4404 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4405 // for shader-related entry points
4406 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4407 return false;
4408 }
4409
4410 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4411 {
4412 return false;
4413 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004414 }
4415
Jamie Madill01a80ee2016-11-07 12:06:18 -05004416 return GetValidProgram(context, program) != nullptr;
4417}
4418
Jamie Madill5b772312018-03-08 20:28:32 -05004419bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004420{
Corentin Walleze4477002017-12-01 14:39:58 -05004421 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004422 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004423 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004424 return false;
4425 }
4426
4427 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4428 !context->isBufferGenerated(buffer))
4429 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004430 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004431 return false;
4432 }
4433
4434 return true;
4435}
4436
Jamie Madill5b772312018-03-08 20:28:32 -05004437bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004438{
Geoff Lange8afa902017-09-27 15:00:43 -04004439 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004440 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004441 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004442 return false;
4443 }
4444
4445 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4446 !context->isFramebufferGenerated(framebuffer))
4447 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004448 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004449 return false;
4450 }
4451
4452 return true;
4453}
4454
Jamie Madill5b772312018-03-08 20:28:32 -05004455bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004456{
4457 if (target != GL_RENDERBUFFER)
4458 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004459 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004460 return false;
4461 }
4462
4463 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4464 !context->isRenderbufferGenerated(renderbuffer))
4465 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004466 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004467 return false;
4468 }
4469
4470 return true;
4471}
4472
Jamie Madill5b772312018-03-08 20:28:32 -05004473static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004474{
4475 switch (mode)
4476 {
4477 case GL_FUNC_ADD:
4478 case GL_FUNC_SUBTRACT:
4479 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004480 return true;
4481
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004482 case GL_MIN:
4483 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004484 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004485
4486 default:
4487 return false;
4488 }
4489}
4490
Jamie Madill5b772312018-03-08 20:28:32 -05004491bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004492{
4493 return true;
4494}
4495
Jamie Madill5b772312018-03-08 20:28:32 -05004496bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004497{
Geoff Lang50cac572017-09-26 17:37:43 -04004498 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004499 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004500 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004501 return false;
4502 }
4503
4504 return true;
4505}
4506
Jamie Madill5b772312018-03-08 20:28:32 -05004507bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004508{
Geoff Lang50cac572017-09-26 17:37:43 -04004509 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004510 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004511 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004512 return false;
4513 }
4514
Geoff Lang50cac572017-09-26 17:37:43 -04004515 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004516 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004517 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004518 return false;
4519 }
4520
4521 return true;
4522}
4523
Jamie Madill5b772312018-03-08 20:28:32 -05004524bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004525{
4526 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4527}
4528
4529static bool ValidSrcBlendFunc(GLenum srcBlend)
4530{
4531 switch (srcBlend)
4532 {
4533 case GL_ZERO:
4534 case GL_ONE:
4535 case GL_SRC_COLOR:
4536 case GL_ONE_MINUS_SRC_COLOR:
4537 case GL_DST_COLOR:
4538 case GL_ONE_MINUS_DST_COLOR:
4539 case GL_SRC_ALPHA:
4540 case GL_ONE_MINUS_SRC_ALPHA:
4541 case GL_DST_ALPHA:
4542 case GL_ONE_MINUS_DST_ALPHA:
4543 case GL_CONSTANT_COLOR:
4544 case GL_ONE_MINUS_CONSTANT_COLOR:
4545 case GL_CONSTANT_ALPHA:
4546 case GL_ONE_MINUS_CONSTANT_ALPHA:
4547 case GL_SRC_ALPHA_SATURATE:
4548 return true;
4549
4550 default:
4551 return false;
4552 }
4553}
4554
4555static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4556{
4557 switch (dstBlend)
4558 {
4559 case GL_ZERO:
4560 case GL_ONE:
4561 case GL_SRC_COLOR:
4562 case GL_ONE_MINUS_SRC_COLOR:
4563 case GL_DST_COLOR:
4564 case GL_ONE_MINUS_DST_COLOR:
4565 case GL_SRC_ALPHA:
4566 case GL_ONE_MINUS_SRC_ALPHA:
4567 case GL_DST_ALPHA:
4568 case GL_ONE_MINUS_DST_ALPHA:
4569 case GL_CONSTANT_COLOR:
4570 case GL_ONE_MINUS_CONSTANT_COLOR:
4571 case GL_CONSTANT_ALPHA:
4572 case GL_ONE_MINUS_CONSTANT_ALPHA:
4573 return true;
4574
4575 case GL_SRC_ALPHA_SATURATE:
4576 return (contextMajorVersion >= 3);
4577
4578 default:
4579 return false;
4580 }
4581}
4582
Jamie Madill5b772312018-03-08 20:28:32 -05004583bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004584 GLenum srcRGB,
4585 GLenum dstRGB,
4586 GLenum srcAlpha,
4587 GLenum dstAlpha)
4588{
4589 if (!ValidSrcBlendFunc(srcRGB))
4590 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004591 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004592 return false;
4593 }
4594
4595 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4596 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004597 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004598 return false;
4599 }
4600
4601 if (!ValidSrcBlendFunc(srcAlpha))
4602 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004603 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004604 return false;
4605 }
4606
4607 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4608 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004609 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004610 return false;
4611 }
4612
Frank Henigman146e8a12017-03-02 23:22:37 -05004613 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4614 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004615 {
4616 bool constantColorUsed =
4617 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4618 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4619
4620 bool constantAlphaUsed =
4621 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4622 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4623
4624 if (constantColorUsed && constantAlphaUsed)
4625 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004626 const char *msg;
4627 if (context->getExtensions().webglCompatibility)
4628 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004629 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004630 }
4631 else
4632 {
4633 msg =
4634 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4635 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4636 "implementation.";
4637 ERR() << msg;
4638 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004639 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004640 return false;
4641 }
4642 }
4643
4644 return true;
4645}
4646
Geoff Langc339c4e2016-11-29 10:37:36 -05004647bool ValidateGetString(Context *context, GLenum name)
4648{
4649 switch (name)
4650 {
4651 case GL_VENDOR:
4652 case GL_RENDERER:
4653 case GL_VERSION:
4654 case GL_SHADING_LANGUAGE_VERSION:
4655 case GL_EXTENSIONS:
4656 break;
4657
4658 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4659 if (!context->getExtensions().requestExtension)
4660 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004661 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004662 return false;
4663 }
4664 break;
4665
4666 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004667 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004668 return false;
4669 }
4670
4671 return true;
4672}
4673
Jamie Madill5b772312018-03-08 20:28:32 -05004674bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004675{
4676 if (width <= 0.0f || isNaN(width))
4677 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004678 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004679 return false;
4680 }
4681
4682 return true;
4683}
4684
Jamie Madill5b772312018-03-08 20:28:32 -05004685bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004686 GLuint index,
4687 GLint size,
4688 GLenum type,
4689 GLboolean normalized,
4690 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004691 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004692{
Shao80957d92017-02-20 21:25:59 +08004693 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004694 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004695 return false;
4696 }
4697
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004698 if (stride < 0)
4699 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004700 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004701 return false;
4702 }
4703
Shao80957d92017-02-20 21:25:59 +08004704 const Caps &caps = context->getCaps();
4705 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004706 {
Shao80957d92017-02-20 21:25:59 +08004707 if (stride > caps.maxVertexAttribStride)
4708 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004709 context->handleError(InvalidValue()
4710 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004711 return false;
4712 }
4713
4714 if (index >= caps.maxVertexAttribBindings)
4715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004716 context->handleError(InvalidValue()
4717 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004718 return false;
4719 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004720 }
4721
4722 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4723 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4724 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4725 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004726 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4727 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004728 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4729 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004730 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004731 context
4732 ->handleError(InvalidOperation()
4733 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004734 return false;
4735 }
4736
4737 if (context->getExtensions().webglCompatibility)
4738 {
4739 // WebGL 1.0 [Section 6.14] Fixed point support
4740 // The WebGL API does not support the GL_FIXED data type.
4741 if (type == GL_FIXED)
4742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004743 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004744 return false;
4745 }
4746
Geoff Lang2d62ab72017-03-23 16:54:40 -04004747 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004748 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004749 return false;
4750 }
4751 }
4752
4753 return true;
4754}
4755
Jamie Madill5b772312018-03-08 20:28:32 -05004756bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004757{
4758 if (context->getExtensions().webglCompatibility && zNear > zFar)
4759 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004760 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004761 return false;
4762 }
4763
4764 return true;
4765}
4766
Jamie Madill5b772312018-03-08 20:28:32 -05004767bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004768 GLenum target,
4769 GLenum internalformat,
4770 GLsizei width,
4771 GLsizei height)
4772{
4773 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4774 height);
4775}
4776
Jamie Madill5b772312018-03-08 20:28:32 -05004777bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004778 GLenum target,
4779 GLsizei samples,
4780 GLenum internalformat,
4781 GLsizei width,
4782 GLsizei height)
4783{
4784 if (!context->getExtensions().framebufferMultisample)
4785 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004786 context->handleError(InvalidOperation()
4787 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004788 return false;
4789 }
4790
4791 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4792 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4793 // generated.
4794 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4795 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004796 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004797 return false;
4798 }
4799
4800 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4801 // the specified storage. This is different than ES 3.0 in which a sample number higher
4802 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4803 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4804 if (context->getClientMajorVersion() >= 3)
4805 {
4806 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4807 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4808 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004809 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004810 return false;
4811 }
4812 }
4813
4814 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4815 width, height);
4816}
4817
Jamie Madill5b772312018-03-08 20:28:32 -05004818bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004819{
Geoff Lange8afa902017-09-27 15:00:43 -04004820 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004821 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004822 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004823 return false;
4824 }
4825
4826 return true;
4827}
4828
Jamie Madill5b772312018-03-08 20:28:32 -05004829bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004830{
4831 return true;
4832}
4833
Jamie Madill5b772312018-03-08 20:28:32 -05004834bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004835{
4836 return true;
4837}
4838
Jamie Madill5b772312018-03-08 20:28:32 -05004839bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004840{
4841 return true;
4842}
4843
Jamie Madill5b772312018-03-08 20:28:32 -05004844bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004845 GLboolean red,
4846 GLboolean green,
4847 GLboolean blue,
4848 GLboolean alpha)
4849{
4850 return true;
4851}
4852
Jamie Madill5b772312018-03-08 20:28:32 -05004853bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004854{
4855 return true;
4856}
4857
Jamie Madill5b772312018-03-08 20:28:32 -05004858bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004859{
4860 return true;
4861}
4862
Jamie Madill5b772312018-03-08 20:28:32 -05004863bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004864{
4865 switch (mode)
4866 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004867 case CullFaceMode::Front:
4868 case CullFaceMode::Back:
4869 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004870 break;
4871
4872 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004873 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004874 return false;
4875 }
4876
4877 return true;
4878}
4879
Jamie Madill5b772312018-03-08 20:28:32 -05004880bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004881{
4882 if (program == 0)
4883 {
4884 return false;
4885 }
4886
4887 if (!context->getProgram(program))
4888 {
4889 if (context->getShader(program))
4890 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004891 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004892 return false;
4893 }
4894 else
4895 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004896 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004897 return false;
4898 }
4899 }
4900
4901 return true;
4902}
4903
Jamie Madill5b772312018-03-08 20:28:32 -05004904bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004905{
4906 if (shader == 0)
4907 {
4908 return false;
4909 }
4910
4911 if (!context->getShader(shader))
4912 {
4913 if (context->getProgram(shader))
4914 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004915 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004916 return false;
4917 }
4918 else
4919 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004920 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004921 return false;
4922 }
4923 }
4924
4925 return true;
4926}
4927
Jamie Madill5b772312018-03-08 20:28:32 -05004928bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004929{
4930 switch (func)
4931 {
4932 case GL_NEVER:
4933 case GL_ALWAYS:
4934 case GL_LESS:
4935 case GL_LEQUAL:
4936 case GL_EQUAL:
4937 case GL_GREATER:
4938 case GL_GEQUAL:
4939 case GL_NOTEQUAL:
4940 break;
4941
4942 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004943 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004944 return false;
4945 }
4946
4947 return true;
4948}
4949
Jamie Madill5b772312018-03-08 20:28:32 -05004950bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004951{
4952 return true;
4953}
4954
Jamie Madill5b772312018-03-08 20:28:32 -05004955bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004956{
4957 Program *programObject = GetValidProgram(context, program);
4958 if (!programObject)
4959 {
4960 return false;
4961 }
4962
4963 Shader *shaderObject = GetValidShader(context, shader);
4964 if (!shaderObject)
4965 {
4966 return false;
4967 }
4968
Jiawei Shao385b3e02018-03-21 09:43:28 +08004969 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004970 if (attachedShader != shaderObject)
4971 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004972 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
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 ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004980{
4981 if (index >= MAX_VERTEX_ATTRIBS)
4982 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004983 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004984 return false;
4985 }
4986
4987 return true;
4988}
4989
Jamie Madill5b772312018-03-08 20:28:32 -05004990bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004991{
4992 if (index >= MAX_VERTEX_ATTRIBS)
4993 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004994 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004995 return false;
4996 }
4997
4998 return true;
4999}
5000
Jamie Madill5b772312018-03-08 20:28:32 -05005001bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005002{
5003 return true;
5004}
5005
Jamie Madill5b772312018-03-08 20:28:32 -05005006bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005007{
5008 return true;
5009}
5010
Jamie Madill5b772312018-03-08 20:28:32 -05005011bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005012{
5013 switch (mode)
5014 {
5015 case GL_CW:
5016 case GL_CCW:
5017 break;
5018 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005019 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005020 return false;
5021 }
5022
5023 return true;
5024}
5025
Jamie Madill5b772312018-03-08 20:28:32 -05005026bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005027 GLuint program,
5028 GLuint index,
5029 GLsizei bufsize,
5030 GLsizei *length,
5031 GLint *size,
5032 GLenum *type,
5033 GLchar *name)
5034{
5035 if (bufsize < 0)
5036 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005037 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005038 return false;
5039 }
5040
5041 Program *programObject = GetValidProgram(context, program);
5042
5043 if (!programObject)
5044 {
5045 return false;
5046 }
5047
5048 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5049 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005050 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005051 return false;
5052 }
5053
5054 return true;
5055}
5056
Jamie Madill5b772312018-03-08 20:28:32 -05005057bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005058 GLuint program,
5059 GLuint index,
5060 GLsizei bufsize,
5061 GLsizei *length,
5062 GLint *size,
5063 GLenum *type,
5064 GLchar *name)
5065{
5066 if (bufsize < 0)
5067 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005068 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005069 return false;
5070 }
5071
5072 Program *programObject = GetValidProgram(context, program);
5073
5074 if (!programObject)
5075 {
5076 return false;
5077 }
5078
5079 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5080 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005081 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005082 return false;
5083 }
5084
5085 return true;
5086}
5087
Jamie Madill5b772312018-03-08 20:28:32 -05005088bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005089 GLuint program,
5090 GLsizei maxcount,
5091 GLsizei *count,
5092 GLuint *shaders)
5093{
5094 if (maxcount < 0)
5095 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005096 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005097 return false;
5098 }
5099
5100 Program *programObject = GetValidProgram(context, program);
5101
5102 if (!programObject)
5103 {
5104 return false;
5105 }
5106
5107 return true;
5108}
5109
Jamie Madill5b772312018-03-08 20:28:32 -05005110bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005111{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005112 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5113 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005114 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005115 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005116 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005117 return false;
5118 }
5119
Jamie Madillc1d770e2017-04-13 17:31:24 -04005120 Program *programObject = GetValidProgram(context, program);
5121
5122 if (!programObject)
5123 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005124 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005125 return false;
5126 }
5127
5128 if (!programObject->isLinked())
5129 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005130 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005131 return false;
5132 }
5133
5134 return true;
5135}
5136
Jamie Madill5b772312018-03-08 20:28:32 -05005137bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005138{
5139 GLenum nativeType;
5140 unsigned int numParams = 0;
5141 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5142}
5143
Jamie Madill5b772312018-03-08 20:28:32 -05005144bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005145{
5146 return true;
5147}
5148
Jamie Madill5b772312018-03-08 20:28:32 -05005149bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005150{
5151 GLenum nativeType;
5152 unsigned int numParams = 0;
5153 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5154}
5155
Jamie Madill5b772312018-03-08 20:28:32 -05005156bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005157{
5158 GLenum nativeType;
5159 unsigned int numParams = 0;
5160 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5161}
5162
Jamie Madill5b772312018-03-08 20:28:32 -05005163bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005164 GLuint program,
5165 GLsizei bufsize,
5166 GLsizei *length,
5167 GLchar *infolog)
5168{
5169 if (bufsize < 0)
5170 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005171 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005172 return false;
5173 }
5174
5175 Program *programObject = GetValidProgram(context, program);
5176 if (!programObject)
5177 {
5178 return false;
5179 }
5180
5181 return true;
5182}
5183
Jamie Madill5b772312018-03-08 20:28:32 -05005184bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005185 GLuint shader,
5186 GLsizei bufsize,
5187 GLsizei *length,
5188 GLchar *infolog)
5189{
5190 if (bufsize < 0)
5191 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005192 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005193 return false;
5194 }
5195
5196 Shader *shaderObject = GetValidShader(context, shader);
5197 if (!shaderObject)
5198 {
5199 return false;
5200 }
5201
5202 return true;
5203}
5204
Jamie Madill5b772312018-03-08 20:28:32 -05005205bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005206 GLenum shadertype,
5207 GLenum precisiontype,
5208 GLint *range,
5209 GLint *precision)
5210{
5211 switch (shadertype)
5212 {
5213 case GL_VERTEX_SHADER:
5214 case GL_FRAGMENT_SHADER:
5215 break;
5216 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005217 context->handleError(InvalidOperation()
5218 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005219 return false;
5220 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005221 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005222 return false;
5223 }
5224
5225 switch (precisiontype)
5226 {
5227 case GL_LOW_FLOAT:
5228 case GL_MEDIUM_FLOAT:
5229 case GL_HIGH_FLOAT:
5230 case GL_LOW_INT:
5231 case GL_MEDIUM_INT:
5232 case GL_HIGH_INT:
5233 break;
5234
5235 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005236 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005237 return false;
5238 }
5239
5240 return true;
5241}
5242
Jamie Madill5b772312018-03-08 20:28:32 -05005243bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005244 GLuint shader,
5245 GLsizei bufsize,
5246 GLsizei *length,
5247 GLchar *source)
5248{
5249 if (bufsize < 0)
5250 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005251 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005252 return false;
5253 }
5254
5255 Shader *shaderObject = GetValidShader(context, shader);
5256 if (!shaderObject)
5257 {
5258 return false;
5259 }
5260
5261 return true;
5262}
5263
Jamie Madill5b772312018-03-08 20:28:32 -05005264bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005265{
5266 if (strstr(name, "gl_") == name)
5267 {
5268 return false;
5269 }
5270
Geoff Langfc32e8b2017-05-31 14:16:59 -04005271 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5272 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005273 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005274 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005275 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005276 return false;
5277 }
5278
Jamie Madillc1d770e2017-04-13 17:31:24 -04005279 Program *programObject = GetValidProgram(context, program);
5280
5281 if (!programObject)
5282 {
5283 return false;
5284 }
5285
5286 if (!programObject->isLinked())
5287 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005288 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005289 return false;
5290 }
5291
5292 return true;
5293}
5294
Jamie Madill5b772312018-03-08 20:28:32 -05005295bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005296{
5297 switch (mode)
5298 {
5299 case GL_FASTEST:
5300 case GL_NICEST:
5301 case GL_DONT_CARE:
5302 break;
5303
5304 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005305 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005306 return false;
5307 }
5308
5309 switch (target)
5310 {
5311 case GL_GENERATE_MIPMAP_HINT:
5312 break;
5313
Geoff Lange7bd2182017-06-16 16:13:13 -04005314 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5315 if (context->getClientVersion() < ES_3_0 &&
5316 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005317 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005318 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005319 return false;
5320 }
5321 break;
5322
5323 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005324 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005325 return false;
5326 }
5327
5328 return true;
5329}
5330
Jamie Madill5b772312018-03-08 20:28:32 -05005331bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005332{
5333 return true;
5334}
5335
Jamie Madill5b772312018-03-08 20:28:32 -05005336bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005337{
5338 return true;
5339}
5340
Jamie Madill5b772312018-03-08 20:28:32 -05005341bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005342{
5343 return true;
5344}
5345
Jamie Madill5b772312018-03-08 20:28:32 -05005346bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347{
5348 return true;
5349}
5350
Jamie Madill5b772312018-03-08 20:28:32 -05005351bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005352{
5353 return true;
5354}
5355
Jamie Madill5b772312018-03-08 20:28:32 -05005356bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005357{
5358 return true;
5359}
5360
Jamie Madill5b772312018-03-08 20:28:32 -05005361bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005362{
5363 if (context->getClientMajorVersion() < 3)
5364 {
5365 switch (pname)
5366 {
5367 case GL_UNPACK_IMAGE_HEIGHT:
5368 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005369 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005370 return false;
5371
5372 case GL_UNPACK_ROW_LENGTH:
5373 case GL_UNPACK_SKIP_ROWS:
5374 case GL_UNPACK_SKIP_PIXELS:
5375 if (!context->getExtensions().unpackSubimage)
5376 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005377 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378 return false;
5379 }
5380 break;
5381
5382 case GL_PACK_ROW_LENGTH:
5383 case GL_PACK_SKIP_ROWS:
5384 case GL_PACK_SKIP_PIXELS:
5385 if (!context->getExtensions().packSubimage)
5386 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005387 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005388 return false;
5389 }
5390 break;
5391 }
5392 }
5393
5394 if (param < 0)
5395 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005396 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397 return false;
5398 }
5399
5400 switch (pname)
5401 {
5402 case GL_UNPACK_ALIGNMENT:
5403 if (param != 1 && param != 2 && param != 4 && param != 8)
5404 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005405 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005406 return false;
5407 }
5408 break;
5409
5410 case GL_PACK_ALIGNMENT:
5411 if (param != 1 && param != 2 && param != 4 && param != 8)
5412 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005413 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005414 return false;
5415 }
5416 break;
5417
5418 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005419 if (!context->getExtensions().packReverseRowOrder)
5420 {
5421 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5422 }
5423 break;
5424
Jamie Madillc1d770e2017-04-13 17:31:24 -04005425 case GL_UNPACK_ROW_LENGTH:
5426 case GL_UNPACK_IMAGE_HEIGHT:
5427 case GL_UNPACK_SKIP_IMAGES:
5428 case GL_UNPACK_SKIP_ROWS:
5429 case GL_UNPACK_SKIP_PIXELS:
5430 case GL_PACK_ROW_LENGTH:
5431 case GL_PACK_SKIP_ROWS:
5432 case GL_PACK_SKIP_PIXELS:
5433 break;
5434
5435 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005436 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005437 return false;
5438 }
5439
5440 return true;
5441}
5442
Jamie Madill5b772312018-03-08 20:28:32 -05005443bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444{
5445 return true;
5446}
5447
Jamie Madill5b772312018-03-08 20:28:32 -05005448bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005449{
5450 return true;
5451}
5452
Jamie Madill5b772312018-03-08 20:28:32 -05005453bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005454{
5455 return true;
5456}
5457
Jamie Madill5b772312018-03-08 20:28:32 -05005458bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005459{
5460 if (width < 0 || height < 0)
5461 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005462 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005463 return false;
5464 }
5465
5466 return true;
5467}
5468
Jamie Madill5b772312018-03-08 20:28:32 -05005469bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470 GLsizei n,
5471 const GLuint *shaders,
5472 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005473 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005474 GLsizei length)
5475{
5476 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5477 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5478 shaderBinaryFormats.end())
5479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005480 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005481 return false;
5482 }
5483
5484 return true;
5485}
5486
Jamie Madill5b772312018-03-08 20:28:32 -05005487bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005488 GLuint shader,
5489 GLsizei count,
5490 const GLchar *const *string,
5491 const GLint *length)
5492{
5493 if (count < 0)
5494 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005495 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005496 return false;
5497 }
5498
Geoff Langfc32e8b2017-05-31 14:16:59 -04005499 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5500 // shader-related entry points
5501 if (context->getExtensions().webglCompatibility)
5502 {
5503 for (GLsizei i = 0; i < count; i++)
5504 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005505 size_t len =
5506 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005507
5508 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005509 if (!IsValidESSLShaderSourceString(string[i], len,
5510 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005511 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005512 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005513 return false;
5514 }
5515 }
5516 }
5517
Jamie Madillc1d770e2017-04-13 17:31:24 -04005518 Shader *shaderObject = GetValidShader(context, shader);
5519 if (!shaderObject)
5520 {
5521 return false;
5522 }
5523
5524 return true;
5525}
5526
Jamie Madill5b772312018-03-08 20:28:32 -05005527bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005528{
5529 if (!IsValidStencilFunc(func))
5530 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005531 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005532 return false;
5533 }
5534
5535 return true;
5536}
5537
Jamie Madill5b772312018-03-08 20:28:32 -05005538bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005539{
5540 if (!IsValidStencilFace(face))
5541 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005542 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005543 return false;
5544 }
5545
5546 if (!IsValidStencilFunc(func))
5547 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005548 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005549 return false;
5550 }
5551
5552 return true;
5553}
5554
Jamie Madill5b772312018-03-08 20:28:32 -05005555bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556{
5557 return true;
5558}
5559
Jamie Madill5b772312018-03-08 20:28:32 -05005560bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005561{
5562 if (!IsValidStencilFace(face))
5563 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005564 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005565 return false;
5566 }
5567
5568 return true;
5569}
5570
Jamie Madill5b772312018-03-08 20:28:32 -05005571bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005572{
5573 if (!IsValidStencilOp(fail))
5574 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005575 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005576 return false;
5577 }
5578
5579 if (!IsValidStencilOp(zfail))
5580 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005581 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005582 return false;
5583 }
5584
5585 if (!IsValidStencilOp(zpass))
5586 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005587 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005588 return false;
5589 }
5590
5591 return true;
5592}
5593
Jamie Madill5b772312018-03-08 20:28:32 -05005594bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005595 GLenum face,
5596 GLenum fail,
5597 GLenum zfail,
5598 GLenum zpass)
5599{
5600 if (!IsValidStencilFace(face))
5601 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005602 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005603 return false;
5604 }
5605
5606 return ValidateStencilOp(context, fail, zfail, zpass);
5607}
5608
Jamie Madill5b772312018-03-08 20:28:32 -05005609bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005610{
5611 return ValidateUniform(context, GL_FLOAT, location, 1);
5612}
5613
Jamie Madill5b772312018-03-08 20:28:32 -05005614bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005615{
5616 return ValidateUniform(context, GL_FLOAT, location, count);
5617}
5618
Jamie Madill5b772312018-03-08 20:28:32 -05005619bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005620{
5621 return ValidateUniform1iv(context, location, 1, &x);
5622}
5623
Jamie Madill5b772312018-03-08 20:28:32 -05005624bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005625{
5626 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5627}
5628
Jamie Madill5b772312018-03-08 20:28:32 -05005629bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005630{
5631 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5632}
5633
Jamie Madill5b772312018-03-08 20:28:32 -05005634bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005635{
5636 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5637}
5638
Jamie Madill5b772312018-03-08 20:28:32 -05005639bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005640{
5641 return ValidateUniform(context, GL_INT_VEC2, location, count);
5642}
5643
Jamie Madill5b772312018-03-08 20:28:32 -05005644bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005645{
5646 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5647}
5648
Jamie Madill5b772312018-03-08 20:28:32 -05005649bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650{
5651 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655{
5656 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5657}
5658
Jamie Madill5b772312018-03-08 20:28:32 -05005659bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005660{
5661 return ValidateUniform(context, GL_INT_VEC3, location, count);
5662}
5663
Jamie Madill5b772312018-03-08 20:28:32 -05005664bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005665{
5666 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670{
5671 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5672}
5673
Jamie Madill5b772312018-03-08 20:28:32 -05005674bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675{
5676 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005680{
5681 return ValidateUniform(context, GL_INT_VEC4, location, count);
5682}
5683
Jamie Madill5b772312018-03-08 20:28:32 -05005684bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005685 GLint location,
5686 GLsizei count,
5687 GLboolean transpose,
5688 const GLfloat *value)
5689{
5690 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5691}
5692
Jamie Madill5b772312018-03-08 20:28:32 -05005693bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005694 GLint location,
5695 GLsizei count,
5696 GLboolean transpose,
5697 const GLfloat *value)
5698{
5699 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5700}
5701
Jamie Madill5b772312018-03-08 20:28:32 -05005702bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005703 GLint location,
5704 GLsizei count,
5705 GLboolean transpose,
5706 const GLfloat *value)
5707{
5708 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5709}
5710
Jamie Madill5b772312018-03-08 20:28:32 -05005711bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005712{
5713 Program *programObject = GetValidProgram(context, program);
5714
5715 if (!programObject)
5716 {
5717 return false;
5718 }
5719
5720 return true;
5721}
5722
Jamie Madill5b772312018-03-08 20:28:32 -05005723bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005724{
5725 return ValidateVertexAttribIndex(context, index);
5726}
5727
Jamie Madill5b772312018-03-08 20:28:32 -05005728bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005729{
5730 return ValidateVertexAttribIndex(context, index);
5731}
5732
Jamie Madill5b772312018-03-08 20:28:32 -05005733bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005734{
5735 return ValidateVertexAttribIndex(context, index);
5736}
5737
Jamie Madill5b772312018-03-08 20:28:32 -05005738bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005739{
5740 return ValidateVertexAttribIndex(context, index);
5741}
5742
Jamie Madill5b772312018-03-08 20:28:32 -05005743bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005744{
5745 return ValidateVertexAttribIndex(context, index);
5746}
5747
Jamie Madill5b772312018-03-08 20:28:32 -05005748bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005749{
5750 return ValidateVertexAttribIndex(context, index);
5751}
5752
Jamie Madill5b772312018-03-08 20:28:32 -05005753bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005754 GLuint index,
5755 GLfloat x,
5756 GLfloat y,
5757 GLfloat z,
5758 GLfloat w)
5759{
5760 return ValidateVertexAttribIndex(context, index);
5761}
5762
Jamie Madill5b772312018-03-08 20:28:32 -05005763bool ValidateVertexAttrib4fv(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 ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005769{
5770 if (width < 0 || height < 0)
5771 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005772 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005773 return false;
5774 }
5775
5776 return true;
5777}
5778
Jamie Madill493f9572018-05-24 19:52:15 -04005779bool ValidateDrawArrays(Context *context, PrimitiveMode mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005780{
5781 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5782}
5783
Jamie Madill5b772312018-03-08 20:28:32 -05005784bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005785 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005786 GLsizei count,
5787 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005788 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005789{
5790 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5791}
5792
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005793bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005794 GLenum target,
5795 GLenum attachment,
5796 GLenum pname,
5797 GLint *params)
5798{
5799 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5800 nullptr);
5801}
5802
Jamie Madill5b772312018-03-08 20:28:32 -05005803bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005804{
5805 return ValidateGetProgramivBase(context, program, pname, nullptr);
5806}
5807
Jamie Madill5b772312018-03-08 20:28:32 -05005808bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005809 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005810 GLint level,
5811 GLenum internalformat,
5812 GLint x,
5813 GLint y,
5814 GLsizei width,
5815 GLsizei height,
5816 GLint border)
5817{
5818 if (context->getClientMajorVersion() < 3)
5819 {
5820 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5821 0, x, y, width, height, border);
5822 }
5823
5824 ASSERT(context->getClientMajorVersion() == 3);
5825 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5826 0, x, y, width, height, border);
5827}
5828
5829bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005830 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005831 GLint level,
5832 GLint xoffset,
5833 GLint yoffset,
5834 GLint x,
5835 GLint y,
5836 GLsizei width,
5837 GLsizei height)
5838{
5839 if (context->getClientMajorVersion() < 3)
5840 {
5841 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5842 yoffset, x, y, width, height, 0);
5843 }
5844
5845 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5846 yoffset, 0, x, y, width, height, 0);
5847}
5848
5849bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5850{
5851 return ValidateGenOrDelete(context, n);
5852}
5853
5854bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5855{
5856 return ValidateGenOrDelete(context, n);
5857}
5858
5859bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5860{
5861 return ValidateGenOrDelete(context, n);
5862}
5863
5864bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5865{
5866 return ValidateGenOrDelete(context, n);
5867}
5868
5869bool ValidateDisable(Context *context, GLenum cap)
5870{
5871 if (!ValidCap(context, cap, false))
5872 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005873 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005874 return false;
5875 }
5876
5877 return true;
5878}
5879
5880bool ValidateEnable(Context *context, GLenum cap)
5881{
5882 if (!ValidCap(context, cap, false))
5883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005884 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005885 return false;
5886 }
5887
5888 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5889 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5890 {
5891 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005892 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005893
5894 // We also output an error message to the debugger window if tracing is active, so that
5895 // developers can see the error message.
5896 ERR() << errorMessage;
5897 return false;
5898 }
5899
5900 return true;
5901}
5902
5903bool ValidateFramebufferRenderbuffer(Context *context,
5904 GLenum target,
5905 GLenum attachment,
5906 GLenum renderbuffertarget,
5907 GLuint renderbuffer)
5908{
Geoff Lange8afa902017-09-27 15:00:43 -04005909 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005910 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005911 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5912 return false;
5913 }
5914
5915 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5916 {
5917 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005918 return false;
5919 }
5920
5921 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5922 renderbuffertarget, renderbuffer);
5923}
5924
5925bool ValidateFramebufferTexture2D(Context *context,
5926 GLenum target,
5927 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005928 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005929 GLuint texture,
5930 GLint level)
5931{
5932 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5933 // extension
5934 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5935 level != 0)
5936 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005937 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005938 return false;
5939 }
5940
5941 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5942 {
5943 return false;
5944 }
5945
5946 if (texture != 0)
5947 {
5948 gl::Texture *tex = context->getTexture(texture);
5949 ASSERT(tex);
5950
5951 const gl::Caps &caps = context->getCaps();
5952
5953 switch (textarget)
5954 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005955 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005956 {
5957 if (level > gl::log2(caps.max2DTextureSize))
5958 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005959 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005960 return false;
5961 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005962 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005963 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005964 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005965 return false;
5966 }
5967 }
5968 break;
5969
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005970 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005971 {
5972 if (level != 0)
5973 {
5974 context->handleError(InvalidValue());
5975 return false;
5976 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005977 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005978 {
5979 context->handleError(InvalidOperation()
5980 << "Textarget must match the texture target type.");
5981 return false;
5982 }
5983 }
5984 break;
5985
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005986 case TextureTarget::CubeMapNegativeX:
5987 case TextureTarget::CubeMapNegativeY:
5988 case TextureTarget::CubeMapNegativeZ:
5989 case TextureTarget::CubeMapPositiveX:
5990 case TextureTarget::CubeMapPositiveY:
5991 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005992 {
5993 if (level > gl::log2(caps.maxCubeMapTextureSize))
5994 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005995 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005996 return false;
5997 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005998 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04005999 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006000 context->handleError(InvalidOperation()
6001 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006002 return false;
6003 }
6004 }
6005 break;
6006
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006007 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006008 {
6009 if (context->getClientVersion() < ES_3_1)
6010 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006011 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 return false;
6013 }
6014
6015 if (level != 0)
6016 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006017 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006018 return false;
6019 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006020 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006021 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006022 context->handleError(InvalidOperation()
6023 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006024 return false;
6025 }
6026 }
6027 break;
6028
6029 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006030 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006031 return false;
6032 }
6033
6034 const Format &format = tex->getFormat(textarget, level);
6035 if (format.info->compressed)
6036 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006037 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006038 return false;
6039 }
6040 }
6041
6042 return true;
6043}
6044
6045bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6046{
6047 return ValidateGenOrDelete(context, n);
6048}
6049
6050bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6051{
6052 return ValidateGenOrDelete(context, n);
6053}
6054
6055bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6056{
6057 return ValidateGenOrDelete(context, n);
6058}
6059
6060bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6061{
6062 return ValidateGenOrDelete(context, n);
6063}
6064
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006065bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006066{
6067 if (!ValidTextureTarget(context, target))
6068 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006069 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006070 return false;
6071 }
6072
6073 Texture *texture = context->getTargetTexture(target);
6074
6075 if (texture == nullptr)
6076 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006077 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006078 return false;
6079 }
6080
6081 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6082
6083 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6084 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6085 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6086 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006087 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006088 return false;
6089 }
6090
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006091 TextureTarget baseTarget = (target == TextureType::CubeMap)
6092 ? TextureTarget::CubeMapPositiveX
6093 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006094 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6095 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6096 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006097 {
6098 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6099 return false;
6100 }
6101
Geoff Lang536eca12017-09-13 11:23:35 -04006102 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6103 bool formatUnsized = !format.sized;
6104 bool formatColorRenderableAndFilterable =
6105 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6106 format.renderSupport(context->getClientVersion(), context->getExtensions());
6107 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006108 {
Geoff Lang536eca12017-09-13 11:23:35 -04006109 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006110 return false;
6111 }
6112
Geoff Lang536eca12017-09-13 11:23:35 -04006113 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6114 // generation
6115 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6116 {
6117 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6118 return false;
6119 }
6120
6121 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
Geoff Lange24032a2018-03-28 15:41:46 -04006122 // not. Differentiate the ES3 format from the extension format by checking if the format is
6123 // sized, GL_EXT_sRGB does not add any sized formats.
6124 bool supportsSRGBMipmapGeneration = context->getExtensions().webglCompatibility;
6125 if (!supportsSRGBMipmapGeneration && !format.sized && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006126 {
Geoff Lang536eca12017-09-13 11:23:35 -04006127 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006128 return false;
6129 }
6130
6131 // Non-power of 2 ES2 check
6132 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6133 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6134 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6135 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006136 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6137 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006138 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006139 return false;
6140 }
6141
6142 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006143 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006144 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006145 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006146 return false;
6147 }
6148
6149 return true;
6150}
6151
Jamie Madill5b772312018-03-08 20:28:32 -05006152bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006153 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006154 GLenum pname,
6155 GLint *params)
6156{
6157 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6158}
6159
6160bool ValidateGetRenderbufferParameteriv(Context *context,
6161 GLenum target,
6162 GLenum pname,
6163 GLint *params)
6164{
6165 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6166}
6167
6168bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6169{
6170 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6171}
6172
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006173bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006174{
6175 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6176}
6177
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006178bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006179{
6180 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6181}
6182
6183bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6184{
6185 return ValidateGetUniformBase(context, program, location);
6186}
6187
6188bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6189{
6190 return ValidateGetUniformBase(context, program, location);
6191}
6192
6193bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6194{
6195 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6196}
6197
6198bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6199{
6200 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6201}
6202
6203bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6204{
6205 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6206}
6207
6208bool ValidateIsEnabled(Context *context, GLenum cap)
6209{
6210 if (!ValidCap(context, cap, true))
6211 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006212 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006213 return false;
6214 }
6215
6216 return true;
6217}
6218
6219bool ValidateLinkProgram(Context *context, GLuint program)
6220{
6221 if (context->hasActiveTransformFeedback(program))
6222 {
6223 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006224 context->handleError(InvalidOperation() << "Cannot link program while program is "
6225 "associated with an active transform "
6226 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006227 return false;
6228 }
6229
6230 Program *programObject = GetValidProgram(context, program);
6231 if (!programObject)
6232 {
6233 return false;
6234 }
6235
6236 return true;
6237}
6238
Jamie Madill4928b7c2017-06-20 12:57:39 -04006239bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006240 GLint x,
6241 GLint y,
6242 GLsizei width,
6243 GLsizei height,
6244 GLenum format,
6245 GLenum type,
6246 void *pixels)
6247{
6248 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6249 nullptr, pixels);
6250}
6251
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006252bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006253{
6254 return ValidateTexParameterBase(context, target, pname, -1, &param);
6255}
6256
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006257bool ValidateTexParameterfv(Context *context,
6258 TextureType target,
6259 GLenum pname,
6260 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006261{
6262 return ValidateTexParameterBase(context, target, pname, -1, params);
6263}
6264
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006265bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006266{
6267 return ValidateTexParameterBase(context, target, pname, -1, &param);
6268}
6269
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006270bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006271{
6272 return ValidateTexParameterBase(context, target, pname, -1, params);
6273}
6274
6275bool ValidateUseProgram(Context *context, GLuint program)
6276{
6277 if (program != 0)
6278 {
6279 Program *programObject = context->getProgram(program);
6280 if (!programObject)
6281 {
6282 // ES 3.1.0 section 7.3 page 72
6283 if (context->getShader(program))
6284 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006285 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006286 return false;
6287 }
6288 else
6289 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006290 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006291 return false;
6292 }
6293 }
6294 if (!programObject->isLinked())
6295 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006296 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006297 return false;
6298 }
6299 }
6300 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6301 {
6302 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006303 context
6304 ->handleError(InvalidOperation()
6305 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006306 return false;
6307 }
6308
6309 return true;
6310}
6311
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006312bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6313{
6314 if (!context->getExtensions().fence)
6315 {
6316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6317 return false;
6318 }
6319
6320 if (n < 0)
6321 {
6322 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6323 return false;
6324 }
6325
6326 return true;
6327}
6328
6329bool ValidateFinishFenceNV(Context *context, GLuint fence)
6330{
6331 if (!context->getExtensions().fence)
6332 {
6333 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6334 return false;
6335 }
6336
6337 FenceNV *fenceObject = context->getFenceNV(fence);
6338
6339 if (fenceObject == nullptr)
6340 {
6341 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6342 return false;
6343 }
6344
6345 if (!fenceObject->isSet())
6346 {
6347 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6348 return false;
6349 }
6350
6351 return true;
6352}
6353
6354bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6355{
6356 if (!context->getExtensions().fence)
6357 {
6358 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6359 return false;
6360 }
6361
6362 if (n < 0)
6363 {
6364 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6365 return false;
6366 }
6367
6368 return true;
6369}
6370
6371bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6372{
6373 if (!context->getExtensions().fence)
6374 {
6375 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6376 return false;
6377 }
6378
6379 FenceNV *fenceObject = context->getFenceNV(fence);
6380
6381 if (fenceObject == nullptr)
6382 {
6383 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6384 return false;
6385 }
6386
6387 if (!fenceObject->isSet())
6388 {
6389 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6390 return false;
6391 }
6392
6393 switch (pname)
6394 {
6395 case GL_FENCE_STATUS_NV:
6396 case GL_FENCE_CONDITION_NV:
6397 break;
6398
6399 default:
6400 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6401 return false;
6402 }
6403
6404 return true;
6405}
6406
6407bool ValidateGetGraphicsResetStatusEXT(Context *context)
6408{
6409 if (!context->getExtensions().robustness)
6410 {
6411 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6412 return false;
6413 }
6414
6415 return true;
6416}
6417
6418bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6419 GLuint shader,
6420 GLsizei bufsize,
6421 GLsizei *length,
6422 GLchar *source)
6423{
6424 if (!context->getExtensions().translatedShaderSource)
6425 {
6426 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6427 return false;
6428 }
6429
6430 if (bufsize < 0)
6431 {
6432 context->handleError(InvalidValue());
6433 return false;
6434 }
6435
6436 Shader *shaderObject = context->getShader(shader);
6437
6438 if (!shaderObject)
6439 {
6440 context->handleError(InvalidOperation());
6441 return false;
6442 }
6443
6444 return true;
6445}
6446
6447bool ValidateIsFenceNV(Context *context, GLuint fence)
6448{
6449 if (!context->getExtensions().fence)
6450 {
6451 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6452 return false;
6453 }
6454
6455 return true;
6456}
6457
Jamie Madill007530e2017-12-28 14:27:04 -05006458bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6459{
6460 if (!context->getExtensions().fence)
6461 {
6462 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6463 return false;
6464 }
6465
6466 if (condition != GL_ALL_COMPLETED_NV)
6467 {
6468 context->handleError(InvalidEnum());
6469 return false;
6470 }
6471
6472 FenceNV *fenceObject = context->getFenceNV(fence);
6473
6474 if (fenceObject == nullptr)
6475 {
6476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6477 return false;
6478 }
6479
6480 return true;
6481}
6482
6483bool ValidateTestFenceNV(Context *context, GLuint fence)
6484{
6485 if (!context->getExtensions().fence)
6486 {
6487 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6488 return false;
6489 }
6490
6491 FenceNV *fenceObject = context->getFenceNV(fence);
6492
6493 if (fenceObject == nullptr)
6494 {
6495 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6496 return false;
6497 }
6498
6499 if (fenceObject->isSet() != GL_TRUE)
6500 {
6501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6502 return false;
6503 }
6504
6505 return true;
6506}
6507
6508bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006509 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006510 GLsizei levels,
6511 GLenum internalformat,
6512 GLsizei width,
6513 GLsizei height)
6514{
6515 if (!context->getExtensions().textureStorage)
6516 {
6517 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6518 return false;
6519 }
6520
6521 if (context->getClientMajorVersion() < 3)
6522 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006523 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006524 height);
6525 }
6526
6527 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006528 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006529 1);
6530}
6531
6532bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6533{
6534 if (!context->getExtensions().instancedArrays)
6535 {
6536 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6537 return false;
6538 }
6539
6540 if (index >= MAX_VERTEX_ATTRIBS)
6541 {
6542 context->handleError(InvalidValue());
6543 return false;
6544 }
6545
6546 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6547 {
6548 if (index == 0 && divisor != 0)
6549 {
6550 const char *errorMessage =
6551 "The current context doesn't support setting a non-zero divisor on the "
6552 "attribute with index zero. "
6553 "Please reorder the attributes in your vertex shader so that attribute zero "
6554 "can have a zero divisor.";
6555 context->handleError(InvalidOperation() << errorMessage);
6556
6557 // We also output an error message to the debugger window if tracing is active, so
6558 // that developers can see the error message.
6559 ERR() << errorMessage;
6560 return false;
6561 }
6562 }
6563
6564 return true;
6565}
6566
6567bool ValidateTexImage3DOES(Context *context,
6568 GLenum target,
6569 GLint level,
6570 GLenum internalformat,
6571 GLsizei width,
6572 GLsizei height,
6573 GLsizei depth,
6574 GLint border,
6575 GLenum format,
6576 GLenum type,
6577 const void *pixels)
6578{
6579 UNIMPLEMENTED(); // FIXME
6580 return false;
6581}
6582
6583bool ValidatePopGroupMarkerEXT(Context *context)
6584{
6585 if (!context->getExtensions().debugMarker)
6586 {
6587 // The debug marker calls should not set error state
6588 // However, it seems reasonable to set an error state if the extension is not enabled
6589 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6590 return false;
6591 }
6592
6593 return true;
6594}
6595
Jamie Madillfa920eb2018-01-04 11:45:50 -05006596bool ValidateTexStorage1DEXT(Context *context,
6597 GLenum target,
6598 GLsizei levels,
6599 GLenum internalformat,
6600 GLsizei width)
6601{
6602 UNIMPLEMENTED();
6603 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6604 return false;
6605}
6606
6607bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006608 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006609 GLsizei levels,
6610 GLenum internalformat,
6611 GLsizei width,
6612 GLsizei height,
6613 GLsizei depth)
6614{
6615 if (!context->getExtensions().textureStorage)
6616 {
6617 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6618 return false;
6619 }
6620
6621 if (context->getClientMajorVersion() < 3)
6622 {
6623 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6624 return false;
6625 }
6626
6627 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6628 depth);
6629}
6630
Jamie Madillc29968b2016-01-20 11:17:23 -05006631} // namespace gl