blob: dba491715b401266926445c9336485e029931388 [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 Yang060088a2018-05-30 20:40:57 -0700814 case GL_CLIP_PLANE0:
815 case GL_CLIP_PLANE1:
816 case GL_CLIP_PLANE2:
817 case GL_CLIP_PLANE3:
818 case GL_CLIP_PLANE4:
819 case GL_CLIP_PLANE5:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700820 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700821 case GL_POINT_SIZE_ARRAY_OES:
822 return context->getClientVersion() < Version(2, 0) &&
823 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700824 case GL_TEXTURE_CUBE_MAP:
825 return context->getClientVersion() < Version(2, 0) &&
826 context->getExtensions().textureCubeMap;
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700827
Jamie Madillbe849e42017-05-02 15:49:00 -0400828 default:
829 return false;
830 }
831}
832
Geoff Langfc32e8b2017-05-31 14:16:59 -0400833// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
834// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400835bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400836{
837 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400838 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
839 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400840 {
841 return true;
842 }
843
844 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
845 if (c >= 9 && c <= 13)
846 {
847 return true;
848 }
849
850 return false;
851}
852
Geoff Langcab92ee2017-07-19 17:32:07 -0400853bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400854{
Geoff Langa71a98e2017-06-19 15:15:00 -0400855 for (size_t i = 0; i < len; i++)
856 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400857 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400858 {
859 return false;
860 }
861 }
862
863 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400864}
865
Geoff Langcab92ee2017-07-19 17:32:07 -0400866bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
867{
868 enum class ParseState
869 {
870 // Have not seen an ASCII non-whitespace character yet on
871 // this line. Possible that we might see a preprocessor
872 // directive.
873 BEGINING_OF_LINE,
874
875 // Have seen at least one ASCII non-whitespace character
876 // on this line.
877 MIDDLE_OF_LINE,
878
879 // Handling a preprocessor directive. Passes through all
880 // characters up to the end of the line. Disables comment
881 // processing.
882 IN_PREPROCESSOR_DIRECTIVE,
883
884 // Handling a single-line comment. The comment text is
885 // replaced with a single space.
886 IN_SINGLE_LINE_COMMENT,
887
888 // Handling a multi-line comment. Newlines are passed
889 // through to preserve line numbers.
890 IN_MULTI_LINE_COMMENT
891 };
892
893 ParseState state = ParseState::BEGINING_OF_LINE;
894 size_t pos = 0;
895
896 while (pos < len)
897 {
898 char c = str[pos];
899 char next = pos + 1 < len ? str[pos + 1] : 0;
900
901 // Check for newlines
902 if (c == '\n' || c == '\r')
903 {
904 if (state != ParseState::IN_MULTI_LINE_COMMENT)
905 {
906 state = ParseState::BEGINING_OF_LINE;
907 }
908
909 pos++;
910 continue;
911 }
912
913 switch (state)
914 {
915 case ParseState::BEGINING_OF_LINE:
916 if (c == ' ')
917 {
918 // Maintain the BEGINING_OF_LINE state until a non-space is seen
919 pos++;
920 }
921 else if (c == '#')
922 {
923 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
924 pos++;
925 }
926 else
927 {
928 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
929 state = ParseState::MIDDLE_OF_LINE;
930 }
931 break;
932
933 case ParseState::MIDDLE_OF_LINE:
934 if (c == '/' && next == '/')
935 {
936 state = ParseState::IN_SINGLE_LINE_COMMENT;
937 pos++;
938 }
939 else if (c == '/' && next == '*')
940 {
941 state = ParseState::IN_MULTI_LINE_COMMENT;
942 pos++;
943 }
944 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
945 {
946 // Skip line continuation characters
947 }
948 else if (!IsValidESSLCharacter(c))
949 {
950 return false;
951 }
952 pos++;
953 break;
954
955 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700956 // Line-continuation characters may not be permitted.
957 // Otherwise, just pass it through. Do not parse comments in this state.
958 if (!lineContinuationAllowed && c == '\\')
959 {
960 return false;
961 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400962 pos++;
963 break;
964
965 case ParseState::IN_SINGLE_LINE_COMMENT:
966 // Line-continuation characters are processed before comment processing.
967 // Advance string if a new line character is immediately behind
968 // line-continuation character.
969 if (c == '\\' && (next == '\n' || next == '\r'))
970 {
971 pos++;
972 }
973 pos++;
974 break;
975
976 case ParseState::IN_MULTI_LINE_COMMENT:
977 if (c == '*' && next == '/')
978 {
979 state = ParseState::MIDDLE_OF_LINE;
980 pos++;
981 }
982 pos++;
983 break;
984 }
985 }
986
987 return true;
988}
989
Jamie Madill5b772312018-03-08 20:28:32 -0500990bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700991{
992 ASSERT(context->isWebGL());
993
994 // WebGL 1.0 [Section 6.16] GLSL Constructs
995 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
996 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
997 {
998 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
999 return false;
1000 }
1001
1002 return true;
1003}
1004
Jamie Madill5b772312018-03-08 20:28:32 -05001005bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001006{
1007 ASSERT(context->isWebGL());
1008
1009 if (context->isWebGL1() && length > 256)
1010 {
1011 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1012 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1013 // locations.
1014 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1015
1016 return false;
1017 }
1018 else if (length > 1024)
1019 {
1020 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1021 // uniform and attribute locations.
1022 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1023 return false;
1024 }
1025
1026 return true;
1027}
1028
Jamie Madill007530e2017-12-28 14:27:04 -05001029bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1030{
1031 if (!context->getExtensions().pathRendering)
1032 {
1033 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1034 return false;
1035 }
1036
1037 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1038 {
1039 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1040 return false;
1041 }
1042 return true;
1043}
Jamie Madillc29968b2016-01-20 11:17:23 -05001044} // anonymous namespace
1045
Geoff Langff5b2d52016-09-07 11:32:23 -04001046bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001047 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001048 GLint level,
1049 GLenum internalformat,
1050 bool isCompressed,
1051 bool isSubImage,
1052 GLint xoffset,
1053 GLint yoffset,
1054 GLsizei width,
1055 GLsizei height,
1056 GLint border,
1057 GLenum format,
1058 GLenum type,
1059 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001060 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001061{
Jamie Madill6f38f822014-06-06 17:12:20 -04001062 if (!ValidTexture2DDestinationTarget(context, target))
1063 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001064 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001065 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001066 }
1067
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001068 TextureType texType = TextureTargetToType(target);
1069 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001070 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001071 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001072 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001073 }
1074
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001075 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001076 {
1077 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1078 return false;
1079 }
1080
1081 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001082 std::numeric_limits<GLsizei>::max() - yoffset < height)
1083 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001084 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001085 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001086 }
1087
Geoff Lang6e898aa2017-06-02 11:17:26 -04001088 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1089 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1090 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1091 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1092 // case.
1093 bool nonEqualFormatsAllowed =
1094 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1095 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1096
1097 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001098 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001099 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001100 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001101 }
1102
Geoff Langaae65a42014-05-26 12:43:44 -04001103 const gl::Caps &caps = context->getCaps();
1104
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001105 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001106 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001107 case TextureType::_2D:
1108 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1109 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1110 {
1111 context->handleError(InvalidValue());
1112 return false;
1113 }
1114 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001115
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001116 case TextureType::Rectangle:
1117 ASSERT(level == 0);
1118 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1119 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1120 {
1121 context->handleError(InvalidValue());
1122 return false;
1123 }
1124 if (isCompressed)
1125 {
1126 context->handleError(InvalidEnum()
1127 << "Rectangle texture cannot have a compressed format.");
1128 return false;
1129 }
1130 break;
1131
1132 case TextureType::CubeMap:
1133 if (!isSubImage && width != height)
1134 {
1135 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1136 return false;
1137 }
1138
1139 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1140 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1141 {
1142 context->handleError(InvalidValue());
1143 return false;
1144 }
1145 break;
1146
1147 default:
1148 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001149 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001150 }
1151
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001152 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001153 if (!texture)
1154 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001155 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001156 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001157 }
1158
Geoff Langa9be0dc2014-12-17 12:34:40 -05001159 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001160 {
Geoff Langca271392017-04-05 12:30:00 -04001161 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1162 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001164 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001165 return false;
1166 }
1167
Geoff Langa9be0dc2014-12-17 12:34:40 -05001168 if (format != GL_NONE)
1169 {
Geoff Langca271392017-04-05 12:30:00 -04001170 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1171 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001172 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001173 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001174 return false;
1175 }
1176 }
1177
1178 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1179 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1180 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001181 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001182 return false;
1183 }
Geoff Langfb052642017-10-24 13:42:09 -04001184
1185 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001186 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001187 {
1188 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1189 return false;
1190 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001191 }
1192 else
1193 {
Geoff Lang69cce582015-09-17 13:20:36 -04001194 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001195 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001196 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001197 return false;
1198 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001199 }
1200
1201 // Verify zero border
1202 if (border != 0)
1203 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001204 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001205 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001206 }
1207
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001208 if (isCompressed)
1209 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001210 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001211 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1212 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001213
1214 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1215
1216 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001217 {
Geoff Lange88e4542018-05-03 15:05:57 -04001218 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1219 return false;
1220 }
1221
1222 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1223 context->getExtensions()))
1224 {
1225 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1226 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001227 }
Geoff Lang966c9402017-04-18 12:38:27 -04001228
1229 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001230 {
Geoff Lange88e4542018-05-03 15:05:57 -04001231 // From the OES_compressed_ETC1_RGB8_texture spec:
1232 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1233 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1234 // ETC1_RGB8_OES.
1235 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1236 {
1237 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1238 return false;
1239 }
1240
Geoff Lang966c9402017-04-18 12:38:27 -04001241 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1242 height, texture->getWidth(target, level),
1243 texture->getHeight(target, level)))
1244 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001245 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001246 return false;
1247 }
1248
1249 if (format != actualInternalFormat)
1250 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001251 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001252 return false;
1253 }
1254 }
1255 else
1256 {
1257 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1258 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001259 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001260 return false;
1261 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001262 }
1263 }
1264 else
1265 {
1266 // validate <type> by itself (used as secondary key below)
1267 switch (type)
1268 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001269 case GL_UNSIGNED_BYTE:
1270 case GL_UNSIGNED_SHORT_5_6_5:
1271 case GL_UNSIGNED_SHORT_4_4_4_4:
1272 case GL_UNSIGNED_SHORT_5_5_5_1:
1273 case GL_UNSIGNED_SHORT:
1274 case GL_UNSIGNED_INT:
1275 case GL_UNSIGNED_INT_24_8_OES:
1276 case GL_HALF_FLOAT_OES:
1277 case GL_FLOAT:
1278 break;
1279 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001280 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001281 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001282 }
1283
1284 // validate <format> + <type> combinations
1285 // - invalid <format> -> sets INVALID_ENUM
1286 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1287 switch (format)
1288 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001289 case GL_ALPHA:
1290 case GL_LUMINANCE:
1291 case GL_LUMINANCE_ALPHA:
1292 switch (type)
1293 {
1294 case GL_UNSIGNED_BYTE:
1295 case GL_FLOAT:
1296 case GL_HALF_FLOAT_OES:
1297 break;
1298 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001299 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001300 return false;
1301 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001302 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 case GL_RED:
1304 case GL_RG:
1305 if (!context->getExtensions().textureRG)
1306 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001307 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001308 return false;
1309 }
1310 switch (type)
1311 {
1312 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001313 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001314 case GL_FLOAT:
1315 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001316 if (!context->getExtensions().textureFloat)
1317 {
1318 context->handleError(InvalidEnum());
1319 return false;
1320 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001321 break;
1322 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001323 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001324 return false;
1325 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001326 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001327 case GL_RGB:
1328 switch (type)
1329 {
1330 case GL_UNSIGNED_BYTE:
1331 case GL_UNSIGNED_SHORT_5_6_5:
1332 case GL_FLOAT:
1333 case GL_HALF_FLOAT_OES:
1334 break;
1335 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001336 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001337 return false;
1338 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001339 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001340 case GL_RGBA:
1341 switch (type)
1342 {
1343 case GL_UNSIGNED_BYTE:
1344 case GL_UNSIGNED_SHORT_4_4_4_4:
1345 case GL_UNSIGNED_SHORT_5_5_5_1:
1346 case GL_FLOAT:
1347 case GL_HALF_FLOAT_OES:
1348 break;
1349 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001351 return false;
1352 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001353 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001354 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001355 if (!context->getExtensions().textureFormatBGRA8888)
1356 {
1357 context->handleError(InvalidEnum());
1358 return false;
1359 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001360 switch (type)
1361 {
1362 case GL_UNSIGNED_BYTE:
1363 break;
1364 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001365 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001366 return false;
1367 }
1368 break;
1369 case GL_SRGB_EXT:
1370 case GL_SRGB_ALPHA_EXT:
1371 if (!context->getExtensions().sRGB)
1372 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001373 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001374 return false;
1375 }
1376 switch (type)
1377 {
1378 case GL_UNSIGNED_BYTE:
1379 break;
1380 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001382 return false;
1383 }
1384 break;
1385 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1386 // handled below
1387 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1388 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1389 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1390 break;
1391 case GL_DEPTH_COMPONENT:
1392 switch (type)
1393 {
1394 case GL_UNSIGNED_SHORT:
1395 case GL_UNSIGNED_INT:
1396 break;
1397 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001398 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001399 return false;
1400 }
1401 break;
1402 case GL_DEPTH_STENCIL_OES:
1403 switch (type)
1404 {
1405 case GL_UNSIGNED_INT_24_8_OES:
1406 break;
1407 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001408 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001409 return false;
1410 }
1411 break;
1412 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001413 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001414 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001415 }
1416
1417 switch (format)
1418 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001419 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1420 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1421 if (context->getExtensions().textureCompressionDXT1)
1422 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001423 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001424 return false;
1425 }
1426 else
1427 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001428 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001429 return false;
1430 }
1431 break;
1432 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1433 if (context->getExtensions().textureCompressionDXT3)
1434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001435 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001436 return false;
1437 }
1438 else
1439 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001440 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001441 return false;
1442 }
1443 break;
1444 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1445 if (context->getExtensions().textureCompressionDXT5)
1446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001447 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001448 return false;
1449 }
1450 else
1451 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001452 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001453 return false;
1454 }
1455 break;
1456 case GL_ETC1_RGB8_OES:
1457 if (context->getExtensions().compressedETC1RGB8Texture)
1458 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001459 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001460 return false;
1461 }
1462 else
1463 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001464 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001465 return false;
1466 }
1467 break;
1468 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001469 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1470 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1471 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1472 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001473 if (context->getExtensions().lossyETCDecode)
1474 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001475 context->handleError(InvalidOperation()
1476 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001477 return false;
1478 }
1479 else
1480 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001481 context->handleError(InvalidEnum()
1482 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001483 return false;
1484 }
1485 break;
1486 case GL_DEPTH_COMPONENT:
1487 case GL_DEPTH_STENCIL_OES:
1488 if (!context->getExtensions().depthTextures)
1489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001490 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001491 return false;
1492 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001493 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001494 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001495 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001496 return false;
1497 }
1498 // OES_depth_texture supports loading depth data and multiple levels,
1499 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001500 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001501 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001502 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1503 return false;
1504 }
1505 if (level != 0)
1506 {
1507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001508 return false;
1509 }
1510 break;
1511 default:
1512 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001513 }
1514
Geoff Lang6e898aa2017-06-02 11:17:26 -04001515 if (!isSubImage)
1516 {
1517 switch (internalformat)
1518 {
1519 case GL_RGBA32F:
1520 if (!context->getExtensions().colorBufferFloatRGBA)
1521 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001522 context->handleError(InvalidValue()
1523 << "Sized GL_RGBA32F internal format requires "
1524 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001525 return false;
1526 }
1527 if (type != GL_FLOAT)
1528 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001529 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001530 return false;
1531 }
1532 if (format != GL_RGBA)
1533 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001534 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001535 return false;
1536 }
1537 break;
1538
1539 case GL_RGB32F:
1540 if (!context->getExtensions().colorBufferFloatRGB)
1541 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001542 context->handleError(InvalidValue()
1543 << "Sized GL_RGB32F internal format requires "
1544 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001545 return false;
1546 }
1547 if (type != GL_FLOAT)
1548 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001549 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001550 return false;
1551 }
1552 if (format != GL_RGB)
1553 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001555 return false;
1556 }
1557 break;
1558
1559 default:
1560 break;
1561 }
1562 }
1563
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001564 if (type == GL_FLOAT)
1565 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001566 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001567 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001568 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001569 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001570 }
1571 }
1572 else if (type == GL_HALF_FLOAT_OES)
1573 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001574 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001575 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001576 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001577 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001578 }
1579 }
1580 }
1581
Geoff Langdbcced82017-06-06 15:55:54 -04001582 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001583 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001584 imageSize))
1585 {
1586 return false;
1587 }
1588
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001589 return true;
1590}
1591
He Yunchaoced53ae2016-11-29 15:00:51 +08001592bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001593 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001594 GLsizei levels,
1595 GLenum internalformat,
1596 GLsizei width,
1597 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001598{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001599 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1600 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001601 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001602 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001603 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001604 }
1605
1606 if (width < 1 || height < 1 || levels < 1)
1607 {
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
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001612 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001613 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001614 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001615 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001616 }
1617
1618 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1619 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001620 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001621 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001622 }
1623
Geoff Langca271392017-04-05 12:30:00 -04001624 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001625 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001626 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001627 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001628 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001629 }
1630
Geoff Langaae65a42014-05-26 12:43:44 -04001631 const gl::Caps &caps = context->getCaps();
1632
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 switch (target)
1634 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001635 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001636 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1637 static_cast<GLuint>(height) > caps.max2DTextureSize)
1638 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001639 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001640 return false;
1641 }
1642 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001643 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001644 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1645 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1646 {
1647 context->handleError(InvalidValue());
1648 return false;
1649 }
1650 if (formatInfo.compressed)
1651 {
1652 context->handleError(InvalidEnum()
1653 << "Rectangle texture cannot have a compressed format.");
1654 return false;
1655 }
1656 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001657 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001658 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1659 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1660 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001661 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001662 return false;
1663 }
1664 break;
1665 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001666 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001667 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001668 }
1669
Geoff Langc0b9ef42014-07-02 10:02:37 -04001670 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001671 {
1672 if (!gl::isPow2(width) || !gl::isPow2(height))
1673 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001674 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001675 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001676 }
1677 }
1678
1679 switch (internalformat)
1680 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001681 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1682 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1683 if (!context->getExtensions().textureCompressionDXT1)
1684 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001685 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001686 return false;
1687 }
1688 break;
1689 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1690 if (!context->getExtensions().textureCompressionDXT3)
1691 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001692 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001693 return false;
1694 }
1695 break;
1696 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1697 if (!context->getExtensions().textureCompressionDXT5)
1698 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001699 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001700 return false;
1701 }
1702 break;
1703 case GL_ETC1_RGB8_OES:
1704 if (!context->getExtensions().compressedETC1RGB8Texture)
1705 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001706 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001707 return false;
1708 }
1709 break;
1710 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001711 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1712 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1713 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1714 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001715 if (!context->getExtensions().lossyETCDecode)
1716 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001717 context->handleError(InvalidEnum()
1718 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001719 return false;
1720 }
1721 break;
1722 case GL_RGBA32F_EXT:
1723 case GL_RGB32F_EXT:
1724 case GL_ALPHA32F_EXT:
1725 case GL_LUMINANCE32F_EXT:
1726 case GL_LUMINANCE_ALPHA32F_EXT:
1727 if (!context->getExtensions().textureFloat)
1728 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001729 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001730 return false;
1731 }
1732 break;
1733 case GL_RGBA16F_EXT:
1734 case GL_RGB16F_EXT:
1735 case GL_ALPHA16F_EXT:
1736 case GL_LUMINANCE16F_EXT:
1737 case GL_LUMINANCE_ALPHA16F_EXT:
1738 if (!context->getExtensions().textureHalfFloat)
1739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001740 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001741 return false;
1742 }
1743 break;
1744 case GL_R8_EXT:
1745 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001746 if (!context->getExtensions().textureRG)
1747 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001748 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001749 return false;
1750 }
1751 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001752 case GL_R16F_EXT:
1753 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001754 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1755 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001756 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001757 return false;
1758 }
1759 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001760 case GL_R32F_EXT:
1761 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001762 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001763 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001764 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001765 return false;
1766 }
1767 break;
1768 case GL_DEPTH_COMPONENT16:
1769 case GL_DEPTH_COMPONENT32_OES:
1770 case GL_DEPTH24_STENCIL8_OES:
1771 if (!context->getExtensions().depthTextures)
1772 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001773 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001774 return false;
1775 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001776 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001777 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001778 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001779 return false;
1780 }
1781 // ANGLE_depth_texture only supports 1-level textures
1782 if (levels != 1)
1783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001784 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001785 return false;
1786 }
1787 break;
1788 default:
1789 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001790 }
1791
Geoff Lang691e58c2014-12-19 17:03:25 -05001792 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001793 if (!texture || texture->id() == 0)
1794 {
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
Geoff Lang69cce582015-09-17 13:20:36 -04001799 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001800 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001801 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001802 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001803 }
1804
1805 return true;
1806}
1807
He Yunchaoced53ae2016-11-29 15:00:51 +08001808bool ValidateDiscardFramebufferEXT(Context *context,
1809 GLenum target,
1810 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001811 const GLenum *attachments)
1812{
Jamie Madillc29968b2016-01-20 11:17:23 -05001813 if (!context->getExtensions().discardFramebuffer)
1814 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001815 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001816 return false;
1817 }
1818
Austin Kinross08332632015-05-05 13:35:47 -07001819 bool defaultFramebuffer = false;
1820
1821 switch (target)
1822 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001823 case GL_FRAMEBUFFER:
1824 defaultFramebuffer =
1825 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1826 break;
1827 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001828 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001829 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001830 }
1831
He Yunchaoced53ae2016-11-29 15:00:51 +08001832 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1833 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001834}
1835
Austin Kinrossbc781f32015-10-26 09:27:38 -07001836bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1837{
1838 if (!context->getExtensions().vertexArrayObject)
1839 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001840 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001841 return false;
1842 }
1843
1844 return ValidateBindVertexArrayBase(context, array);
1845}
1846
Jamie Madilld7576732017-08-26 18:49:50 -04001847bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001848{
1849 if (!context->getExtensions().vertexArrayObject)
1850 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001851 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001852 return false;
1853 }
1854
Olli Etuaho41997e72016-03-10 13:38:39 +02001855 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001856}
1857
Jamie Madilld7576732017-08-26 18:49:50 -04001858bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001859{
1860 if (!context->getExtensions().vertexArrayObject)
1861 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001862 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001863 return false;
1864 }
1865
Olli Etuaho41997e72016-03-10 13:38:39 +02001866 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001867}
1868
Jamie Madilld7576732017-08-26 18:49:50 -04001869bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870{
1871 if (!context->getExtensions().vertexArrayObject)
1872 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001873 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001874 return false;
1875 }
1876
1877 return true;
1878}
Geoff Langc5629752015-12-07 16:29:04 -05001879
1880bool ValidateProgramBinaryOES(Context *context,
1881 GLuint program,
1882 GLenum binaryFormat,
1883 const void *binary,
1884 GLint length)
1885{
1886 if (!context->getExtensions().getProgramBinary)
1887 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001888 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001889 return false;
1890 }
1891
1892 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1893}
1894
1895bool ValidateGetProgramBinaryOES(Context *context,
1896 GLuint program,
1897 GLsizei bufSize,
1898 GLsizei *length,
1899 GLenum *binaryFormat,
1900 void *binary)
1901{
1902 if (!context->getExtensions().getProgramBinary)
1903 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001904 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001905 return false;
1906 }
1907
1908 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1909}
Geoff Lange102fee2015-12-10 11:23:30 -05001910
Geoff Lang70d0f492015-12-10 17:45:46 -05001911static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1912{
1913 switch (source)
1914 {
1915 case GL_DEBUG_SOURCE_API:
1916 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1917 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1918 case GL_DEBUG_SOURCE_OTHER:
1919 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1920 return !mustBeThirdPartyOrApplication;
1921
1922 case GL_DEBUG_SOURCE_THIRD_PARTY:
1923 case GL_DEBUG_SOURCE_APPLICATION:
1924 return true;
1925
1926 default:
1927 return false;
1928 }
1929}
1930
1931static bool ValidDebugType(GLenum type)
1932{
1933 switch (type)
1934 {
1935 case GL_DEBUG_TYPE_ERROR:
1936 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1937 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1938 case GL_DEBUG_TYPE_PERFORMANCE:
1939 case GL_DEBUG_TYPE_PORTABILITY:
1940 case GL_DEBUG_TYPE_OTHER:
1941 case GL_DEBUG_TYPE_MARKER:
1942 case GL_DEBUG_TYPE_PUSH_GROUP:
1943 case GL_DEBUG_TYPE_POP_GROUP:
1944 return true;
1945
1946 default:
1947 return false;
1948 }
1949}
1950
1951static bool ValidDebugSeverity(GLenum severity)
1952{
1953 switch (severity)
1954 {
1955 case GL_DEBUG_SEVERITY_HIGH:
1956 case GL_DEBUG_SEVERITY_MEDIUM:
1957 case GL_DEBUG_SEVERITY_LOW:
1958 case GL_DEBUG_SEVERITY_NOTIFICATION:
1959 return true;
1960
1961 default:
1962 return false;
1963 }
1964}
1965
Geoff Lange102fee2015-12-10 11:23:30 -05001966bool ValidateDebugMessageControlKHR(Context *context,
1967 GLenum source,
1968 GLenum type,
1969 GLenum severity,
1970 GLsizei count,
1971 const GLuint *ids,
1972 GLboolean enabled)
1973{
1974 if (!context->getExtensions().debug)
1975 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001976 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001977 return false;
1978 }
1979
Geoff Lang70d0f492015-12-10 17:45:46 -05001980 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1981 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001982 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001983 return false;
1984 }
1985
1986 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1987 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001988 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001989 return false;
1990 }
1991
1992 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1993 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001994 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001995 return false;
1996 }
1997
1998 if (count > 0)
1999 {
2000 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2001 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002002 context->handleError(
2003 InvalidOperation()
2004 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002005 return false;
2006 }
2007
2008 if (severity != GL_DONT_CARE)
2009 {
Jamie Madill437fa652016-05-03 15:13:24 -04002010 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002011 InvalidOperation()
2012 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002013 return false;
2014 }
2015 }
2016
Geoff Lange102fee2015-12-10 11:23:30 -05002017 return true;
2018}
2019
2020bool ValidateDebugMessageInsertKHR(Context *context,
2021 GLenum source,
2022 GLenum type,
2023 GLuint id,
2024 GLenum severity,
2025 GLsizei length,
2026 const GLchar *buf)
2027{
2028 if (!context->getExtensions().debug)
2029 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002030 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002031 return false;
2032 }
2033
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002034 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002035 {
2036 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2037 // not generate an error.
2038 return false;
2039 }
2040
2041 if (!ValidDebugSeverity(severity))
2042 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002043 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002044 return false;
2045 }
2046
2047 if (!ValidDebugType(type))
2048 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002049 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002050 return false;
2051 }
2052
2053 if (!ValidDebugSource(source, true))
2054 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002055 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002056 return false;
2057 }
2058
2059 size_t messageLength = (length < 0) ? strlen(buf) : length;
2060 if (messageLength > context->getExtensions().maxDebugMessageLength)
2061 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002062 context->handleError(InvalidValue()
2063 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002064 return false;
2065 }
2066
Geoff Lange102fee2015-12-10 11:23:30 -05002067 return true;
2068}
2069
2070bool ValidateDebugMessageCallbackKHR(Context *context,
2071 GLDEBUGPROCKHR callback,
2072 const void *userParam)
2073{
2074 if (!context->getExtensions().debug)
2075 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002076 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002077 return false;
2078 }
2079
Geoff Lange102fee2015-12-10 11:23:30 -05002080 return true;
2081}
2082
2083bool ValidateGetDebugMessageLogKHR(Context *context,
2084 GLuint count,
2085 GLsizei bufSize,
2086 GLenum *sources,
2087 GLenum *types,
2088 GLuint *ids,
2089 GLenum *severities,
2090 GLsizei *lengths,
2091 GLchar *messageLog)
2092{
2093 if (!context->getExtensions().debug)
2094 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002095 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002096 return false;
2097 }
2098
Geoff Lang70d0f492015-12-10 17:45:46 -05002099 if (bufSize < 0 && messageLog != nullptr)
2100 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002101 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002102 return false;
2103 }
2104
Geoff Lange102fee2015-12-10 11:23:30 -05002105 return true;
2106}
2107
2108bool ValidatePushDebugGroupKHR(Context *context,
2109 GLenum source,
2110 GLuint id,
2111 GLsizei length,
2112 const GLchar *message)
2113{
2114 if (!context->getExtensions().debug)
2115 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002116 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002117 return false;
2118 }
2119
Geoff Lang70d0f492015-12-10 17:45:46 -05002120 if (!ValidDebugSource(source, true))
2121 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002122 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002123 return false;
2124 }
2125
2126 size_t messageLength = (length < 0) ? strlen(message) : length;
2127 if (messageLength > context->getExtensions().maxDebugMessageLength)
2128 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002129 context->handleError(InvalidValue()
2130 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002131 return false;
2132 }
2133
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002134 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002135 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2136 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002137 context
2138 ->handleError(StackOverflow()
2139 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002140 return false;
2141 }
2142
Geoff Lange102fee2015-12-10 11:23:30 -05002143 return true;
2144}
2145
2146bool ValidatePopDebugGroupKHR(Context *context)
2147{
2148 if (!context->getExtensions().debug)
2149 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002150 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002151 return false;
2152 }
2153
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002154 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002155 if (currentStackSize <= 1)
2156 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002157 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002158 return false;
2159 }
2160
2161 return true;
2162}
2163
2164static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2165{
2166 switch (identifier)
2167 {
2168 case GL_BUFFER:
2169 if (context->getBuffer(name) == nullptr)
2170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002171 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002172 return false;
2173 }
2174 return true;
2175
2176 case GL_SHADER:
2177 if (context->getShader(name) == nullptr)
2178 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002179 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002180 return false;
2181 }
2182 return true;
2183
2184 case GL_PROGRAM:
2185 if (context->getProgram(name) == nullptr)
2186 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002187 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002188 return false;
2189 }
2190 return true;
2191
2192 case GL_VERTEX_ARRAY:
2193 if (context->getVertexArray(name) == nullptr)
2194 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002195 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002196 return false;
2197 }
2198 return true;
2199
2200 case GL_QUERY:
2201 if (context->getQuery(name) == nullptr)
2202 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002203 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002204 return false;
2205 }
2206 return true;
2207
2208 case GL_TRANSFORM_FEEDBACK:
2209 if (context->getTransformFeedback(name) == nullptr)
2210 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002211 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002212 return false;
2213 }
2214 return true;
2215
2216 case GL_SAMPLER:
2217 if (context->getSampler(name) == nullptr)
2218 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002219 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002220 return false;
2221 }
2222 return true;
2223
2224 case GL_TEXTURE:
2225 if (context->getTexture(name) == nullptr)
2226 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002227 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002228 return false;
2229 }
2230 return true;
2231
2232 case GL_RENDERBUFFER:
2233 if (context->getRenderbuffer(name) == nullptr)
2234 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002235 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002236 return false;
2237 }
2238 return true;
2239
2240 case GL_FRAMEBUFFER:
2241 if (context->getFramebuffer(name) == nullptr)
2242 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002243 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002244 return false;
2245 }
2246 return true;
2247
2248 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002249 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002250 return false;
2251 }
Geoff Lange102fee2015-12-10 11:23:30 -05002252}
2253
Martin Radev9d901792016-07-15 15:58:58 +03002254static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2255{
2256 size_t labelLength = 0;
2257
2258 if (length < 0)
2259 {
2260 if (label != nullptr)
2261 {
2262 labelLength = strlen(label);
2263 }
2264 }
2265 else
2266 {
2267 labelLength = static_cast<size_t>(length);
2268 }
2269
2270 if (labelLength > context->getExtensions().maxLabelLength)
2271 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002272 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002273 return false;
2274 }
2275
2276 return true;
2277}
2278
Geoff Lange102fee2015-12-10 11:23:30 -05002279bool ValidateObjectLabelKHR(Context *context,
2280 GLenum identifier,
2281 GLuint name,
2282 GLsizei length,
2283 const GLchar *label)
2284{
2285 if (!context->getExtensions().debug)
2286 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002287 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002288 return false;
2289 }
2290
Geoff Lang70d0f492015-12-10 17:45:46 -05002291 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2292 {
2293 return false;
2294 }
2295
Martin Radev9d901792016-07-15 15:58:58 +03002296 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002297 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002298 return false;
2299 }
2300
Geoff Lange102fee2015-12-10 11:23:30 -05002301 return true;
2302}
2303
2304bool ValidateGetObjectLabelKHR(Context *context,
2305 GLenum identifier,
2306 GLuint name,
2307 GLsizei bufSize,
2308 GLsizei *length,
2309 GLchar *label)
2310{
2311 if (!context->getExtensions().debug)
2312 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002313 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002314 return false;
2315 }
2316
Geoff Lang70d0f492015-12-10 17:45:46 -05002317 if (bufSize < 0)
2318 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002319 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002320 return false;
2321 }
2322
2323 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2324 {
2325 return false;
2326 }
2327
Martin Radev9d901792016-07-15 15:58:58 +03002328 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002329}
2330
2331static bool ValidateObjectPtrName(Context *context, const void *ptr)
2332{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002333 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002334 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002335 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002336 return false;
2337 }
2338
Geoff Lange102fee2015-12-10 11:23:30 -05002339 return true;
2340}
2341
2342bool ValidateObjectPtrLabelKHR(Context *context,
2343 const void *ptr,
2344 GLsizei length,
2345 const GLchar *label)
2346{
2347 if (!context->getExtensions().debug)
2348 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002349 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002350 return false;
2351 }
2352
Geoff Lang70d0f492015-12-10 17:45:46 -05002353 if (!ValidateObjectPtrName(context, ptr))
2354 {
2355 return false;
2356 }
2357
Martin Radev9d901792016-07-15 15:58:58 +03002358 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002359 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002360 return false;
2361 }
2362
Geoff Lange102fee2015-12-10 11:23:30 -05002363 return true;
2364}
2365
2366bool ValidateGetObjectPtrLabelKHR(Context *context,
2367 const void *ptr,
2368 GLsizei bufSize,
2369 GLsizei *length,
2370 GLchar *label)
2371{
2372 if (!context->getExtensions().debug)
2373 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002374 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002375 return false;
2376 }
2377
Geoff Lang70d0f492015-12-10 17:45:46 -05002378 if (bufSize < 0)
2379 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002380 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002381 return false;
2382 }
2383
2384 if (!ValidateObjectPtrName(context, ptr))
2385 {
2386 return false;
2387 }
2388
Martin Radev9d901792016-07-15 15:58:58 +03002389 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002390}
2391
2392bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2393{
2394 if (!context->getExtensions().debug)
2395 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002396 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002397 return false;
2398 }
2399
Geoff Lang70d0f492015-12-10 17:45:46 -05002400 // TODO: represent this in Context::getQueryParameterInfo.
2401 switch (pname)
2402 {
2403 case GL_DEBUG_CALLBACK_FUNCTION:
2404 case GL_DEBUG_CALLBACK_USER_PARAM:
2405 break;
2406
2407 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002408 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002409 return false;
2410 }
2411
Geoff Lange102fee2015-12-10 11:23:30 -05002412 return true;
2413}
Jamie Madillc29968b2016-01-20 11:17:23 -05002414
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002415bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2416 GLenum pname,
2417 GLsizei bufSize,
2418 GLsizei *length,
2419 void **params)
2420{
2421 UNIMPLEMENTED();
2422 return false;
2423}
2424
Jamie Madillc29968b2016-01-20 11:17:23 -05002425bool ValidateBlitFramebufferANGLE(Context *context,
2426 GLint srcX0,
2427 GLint srcY0,
2428 GLint srcX1,
2429 GLint srcY1,
2430 GLint dstX0,
2431 GLint dstY0,
2432 GLint dstX1,
2433 GLint dstY1,
2434 GLbitfield mask,
2435 GLenum filter)
2436{
2437 if (!context->getExtensions().framebufferBlit)
2438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002439 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002440 return false;
2441 }
2442
2443 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2444 {
2445 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002446 context->handleError(InvalidOperation() << "Scaling and flipping in "
2447 "BlitFramebufferANGLE not supported by this "
2448 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002449 return false;
2450 }
2451
2452 if (filter == GL_LINEAR)
2453 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002454 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002455 return false;
2456 }
2457
Jamie Madill51f40ec2016-06-15 14:06:00 -04002458 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2459 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002460
2461 if (mask & GL_COLOR_BUFFER_BIT)
2462 {
2463 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2464 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2465
2466 if (readColorAttachment && drawColorAttachment)
2467 {
2468 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002469 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002470 readColorAttachment->type() != GL_RENDERBUFFER &&
2471 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2472 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002473 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002474 return false;
2475 }
2476
Geoff Langa15472a2015-08-11 11:48:03 -04002477 for (size_t drawbufferIdx = 0;
2478 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002479 {
Geoff Langa15472a2015-08-11 11:48:03 -04002480 const FramebufferAttachment *attachment =
2481 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2482 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002484 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002485 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002486 attachment->type() != GL_RENDERBUFFER &&
2487 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2488 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002489 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002490 return false;
2491 }
2492
2493 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002494 if (!Format::EquivalentForBlit(attachment->getFormat(),
2495 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002496 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002497 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002498 return false;
2499 }
2500 }
2501 }
2502
Jamie Madill427064d2018-04-13 16:20:34 -04002503 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002504 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002505 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2506 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2507 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002508 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002509 return false;
2510 }
2511 }
2512 }
2513
2514 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2515 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2516 for (size_t i = 0; i < 2; i++)
2517 {
2518 if (mask & masks[i])
2519 {
2520 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002521 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002522 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002523 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002524
2525 if (readBuffer && drawBuffer)
2526 {
2527 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2528 dstX0, dstY0, dstX1, dstY1))
2529 {
2530 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002531 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2532 "stencil blits are supported by "
2533 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002534 return false;
2535 }
2536
2537 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2538 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002539 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002540 return false;
2541 }
2542 }
2543 }
2544 }
2545
2546 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2547 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002548}
Jamie Madillc29968b2016-01-20 11:17:23 -05002549
Jamie Madill5b772312018-03-08 20:28:32 -05002550bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002551{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002552 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002553
Jamie Madill427064d2018-04-13 16:20:34 -04002554 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002555 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002556 return false;
2557 }
2558
2559 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2560 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002561 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002562 return false;
2563 }
2564
Geoff Lang76e65652017-03-27 14:58:02 -04002565 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2566 {
2567 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2568 GL_SIGNED_NORMALIZED};
2569
Corentin Wallez59c41592017-07-11 13:19:54 -04002570 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002571 drawBufferIdx++)
2572 {
2573 if (!ValidateWebGLFramebufferAttachmentClearType(
2574 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2575 {
2576 return false;
2577 }
2578 }
2579 }
2580
Jamie Madillc29968b2016-01-20 11:17:23 -05002581 return true;
2582}
2583
Jamie Madill5b772312018-03-08 20:28:32 -05002584bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002585{
2586 if (!context->getExtensions().drawBuffers)
2587 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002588 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002589 return false;
2590 }
2591
2592 return ValidateDrawBuffersBase(context, n, bufs);
2593}
2594
Jamie Madill73a84962016-02-12 09:27:23 -05002595bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002596 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002597 GLint level,
2598 GLint internalformat,
2599 GLsizei width,
2600 GLsizei height,
2601 GLint border,
2602 GLenum format,
2603 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002604 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002605{
Martin Radev1be913c2016-07-11 17:59:16 +03002606 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002607 {
2608 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002609 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002610 }
2611
Martin Radev1be913c2016-07-11 17:59:16 +03002612 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002613 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002614 0, 0, width, height, 1, border, format, type, -1,
2615 pixels);
2616}
2617
Brandon Jones416aaf92018-04-10 08:10:16 -07002618bool ValidateTexImage2DRobustANGLE(Context *context,
2619 TextureTarget target,
2620 GLint level,
2621 GLint internalformat,
2622 GLsizei width,
2623 GLsizei height,
2624 GLint border,
2625 GLenum format,
2626 GLenum type,
2627 GLsizei bufSize,
2628 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002629{
2630 if (!ValidateRobustEntryPoint(context, bufSize))
2631 {
2632 return false;
2633 }
2634
2635 if (context->getClientMajorVersion() < 3)
2636 {
2637 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2638 0, 0, width, height, border, format, type, bufSize,
2639 pixels);
2640 }
2641
2642 ASSERT(context->getClientMajorVersion() >= 3);
2643 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2644 0, 0, width, height, 1, border, format, type, bufSize,
2645 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002646}
2647
2648bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002649 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002650 GLint level,
2651 GLint xoffset,
2652 GLint yoffset,
2653 GLsizei width,
2654 GLsizei height,
2655 GLenum format,
2656 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002657 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002658{
2659
Martin Radev1be913c2016-07-11 17:59:16 +03002660 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002661 {
2662 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002663 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002664 }
2665
Martin Radev1be913c2016-07-11 17:59:16 +03002666 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002667 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002668 yoffset, 0, width, height, 1, 0, format, type, -1,
2669 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002670}
2671
Geoff Langc52f6f12016-10-14 10:18:00 -04002672bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002673 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002674 GLint level,
2675 GLint xoffset,
2676 GLint yoffset,
2677 GLsizei width,
2678 GLsizei height,
2679 GLenum format,
2680 GLenum type,
2681 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002682 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002683{
2684 if (!ValidateRobustEntryPoint(context, bufSize))
2685 {
2686 return false;
2687 }
2688
2689 if (context->getClientMajorVersion() < 3)
2690 {
2691 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2692 yoffset, width, height, 0, format, type, bufSize,
2693 pixels);
2694 }
2695
2696 ASSERT(context->getClientMajorVersion() >= 3);
2697 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2698 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2699 pixels);
2700}
2701
Jamie Madill73a84962016-02-12 09:27:23 -05002702bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002703 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002704 GLint level,
2705 GLenum internalformat,
2706 GLsizei width,
2707 GLsizei height,
2708 GLint border,
2709 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002710 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002711{
Martin Radev1be913c2016-07-11 17:59:16 +03002712 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002713 {
2714 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002715 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002716 {
2717 return false;
2718 }
2719 }
2720 else
2721 {
Martin Radev1be913c2016-07-11 17:59:16 +03002722 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002723 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002724 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002725 data))
2726 {
2727 return false;
2728 }
2729 }
2730
Geoff Langca271392017-04-05 12:30:00 -04002731 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002732 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002733 if (blockSizeOrErr.isError())
2734 {
2735 context->handleError(blockSizeOrErr.getError());
2736 return false;
2737 }
2738
2739 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002740 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002741 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002742 return false;
2743 }
2744
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002745 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002746 {
2747 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2748 return false;
2749 }
2750
Jamie Madill73a84962016-02-12 09:27:23 -05002751 return true;
2752}
2753
Corentin Wallezb2931602017-04-11 15:58:57 -04002754bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002755 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002756 GLint level,
2757 GLenum internalformat,
2758 GLsizei width,
2759 GLsizei height,
2760 GLint border,
2761 GLsizei imageSize,
2762 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002763 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002764{
2765 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2766 {
2767 return false;
2768 }
2769
2770 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2771 border, imageSize, data);
2772}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002773
Corentin Wallezb2931602017-04-11 15:58:57 -04002774bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002775 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002776 GLint level,
2777 GLint xoffset,
2778 GLint yoffset,
2779 GLsizei width,
2780 GLsizei height,
2781 GLenum format,
2782 GLsizei imageSize,
2783 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002784 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002785{
2786 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2787 {
2788 return false;
2789 }
2790
2791 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2792 format, imageSize, data);
2793}
2794
Jamie Madill73a84962016-02-12 09:27:23 -05002795bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002796 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002797 GLint level,
2798 GLint xoffset,
2799 GLint yoffset,
2800 GLsizei width,
2801 GLsizei height,
2802 GLenum format,
2803 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002804 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002805{
Martin Radev1be913c2016-07-11 17:59:16 +03002806 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002807 {
2808 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002809 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002810 {
2811 return false;
2812 }
2813 }
2814 else
2815 {
Martin Radev1be913c2016-07-11 17:59:16 +03002816 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002817 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002818 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002819 data))
2820 {
2821 return false;
2822 }
2823 }
2824
Geoff Langca271392017-04-05 12:30:00 -04002825 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002826 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002827 if (blockSizeOrErr.isError())
2828 {
2829 context->handleError(blockSizeOrErr.getError());
2830 return false;
2831 }
2832
2833 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002834 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002835 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002836 return false;
2837 }
2838
2839 return true;
2840}
2841
Corentin Wallez336129f2017-10-17 15:55:40 -04002842bool ValidateGetBufferPointervOES(Context *context,
2843 BufferBinding target,
2844 GLenum pname,
2845 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002846{
Geoff Lang496c02d2016-10-20 11:38:11 -07002847 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002848}
2849
Corentin Wallez336129f2017-10-17 15:55:40 -04002850bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002851{
2852 if (!context->getExtensions().mapBuffer)
2853 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002854 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002855 return false;
2856 }
2857
Corentin Walleze4477002017-12-01 14:39:58 -05002858 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002859 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002860 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002861 return false;
2862 }
2863
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002864 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002865
2866 if (buffer == nullptr)
2867 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002868 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002869 return false;
2870 }
2871
2872 if (access != GL_WRITE_ONLY_OES)
2873 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002874 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002875 return false;
2876 }
2877
2878 if (buffer->isMapped())
2879 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002880 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002881 return false;
2882 }
2883
Geoff Lang79f71042017-08-14 16:43:43 -04002884 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002885}
2886
Corentin Wallez336129f2017-10-17 15:55:40 -04002887bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002888{
2889 if (!context->getExtensions().mapBuffer)
2890 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002891 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002892 return false;
2893 }
2894
2895 return ValidateUnmapBufferBase(context, target);
2896}
2897
2898bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002899 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002900 GLintptr offset,
2901 GLsizeiptr length,
2902 GLbitfield access)
2903{
2904 if (!context->getExtensions().mapBufferRange)
2905 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002906 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002907 return false;
2908 }
2909
2910 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2911}
2912
Corentin Wallez336129f2017-10-17 15:55:40 -04002913bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002914{
2915 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2916 ASSERT(buffer != nullptr);
2917
2918 // Check if this buffer is currently being used as a transform feedback output buffer
2919 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2920 if (transformFeedback != nullptr && transformFeedback->isActive())
2921 {
2922 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2923 {
2924 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2925 if (transformFeedbackBuffer.get() == buffer)
2926 {
2927 context->handleError(InvalidOperation()
2928 << "Buffer is currently bound for transform feedback.");
2929 return false;
2930 }
2931 }
2932 }
2933
James Darpiniane8a93c62018-01-04 18:02:24 -08002934 if (context->getExtensions().webglCompatibility &&
2935 buffer->isBoundForTransformFeedbackAndOtherUse())
2936 {
2937 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2938 return false;
2939 }
2940
Geoff Lang79f71042017-08-14 16:43:43 -04002941 return true;
2942}
2943
Olli Etuaho4f667482016-03-30 15:56:35 +03002944bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002945 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002946 GLintptr offset,
2947 GLsizeiptr length)
2948{
2949 if (!context->getExtensions().mapBufferRange)
2950 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002951 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002952 return false;
2953 }
2954
2955 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2956}
2957
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002958bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002959{
2960 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002961 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002962 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002963 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002964 return false;
2965 }
2966
Geoff Langf41a7152016-09-19 15:11:17 -04002967 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2968 !context->isTextureGenerated(texture))
2969 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002970 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002971 return false;
2972 }
2973
Ian Ewell54f87462016-03-10 13:47:21 -05002974 switch (target)
2975 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002976 case TextureType::_2D:
2977 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002978 break;
2979
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002980 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002981 if (!context->getExtensions().textureRectangle)
2982 {
2983 context->handleError(InvalidEnum()
2984 << "Context does not support GL_ANGLE_texture_rectangle");
2985 return false;
2986 }
2987 break;
2988
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002989 case TextureType::_3D:
2990 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002991 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002992 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002993 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002994 return false;
2995 }
2996 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002997
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002998 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04002999 if (context->getClientVersion() < Version(3, 1))
3000 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003001 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003002 return false;
3003 }
Geoff Lang3b573612016-10-31 14:08:10 -04003004 break;
3005
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003006 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003007 if (!context->getExtensions().eglImageExternal &&
3008 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003009 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003010 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003011 return false;
3012 }
3013 break;
3014 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003015 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003016 return false;
3017 }
3018
3019 return true;
3020}
3021
Geoff Langd8605522016-04-13 10:19:12 -04003022bool ValidateBindUniformLocationCHROMIUM(Context *context,
3023 GLuint program,
3024 GLint location,
3025 const GLchar *name)
3026{
3027 if (!context->getExtensions().bindUniformLocation)
3028 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003029 context->handleError(InvalidOperation()
3030 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003031 return false;
3032 }
3033
3034 Program *programObject = GetValidProgram(context, program);
3035 if (!programObject)
3036 {
3037 return false;
3038 }
3039
3040 if (location < 0)
3041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003042 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003043 return false;
3044 }
3045
3046 const Caps &caps = context->getCaps();
3047 if (static_cast<size_t>(location) >=
3048 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3049 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003050 context->handleError(InvalidValue() << "Location must be less than "
3051 "(MAX_VERTEX_UNIFORM_VECTORS + "
3052 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003053 return false;
3054 }
3055
Geoff Langfc32e8b2017-05-31 14:16:59 -04003056 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3057 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003058 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003059 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003060 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003061 return false;
3062 }
3063
Geoff Langd8605522016-04-13 10:19:12 -04003064 if (strncmp(name, "gl_", 3) == 0)
3065 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003066 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003067 return false;
3068 }
3069
3070 return true;
3071}
3072
Jamie Madille2e406c2016-06-02 13:04:10 -04003073bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003074{
3075 if (!context->getExtensions().framebufferMixedSamples)
3076 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003077 context->handleError(InvalidOperation()
3078 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003079 return false;
3080 }
3081 switch (components)
3082 {
3083 case GL_RGB:
3084 case GL_RGBA:
3085 case GL_ALPHA:
3086 case GL_NONE:
3087 break;
3088 default:
3089 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003090 InvalidEnum()
3091 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003092 return false;
3093 }
3094
3095 return true;
3096}
3097
Sami Väisänene45e53b2016-05-25 10:36:04 +03003098// CHROMIUM_path_rendering
3099
Jamie Madill007530e2017-12-28 14:27:04 -05003100bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003101{
Jamie Madill007530e2017-12-28 14:27:04 -05003102 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003103 {
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 if (matrix == nullptr)
3108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003109 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003110 return false;
3111 }
Jamie Madill007530e2017-12-28 14:27:04 -05003112
Sami Väisänene45e53b2016-05-25 10:36:04 +03003113 return true;
3114}
3115
Jamie Madill007530e2017-12-28 14:27:04 -05003116bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003117{
Jamie Madill007530e2017-12-28 14:27:04 -05003118 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003119}
3120
Jamie Madill007530e2017-12-28 14:27:04 -05003121bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003122{
3123 if (!context->getExtensions().pathRendering)
3124 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003125 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003126 return false;
3127 }
3128
3129 // range = 0 is undefined in NV_path_rendering.
3130 // we add stricter semantic check here and require a non zero positive range.
3131 if (range <= 0)
3132 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003133 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003134 return false;
3135 }
3136
3137 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3138 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003139 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003140 return false;
3141 }
3142
3143 return true;
3144}
3145
Jamie Madill007530e2017-12-28 14:27:04 -05003146bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003147{
3148 if (!context->getExtensions().pathRendering)
3149 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003150 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003151 return false;
3152 }
3153
3154 // range = 0 is undefined in NV_path_rendering.
3155 // we add stricter semantic check here and require a non zero positive range.
3156 if (range <= 0)
3157 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003158 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003159 return false;
3160 }
3161
3162 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3163 checkedRange += range;
3164
3165 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3166 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003167 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003168 return false;
3169 }
3170 return true;
3171}
3172
Jamie Madill007530e2017-12-28 14:27:04 -05003173bool ValidatePathCommandsCHROMIUM(Context *context,
3174 GLuint path,
3175 GLsizei numCommands,
3176 const GLubyte *commands,
3177 GLsizei numCoords,
3178 GLenum coordType,
3179 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003180{
3181 if (!context->getExtensions().pathRendering)
3182 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003183 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003184 return false;
3185 }
Brandon Jones59770802018-04-02 13:18:42 -07003186 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003187 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003188 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003189 return false;
3190 }
3191
3192 if (numCommands < 0)
3193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003194 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003195 return false;
3196 }
3197 else if (numCommands > 0)
3198 {
3199 if (!commands)
3200 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003201 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003202 return false;
3203 }
3204 }
3205
3206 if (numCoords < 0)
3207 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003208 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003209 return false;
3210 }
3211 else if (numCoords > 0)
3212 {
3213 if (!coords)
3214 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003215 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003216 return false;
3217 }
3218 }
3219
3220 std::uint32_t coordTypeSize = 0;
3221 switch (coordType)
3222 {
3223 case GL_BYTE:
3224 coordTypeSize = sizeof(GLbyte);
3225 break;
3226
3227 case GL_UNSIGNED_BYTE:
3228 coordTypeSize = sizeof(GLubyte);
3229 break;
3230
3231 case GL_SHORT:
3232 coordTypeSize = sizeof(GLshort);
3233 break;
3234
3235 case GL_UNSIGNED_SHORT:
3236 coordTypeSize = sizeof(GLushort);
3237 break;
3238
3239 case GL_FLOAT:
3240 coordTypeSize = sizeof(GLfloat);
3241 break;
3242
3243 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003244 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003245 return false;
3246 }
3247
3248 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3249 checkedSize += (coordTypeSize * numCoords);
3250 if (!checkedSize.IsValid())
3251 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003252 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003253 return false;
3254 }
3255
3256 // early return skips command data validation when it doesn't exist.
3257 if (!commands)
3258 return true;
3259
3260 GLsizei expectedNumCoords = 0;
3261 for (GLsizei i = 0; i < numCommands; ++i)
3262 {
3263 switch (commands[i])
3264 {
3265 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3266 break;
3267 case GL_MOVE_TO_CHROMIUM:
3268 case GL_LINE_TO_CHROMIUM:
3269 expectedNumCoords += 2;
3270 break;
3271 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3272 expectedNumCoords += 4;
3273 break;
3274 case GL_CUBIC_CURVE_TO_CHROMIUM:
3275 expectedNumCoords += 6;
3276 break;
3277 case GL_CONIC_CURVE_TO_CHROMIUM:
3278 expectedNumCoords += 5;
3279 break;
3280 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003281 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003282 return false;
3283 }
3284 }
3285 if (expectedNumCoords != numCoords)
3286 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003287 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003288 return false;
3289 }
3290
3291 return true;
3292}
3293
Jamie Madill007530e2017-12-28 14:27:04 -05003294bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003295{
3296 if (!context->getExtensions().pathRendering)
3297 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003298 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003299 return false;
3300 }
Brandon Jones59770802018-04-02 13:18:42 -07003301 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003302 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003303 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003304 return false;
3305 }
3306
3307 switch (pname)
3308 {
3309 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3310 if (value < 0.0f)
3311 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003312 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003313 return false;
3314 }
3315 break;
3316 case GL_PATH_END_CAPS_CHROMIUM:
3317 switch (static_cast<GLenum>(value))
3318 {
3319 case GL_FLAT_CHROMIUM:
3320 case GL_SQUARE_CHROMIUM:
3321 case GL_ROUND_CHROMIUM:
3322 break;
3323 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003324 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003325 return false;
3326 }
3327 break;
3328 case GL_PATH_JOIN_STYLE_CHROMIUM:
3329 switch (static_cast<GLenum>(value))
3330 {
3331 case GL_MITER_REVERT_CHROMIUM:
3332 case GL_BEVEL_CHROMIUM:
3333 case GL_ROUND_CHROMIUM:
3334 break;
3335 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003336 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003337 return false;
3338 }
Nico Weber41b072b2018-02-09 10:01:32 -05003339 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003340 case GL_PATH_MITER_LIMIT_CHROMIUM:
3341 if (value < 0.0f)
3342 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003343 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003344 return false;
3345 }
3346 break;
3347
3348 case GL_PATH_STROKE_BOUND_CHROMIUM:
3349 // no errors, only clamping.
3350 break;
3351
3352 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003353 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003354 return false;
3355 }
3356 return true;
3357}
3358
Jamie Madill007530e2017-12-28 14:27:04 -05003359bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3360{
3361 // TODO(jmadill): Use proper clamping cast.
3362 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3363}
3364
3365bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003366{
3367 if (!context->getExtensions().pathRendering)
3368 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003369 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003370 return false;
3371 }
3372
Brandon Jones59770802018-04-02 13:18:42 -07003373 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003374 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003375 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003376 return false;
3377 }
3378 if (!value)
3379 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003380 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003381 return false;
3382 }
3383
3384 switch (pname)
3385 {
3386 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3387 case GL_PATH_END_CAPS_CHROMIUM:
3388 case GL_PATH_JOIN_STYLE_CHROMIUM:
3389 case GL_PATH_MITER_LIMIT_CHROMIUM:
3390 case GL_PATH_STROKE_BOUND_CHROMIUM:
3391 break;
3392
3393 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003394 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003395 return false;
3396 }
3397
3398 return true;
3399}
3400
Jamie Madill007530e2017-12-28 14:27:04 -05003401bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3402{
3403 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3404 reinterpret_cast<GLfloat *>(value));
3405}
3406
3407bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003408{
3409 if (!context->getExtensions().pathRendering)
3410 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003411 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003412 return false;
3413 }
3414
3415 switch (func)
3416 {
3417 case GL_NEVER:
3418 case GL_ALWAYS:
3419 case GL_LESS:
3420 case GL_LEQUAL:
3421 case GL_EQUAL:
3422 case GL_GEQUAL:
3423 case GL_GREATER:
3424 case GL_NOTEQUAL:
3425 break;
3426 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003427 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003428 return false;
3429 }
3430
3431 return true;
3432}
3433
3434// Note that the spec specifies that for the path drawing commands
3435// if the path object is not an existing path object the command
3436// does nothing and no error is generated.
3437// However if the path object exists but has not been specified any
3438// commands then an error is generated.
3439
Jamie Madill007530e2017-12-28 14:27:04 -05003440bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003441{
3442 if (!context->getExtensions().pathRendering)
3443 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003444 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003445 return false;
3446 }
Brandon Jones59770802018-04-02 13:18:42 -07003447 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003448 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003449 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003450 return false;
3451 }
3452
3453 switch (fillMode)
3454 {
3455 case GL_COUNT_UP_CHROMIUM:
3456 case GL_COUNT_DOWN_CHROMIUM:
3457 break;
3458 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003459 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003460 return false;
3461 }
3462
3463 if (!isPow2(mask + 1))
3464 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003465 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003466 return false;
3467 }
3468
3469 return true;
3470}
3471
Jamie Madill007530e2017-12-28 14:27:04 -05003472bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003473{
3474 if (!context->getExtensions().pathRendering)
3475 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003476 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003477 return false;
3478 }
Brandon Jones59770802018-04-02 13:18:42 -07003479 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003480 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003481 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003482 return false;
3483 }
3484
3485 return true;
3486}
3487
Brandon Jonesd1049182018-03-28 10:02:20 -07003488bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3489{
3490 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3491}
3492
3493bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3494{
3495 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3496}
3497
Jamie Madill007530e2017-12-28 14:27:04 -05003498bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003499{
3500 if (!context->getExtensions().pathRendering)
3501 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003502 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003503 return false;
3504 }
Brandon Jones59770802018-04-02 13:18:42 -07003505 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003506 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003508 return false;
3509 }
3510
3511 switch (coverMode)
3512 {
3513 case GL_CONVEX_HULL_CHROMIUM:
3514 case GL_BOUNDING_BOX_CHROMIUM:
3515 break;
3516 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003517 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003518 return false;
3519 }
3520 return true;
3521}
3522
Jamie Madill007530e2017-12-28 14:27:04 -05003523bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3524 GLuint path,
3525 GLenum fillMode,
3526 GLuint mask,
3527 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003528{
Jamie Madill007530e2017-12-28 14:27:04 -05003529 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3530 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003531}
3532
Jamie Madill007530e2017-12-28 14:27:04 -05003533bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3534 GLuint path,
3535 GLint reference,
3536 GLuint mask,
3537 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003538{
Jamie Madill007530e2017-12-28 14:27:04 -05003539 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3540 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003541}
3542
Brandon Jonesd1049182018-03-28 10:02:20 -07003543bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003544{
3545 if (!context->getExtensions().pathRendering)
3546 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003547 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003548 return false;
3549 }
3550 return true;
3551}
3552
Jamie Madill007530e2017-12-28 14:27:04 -05003553bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3554 GLsizei numPaths,
3555 GLenum pathNameType,
3556 const void *paths,
3557 GLuint pathBase,
3558 GLenum coverMode,
3559 GLenum transformType,
3560 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003561{
3562 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3563 transformType, transformValues))
3564 return false;
3565
3566 switch (coverMode)
3567 {
3568 case GL_CONVEX_HULL_CHROMIUM:
3569 case GL_BOUNDING_BOX_CHROMIUM:
3570 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3571 break;
3572 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003573 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003574 return false;
3575 }
3576
3577 return true;
3578}
3579
Jamie Madill007530e2017-12-28 14:27:04 -05003580bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3581 GLsizei numPaths,
3582 GLenum pathNameType,
3583 const void *paths,
3584 GLuint pathBase,
3585 GLenum coverMode,
3586 GLenum transformType,
3587 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003588{
3589 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3590 transformType, transformValues))
3591 return false;
3592
3593 switch (coverMode)
3594 {
3595 case GL_CONVEX_HULL_CHROMIUM:
3596 case GL_BOUNDING_BOX_CHROMIUM:
3597 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3598 break;
3599 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003600 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003601 return false;
3602 }
3603
3604 return true;
3605}
3606
Jamie Madill007530e2017-12-28 14:27:04 -05003607bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3608 GLsizei numPaths,
3609 GLenum pathNameType,
3610 const void *paths,
3611 GLuint pathBase,
3612 GLenum fillMode,
3613 GLuint mask,
3614 GLenum transformType,
3615 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003616{
3617
3618 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3619 transformType, transformValues))
3620 return false;
3621
3622 switch (fillMode)
3623 {
3624 case GL_COUNT_UP_CHROMIUM:
3625 case GL_COUNT_DOWN_CHROMIUM:
3626 break;
3627 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003628 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003629 return false;
3630 }
3631 if (!isPow2(mask + 1))
3632 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003633 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003634 return false;
3635 }
3636 return true;
3637}
3638
Jamie Madill007530e2017-12-28 14:27:04 -05003639bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3640 GLsizei numPaths,
3641 GLenum pathNameType,
3642 const void *paths,
3643 GLuint pathBase,
3644 GLint reference,
3645 GLuint mask,
3646 GLenum transformType,
3647 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003648{
3649 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3650 transformType, transformValues))
3651 return false;
3652
3653 // no more validation here.
3654
3655 return true;
3656}
3657
Jamie Madill007530e2017-12-28 14:27:04 -05003658bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3659 GLsizei numPaths,
3660 GLenum pathNameType,
3661 const void *paths,
3662 GLuint pathBase,
3663 GLenum fillMode,
3664 GLuint mask,
3665 GLenum coverMode,
3666 GLenum transformType,
3667 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003668{
3669 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3670 transformType, transformValues))
3671 return false;
3672
3673 switch (coverMode)
3674 {
3675 case GL_CONVEX_HULL_CHROMIUM:
3676 case GL_BOUNDING_BOX_CHROMIUM:
3677 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3678 break;
3679 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003680 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003681 return false;
3682 }
3683
3684 switch (fillMode)
3685 {
3686 case GL_COUNT_UP_CHROMIUM:
3687 case GL_COUNT_DOWN_CHROMIUM:
3688 break;
3689 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003690 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003691 return false;
3692 }
3693 if (!isPow2(mask + 1))
3694 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003695 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003696 return false;
3697 }
3698
3699 return true;
3700}
3701
Jamie Madill007530e2017-12-28 14:27:04 -05003702bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3703 GLsizei numPaths,
3704 GLenum pathNameType,
3705 const void *paths,
3706 GLuint pathBase,
3707 GLint reference,
3708 GLuint mask,
3709 GLenum coverMode,
3710 GLenum transformType,
3711 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003712{
3713 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3714 transformType, transformValues))
3715 return false;
3716
3717 switch (coverMode)
3718 {
3719 case GL_CONVEX_HULL_CHROMIUM:
3720 case GL_BOUNDING_BOX_CHROMIUM:
3721 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3722 break;
3723 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003724 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003725 return false;
3726 }
3727
3728 return true;
3729}
3730
Jamie Madill007530e2017-12-28 14:27:04 -05003731bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3732 GLuint program,
3733 GLint location,
3734 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003735{
3736 if (!context->getExtensions().pathRendering)
3737 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003738 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003739 return false;
3740 }
3741
3742 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3743 if (location >= MaxLocation)
3744 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003745 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003746 return false;
3747 }
3748
3749 const auto *programObject = context->getProgram(program);
3750 if (!programObject)
3751 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003752 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003753 return false;
3754 }
3755
3756 if (!name)
3757 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003758 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003759 return false;
3760 }
3761
3762 if (angle::BeginsWith(name, "gl_"))
3763 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003764 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003765 return false;
3766 }
3767
3768 return true;
3769}
3770
Jamie Madill007530e2017-12-28 14:27:04 -05003771bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3772 GLuint program,
3773 GLint location,
3774 GLenum genMode,
3775 GLint components,
3776 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003777{
3778 if (!context->getExtensions().pathRendering)
3779 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003780 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003781 return false;
3782 }
3783
3784 const auto *programObject = context->getProgram(program);
3785 if (!programObject || programObject->isFlaggedForDeletion())
3786 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003787 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003788 return false;
3789 }
3790
3791 if (!programObject->isLinked())
3792 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003793 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003794 return false;
3795 }
3796
3797 switch (genMode)
3798 {
3799 case GL_NONE:
3800 if (components != 0)
3801 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003802 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003803 return false;
3804 }
3805 break;
3806
3807 case GL_OBJECT_LINEAR_CHROMIUM:
3808 case GL_EYE_LINEAR_CHROMIUM:
3809 case GL_CONSTANT_CHROMIUM:
3810 if (components < 1 || components > 4)
3811 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003812 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003813 return false;
3814 }
3815 if (!coeffs)
3816 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003817 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003818 return false;
3819 }
3820 break;
3821
3822 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003823 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003824 return false;
3825 }
3826
3827 // If the location is -1 then the command is silently ignored
3828 // and no further validation is needed.
3829 if (location == -1)
3830 return true;
3831
Jamie Madillbd044ed2017-06-05 12:59:21 -04003832 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003833
3834 if (!binding.valid)
3835 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003836 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003837 return false;
3838 }
3839
3840 if (binding.type != GL_NONE)
3841 {
3842 GLint expectedComponents = 0;
3843 switch (binding.type)
3844 {
3845 case GL_FLOAT:
3846 expectedComponents = 1;
3847 break;
3848 case GL_FLOAT_VEC2:
3849 expectedComponents = 2;
3850 break;
3851 case GL_FLOAT_VEC3:
3852 expectedComponents = 3;
3853 break;
3854 case GL_FLOAT_VEC4:
3855 expectedComponents = 4;
3856 break;
3857 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003858 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003859 InvalidOperation()
3860 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003861 return false;
3862 }
3863 if (expectedComponents != components && genMode != GL_NONE)
3864 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003865 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003866 return false;
3867 }
3868 }
3869 return true;
3870}
3871
Geoff Lang97073d12016-04-20 10:42:34 -07003872bool ValidateCopyTextureCHROMIUM(Context *context,
3873 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003874 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003875 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003876 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003877 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003878 GLint internalFormat,
3879 GLenum destType,
3880 GLboolean unpackFlipY,
3881 GLboolean unpackPremultiplyAlpha,
3882 GLboolean unpackUnmultiplyAlpha)
3883{
3884 if (!context->getExtensions().copyTexture)
3885 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003886 context->handleError(InvalidOperation()
3887 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003888 return false;
3889 }
3890
Geoff Lang4f0e0032017-05-01 16:04:35 -04003891 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003892 if (source == nullptr)
3893 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003894 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003895 return false;
3896 }
3897
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003898 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003899 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003900 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003901 return false;
3902 }
3903
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003904 TextureType sourceType = source->getType();
3905 ASSERT(sourceType != TextureType::CubeMap);
3906 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003907
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003908 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003909 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003910 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003911 return false;
3912 }
3913
Geoff Lang4f0e0032017-05-01 16:04:35 -04003914 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3915 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3916 if (sourceWidth == 0 || sourceHeight == 0)
3917 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003918 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003919 return false;
3920 }
3921
3922 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3923 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003924 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003925 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003926 return false;
3927 }
3928
Geoff Lang63458a32017-10-30 15:16:53 -04003929 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3930 {
3931 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3932 return false;
3933 }
3934
Geoff Lang4f0e0032017-05-01 16:04:35 -04003935 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003936 if (dest == nullptr)
3937 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003938 context->handleError(InvalidValue()
3939 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003940 return false;
3941 }
3942
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003943 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003944 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003945 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003946 return false;
3947 }
3948
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003949 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003950 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003951 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003952 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003953 return false;
3954 }
3955
Geoff Lang97073d12016-04-20 10:42:34 -07003956 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3957 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003958 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003959 return false;
3960 }
3961
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003962 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003963 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003964 context->handleError(
3965 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003966 return false;
3967 }
3968
Geoff Lang97073d12016-04-20 10:42:34 -07003969 if (dest->getImmutableFormat())
3970 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003971 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003972 return false;
3973 }
3974
3975 return true;
3976}
3977
3978bool ValidateCopySubTextureCHROMIUM(Context *context,
3979 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003980 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003981 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003982 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003983 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003984 GLint xoffset,
3985 GLint yoffset,
3986 GLint x,
3987 GLint y,
3988 GLsizei width,
3989 GLsizei height,
3990 GLboolean unpackFlipY,
3991 GLboolean unpackPremultiplyAlpha,
3992 GLboolean unpackUnmultiplyAlpha)
3993{
3994 if (!context->getExtensions().copyTexture)
3995 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003996 context->handleError(InvalidOperation()
3997 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003998 return false;
3999 }
4000
Geoff Lang4f0e0032017-05-01 16:04:35 -04004001 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004002 if (source == nullptr)
4003 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004004 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004005 return false;
4006 }
4007
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004008 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004009 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004010 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004011 return false;
4012 }
4013
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004014 TextureType sourceType = source->getType();
4015 ASSERT(sourceType != TextureType::CubeMap);
4016 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004017
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004018 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004019 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004020 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004021 return false;
4022 }
4023
4024 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4025 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004026 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004027 context->handleError(InvalidValue()
4028 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004029 return false;
4030 }
4031
4032 if (x < 0 || y < 0)
4033 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004034 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004035 return false;
4036 }
4037
4038 if (width < 0 || height < 0)
4039 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004040 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004041 return false;
4042 }
4043
Geoff Lang4f0e0032017-05-01 16:04:35 -04004044 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4045 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004046 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004047 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004048 return false;
4049 }
4050
Geoff Lang4f0e0032017-05-01 16:04:35 -04004051 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4052 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004053 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004054 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004055 return false;
4056 }
4057
Geoff Lang63458a32017-10-30 15:16:53 -04004058 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4059 {
4060 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4061 return false;
4062 }
4063
Geoff Lang4f0e0032017-05-01 16:04:35 -04004064 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004065 if (dest == nullptr)
4066 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004067 context->handleError(InvalidValue()
4068 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004069 return false;
4070 }
4071
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004072 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004073 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004074 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004075 return false;
4076 }
4077
Brandon Jones28783792018-03-05 09:37:32 -08004078 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4079 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004080 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004081 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004082 return false;
4083 }
4084
Geoff Lang4f0e0032017-05-01 16:04:35 -04004085 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4086 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004087 context
4088 ->handleError(InvalidOperation()
4089 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004090 return false;
4091 }
4092
4093 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4094 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004095 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004096 context->handleError(InvalidOperation()
4097 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004098 return false;
4099 }
4100
4101 if (xoffset < 0 || yoffset < 0)
4102 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004103 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004104 return false;
4105 }
4106
Geoff Lang4f0e0032017-05-01 16:04:35 -04004107 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4108 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004109 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004110 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004111 return false;
4112 }
4113
4114 return true;
4115}
4116
Geoff Lang47110bf2016-04-20 11:13:22 -07004117bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4118{
4119 if (!context->getExtensions().copyCompressedTexture)
4120 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004121 context->handleError(InvalidOperation()
4122 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004123 return false;
4124 }
4125
4126 const gl::Texture *source = context->getTexture(sourceId);
4127 if (source == nullptr)
4128 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004129 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004130 return false;
4131 }
4132
Corentin Wallez99d492c2018-02-27 15:17:10 -05004133 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004135 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004136 return false;
4137 }
4138
Corentin Wallez99d492c2018-02-27 15:17:10 -05004139 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4140 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004141 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004142 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004143 return false;
4144 }
4145
Corentin Wallez99d492c2018-02-27 15:17:10 -05004146 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004147 if (!sourceFormat.info->compressed)
4148 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004149 context->handleError(InvalidOperation()
4150 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004151 return false;
4152 }
4153
4154 const gl::Texture *dest = context->getTexture(destId);
4155 if (dest == nullptr)
4156 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004157 context->handleError(InvalidValue()
4158 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004159 return false;
4160 }
4161
Corentin Wallez99d492c2018-02-27 15:17:10 -05004162 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004164 context->handleError(InvalidValue()
4165 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004166 return false;
4167 }
4168
4169 if (dest->getImmutableFormat())
4170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004171 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004172 return false;
4173 }
4174
4175 return true;
4176}
4177
Jiawei Shao385b3e02018-03-21 09:43:28 +08004178bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004179{
4180 switch (type)
4181 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004182 case ShaderType::Vertex:
4183 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004184 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004185
Jiawei Shao385b3e02018-03-21 09:43:28 +08004186 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004187 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004188 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004189 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004190 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004191 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004192 break;
4193
Jiawei Shao385b3e02018-03-21 09:43:28 +08004194 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004195 if (!context->getExtensions().geometryShader)
4196 {
4197 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4198 return false;
4199 }
4200 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004201 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004202 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004203 return false;
4204 }
Jamie Madill29639852016-09-02 15:00:09 -04004205
4206 return true;
4207}
4208
Jamie Madill5b772312018-03-08 20:28:32 -05004209bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004210 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004211 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004212 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004213 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004214{
4215 if (size < 0)
4216 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004217 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004218 return false;
4219 }
4220
4221 switch (usage)
4222 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004223 case BufferUsage::StreamDraw:
4224 case BufferUsage::StaticDraw:
4225 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004226 break;
4227
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004228 case BufferUsage::StreamRead:
4229 case BufferUsage::StaticRead:
4230 case BufferUsage::DynamicRead:
4231 case BufferUsage::StreamCopy:
4232 case BufferUsage::StaticCopy:
4233 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004234 if (context->getClientMajorVersion() < 3)
4235 {
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 break;
4240
4241 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004242 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004243 return false;
4244 }
4245
Corentin Walleze4477002017-12-01 14:39:58 -05004246 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004247 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004248 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004249 return false;
4250 }
4251
4252 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4253
4254 if (!buffer)
4255 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004256 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004257 return false;
4258 }
4259
James Darpiniane8a93c62018-01-04 18:02:24 -08004260 if (context->getExtensions().webglCompatibility &&
4261 buffer->isBoundForTransformFeedbackAndOtherUse())
4262 {
4263 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4264 return false;
4265 }
4266
Jamie Madill29639852016-09-02 15:00:09 -04004267 return true;
4268}
4269
Jamie Madill5b772312018-03-08 20:28:32 -05004270bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004271 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004272 GLintptr offset,
4273 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004274 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004275{
Brandon Jones6cad5662017-06-14 13:25:13 -07004276 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004277 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004278 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4279 return false;
4280 }
4281
4282 if (offset < 0)
4283 {
4284 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004285 return false;
4286 }
4287
Corentin Walleze4477002017-12-01 14:39:58 -05004288 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004289 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004290 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004291 return false;
4292 }
4293
4294 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4295
4296 if (!buffer)
4297 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004298 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004299 return false;
4300 }
4301
4302 if (buffer->isMapped())
4303 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004304 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004305 return false;
4306 }
4307
James Darpiniane8a93c62018-01-04 18:02:24 -08004308 if (context->getExtensions().webglCompatibility &&
4309 buffer->isBoundForTransformFeedbackAndOtherUse())
4310 {
4311 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4312 return false;
4313 }
4314
Jamie Madill29639852016-09-02 15:00:09 -04004315 // Check for possible overflow of size + offset
4316 angle::CheckedNumeric<size_t> checkedSize(size);
4317 checkedSize += offset;
4318 if (!checkedSize.IsValid())
4319 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004320 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004321 return false;
4322 }
4323
4324 if (size + offset > buffer->getSize())
4325 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004326 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004327 return false;
4328 }
4329
Martin Radev4c4c8e72016-08-04 12:25:34 +03004330 return true;
4331}
4332
Geoff Lang111a99e2017-10-17 10:58:41 -04004333bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004334{
Geoff Langc339c4e2016-11-29 10:37:36 -05004335 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004336 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004337 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004338 return false;
4339 }
4340
Geoff Lang111a99e2017-10-17 10:58:41 -04004341 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004342 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004343 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004344 return false;
4345 }
4346
4347 return true;
4348}
4349
Jamie Madill5b772312018-03-08 20:28:32 -05004350bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004351{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004352 if (context->getClientMajorVersion() < 2)
4353 {
4354 return ValidateMultitextureUnit(context, texture);
4355 }
4356
Jamie Madillef300b12016-10-07 15:12:09 -04004357 if (texture < GL_TEXTURE0 ||
4358 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4359 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004360 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004361 return false;
4362 }
4363
4364 return true;
4365}
4366
Jamie Madill5b772312018-03-08 20:28:32 -05004367bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004368{
4369 Program *programObject = GetValidProgram(context, program);
4370 if (!programObject)
4371 {
4372 return false;
4373 }
4374
4375 Shader *shaderObject = GetValidShader(context, shader);
4376 if (!shaderObject)
4377 {
4378 return false;
4379 }
4380
Jiawei Shao385b3e02018-03-21 09:43:28 +08004381 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004382 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004383 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4384 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004385 }
4386
4387 return true;
4388}
4389
Jamie Madill5b772312018-03-08 20:28:32 -05004390bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004391{
4392 if (index >= MAX_VERTEX_ATTRIBS)
4393 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004394 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004395 return false;
4396 }
4397
4398 if (strncmp(name, "gl_", 3) == 0)
4399 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004401 return false;
4402 }
4403
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004404 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004405 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004406 const size_t length = strlen(name);
4407
4408 if (!IsValidESSLString(name, length))
4409 {
4410 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4411 // for shader-related entry points
4412 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4413 return false;
4414 }
4415
4416 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4417 {
4418 return false;
4419 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004420 }
4421
Jamie Madill01a80ee2016-11-07 12:06:18 -05004422 return GetValidProgram(context, program) != nullptr;
4423}
4424
Jamie Madill5b772312018-03-08 20:28:32 -05004425bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004426{
Corentin Walleze4477002017-12-01 14:39:58 -05004427 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004428 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004429 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004430 return false;
4431 }
4432
4433 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4434 !context->isBufferGenerated(buffer))
4435 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004436 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004437 return false;
4438 }
4439
4440 return true;
4441}
4442
Jamie Madill5b772312018-03-08 20:28:32 -05004443bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444{
Geoff Lange8afa902017-09-27 15:00:43 -04004445 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004446 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004447 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004448 return false;
4449 }
4450
4451 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4452 !context->isFramebufferGenerated(framebuffer))
4453 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004454 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004455 return false;
4456 }
4457
4458 return true;
4459}
4460
Jamie Madill5b772312018-03-08 20:28:32 -05004461bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004462{
4463 if (target != GL_RENDERBUFFER)
4464 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004465 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004466 return false;
4467 }
4468
4469 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4470 !context->isRenderbufferGenerated(renderbuffer))
4471 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004472 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004473 return false;
4474 }
4475
4476 return true;
4477}
4478
Jamie Madill5b772312018-03-08 20:28:32 -05004479static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004480{
4481 switch (mode)
4482 {
4483 case GL_FUNC_ADD:
4484 case GL_FUNC_SUBTRACT:
4485 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004486 return true;
4487
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004488 case GL_MIN:
4489 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004490 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004491
4492 default:
4493 return false;
4494 }
4495}
4496
Jamie Madill5b772312018-03-08 20:28:32 -05004497bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004498{
4499 return true;
4500}
4501
Jamie Madill5b772312018-03-08 20:28:32 -05004502bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004503{
Geoff Lang50cac572017-09-26 17:37:43 -04004504 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004505 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004506 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004507 return false;
4508 }
4509
4510 return true;
4511}
4512
Jamie Madill5b772312018-03-08 20:28:32 -05004513bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004514{
Geoff Lang50cac572017-09-26 17:37:43 -04004515 if (!ValidBlendEquationMode(context, modeRGB))
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
Geoff Lang50cac572017-09-26 17:37:43 -04004521 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004522 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004523 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004524 return false;
4525 }
4526
4527 return true;
4528}
4529
Jamie Madill5b772312018-03-08 20:28:32 -05004530bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004531{
4532 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4533}
4534
4535static bool ValidSrcBlendFunc(GLenum srcBlend)
4536{
4537 switch (srcBlend)
4538 {
4539 case GL_ZERO:
4540 case GL_ONE:
4541 case GL_SRC_COLOR:
4542 case GL_ONE_MINUS_SRC_COLOR:
4543 case GL_DST_COLOR:
4544 case GL_ONE_MINUS_DST_COLOR:
4545 case GL_SRC_ALPHA:
4546 case GL_ONE_MINUS_SRC_ALPHA:
4547 case GL_DST_ALPHA:
4548 case GL_ONE_MINUS_DST_ALPHA:
4549 case GL_CONSTANT_COLOR:
4550 case GL_ONE_MINUS_CONSTANT_COLOR:
4551 case GL_CONSTANT_ALPHA:
4552 case GL_ONE_MINUS_CONSTANT_ALPHA:
4553 case GL_SRC_ALPHA_SATURATE:
4554 return true;
4555
4556 default:
4557 return false;
4558 }
4559}
4560
4561static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4562{
4563 switch (dstBlend)
4564 {
4565 case GL_ZERO:
4566 case GL_ONE:
4567 case GL_SRC_COLOR:
4568 case GL_ONE_MINUS_SRC_COLOR:
4569 case GL_DST_COLOR:
4570 case GL_ONE_MINUS_DST_COLOR:
4571 case GL_SRC_ALPHA:
4572 case GL_ONE_MINUS_SRC_ALPHA:
4573 case GL_DST_ALPHA:
4574 case GL_ONE_MINUS_DST_ALPHA:
4575 case GL_CONSTANT_COLOR:
4576 case GL_ONE_MINUS_CONSTANT_COLOR:
4577 case GL_CONSTANT_ALPHA:
4578 case GL_ONE_MINUS_CONSTANT_ALPHA:
4579 return true;
4580
4581 case GL_SRC_ALPHA_SATURATE:
4582 return (contextMajorVersion >= 3);
4583
4584 default:
4585 return false;
4586 }
4587}
4588
Jamie Madill5b772312018-03-08 20:28:32 -05004589bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004590 GLenum srcRGB,
4591 GLenum dstRGB,
4592 GLenum srcAlpha,
4593 GLenum dstAlpha)
4594{
4595 if (!ValidSrcBlendFunc(srcRGB))
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 (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
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 (!ValidSrcBlendFunc(srcAlpha))
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
4613 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4614 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004615 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004616 return false;
4617 }
4618
Frank Henigman146e8a12017-03-02 23:22:37 -05004619 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4620 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004621 {
4622 bool constantColorUsed =
4623 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4624 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4625
4626 bool constantAlphaUsed =
4627 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4628 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4629
4630 if (constantColorUsed && constantAlphaUsed)
4631 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004632 const char *msg;
4633 if (context->getExtensions().webglCompatibility)
4634 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004635 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004636 }
4637 else
4638 {
4639 msg =
4640 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4641 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4642 "implementation.";
4643 ERR() << msg;
4644 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004645 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004646 return false;
4647 }
4648 }
4649
4650 return true;
4651}
4652
Geoff Langc339c4e2016-11-29 10:37:36 -05004653bool ValidateGetString(Context *context, GLenum name)
4654{
4655 switch (name)
4656 {
4657 case GL_VENDOR:
4658 case GL_RENDERER:
4659 case GL_VERSION:
4660 case GL_SHADING_LANGUAGE_VERSION:
4661 case GL_EXTENSIONS:
4662 break;
4663
4664 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4665 if (!context->getExtensions().requestExtension)
4666 {
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 break;
4671
4672 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004673 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004674 return false;
4675 }
4676
4677 return true;
4678}
4679
Jamie Madill5b772312018-03-08 20:28:32 -05004680bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004681{
4682 if (width <= 0.0f || isNaN(width))
4683 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004684 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004685 return false;
4686 }
4687
4688 return true;
4689}
4690
Jamie Madill5b772312018-03-08 20:28:32 -05004691bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004692 GLuint index,
4693 GLint size,
4694 GLenum type,
4695 GLboolean normalized,
4696 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004697 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004698{
Shao80957d92017-02-20 21:25:59 +08004699 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004700 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004701 return false;
4702 }
4703
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004704 if (stride < 0)
4705 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004706 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004707 return false;
4708 }
4709
Shao80957d92017-02-20 21:25:59 +08004710 const Caps &caps = context->getCaps();
4711 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004712 {
Shao80957d92017-02-20 21:25:59 +08004713 if (stride > caps.maxVertexAttribStride)
4714 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004715 context->handleError(InvalidValue()
4716 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004717 return false;
4718 }
4719
4720 if (index >= caps.maxVertexAttribBindings)
4721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004722 context->handleError(InvalidValue()
4723 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004724 return false;
4725 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004726 }
4727
4728 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4729 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4730 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4731 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004732 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4733 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004734 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4735 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004736 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004737 context
4738 ->handleError(InvalidOperation()
4739 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004740 return false;
4741 }
4742
4743 if (context->getExtensions().webglCompatibility)
4744 {
4745 // WebGL 1.0 [Section 6.14] Fixed point support
4746 // The WebGL API does not support the GL_FIXED data type.
4747 if (type == GL_FIXED)
4748 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004749 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004750 return false;
4751 }
4752
Geoff Lang2d62ab72017-03-23 16:54:40 -04004753 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004754 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004755 return false;
4756 }
4757 }
4758
4759 return true;
4760}
4761
Jamie Madill5b772312018-03-08 20:28:32 -05004762bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004763{
4764 if (context->getExtensions().webglCompatibility && zNear > zFar)
4765 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004766 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004767 return false;
4768 }
4769
4770 return true;
4771}
4772
Jamie Madill5b772312018-03-08 20:28:32 -05004773bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004774 GLenum target,
4775 GLenum internalformat,
4776 GLsizei width,
4777 GLsizei height)
4778{
4779 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4780 height);
4781}
4782
Jamie Madill5b772312018-03-08 20:28:32 -05004783bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004784 GLenum target,
4785 GLsizei samples,
4786 GLenum internalformat,
4787 GLsizei width,
4788 GLsizei height)
4789{
4790 if (!context->getExtensions().framebufferMultisample)
4791 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004792 context->handleError(InvalidOperation()
4793 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004794 return false;
4795 }
4796
4797 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4798 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4799 // generated.
4800 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4801 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004802 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004803 return false;
4804 }
4805
4806 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4807 // the specified storage. This is different than ES 3.0 in which a sample number higher
4808 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4809 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4810 if (context->getClientMajorVersion() >= 3)
4811 {
4812 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4813 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4814 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004815 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004816 return false;
4817 }
4818 }
4819
4820 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4821 width, height);
4822}
4823
Jamie Madill5b772312018-03-08 20:28:32 -05004824bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004825{
Geoff Lange8afa902017-09-27 15:00:43 -04004826 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004827 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004828 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004829 return false;
4830 }
4831
4832 return true;
4833}
4834
Jamie Madill5b772312018-03-08 20:28:32 -05004835bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004836{
4837 return true;
4838}
4839
Jamie Madill5b772312018-03-08 20:28:32 -05004840bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004841{
4842 return true;
4843}
4844
Jamie Madill5b772312018-03-08 20:28:32 -05004845bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004846{
4847 return true;
4848}
4849
Jamie Madill5b772312018-03-08 20:28:32 -05004850bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004851 GLboolean red,
4852 GLboolean green,
4853 GLboolean blue,
4854 GLboolean alpha)
4855{
4856 return true;
4857}
4858
Jamie Madill5b772312018-03-08 20:28:32 -05004859bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004860{
4861 return true;
4862}
4863
Jamie Madill5b772312018-03-08 20:28:32 -05004864bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004865{
4866 return true;
4867}
4868
Jamie Madill5b772312018-03-08 20:28:32 -05004869bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004870{
4871 switch (mode)
4872 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004873 case CullFaceMode::Front:
4874 case CullFaceMode::Back:
4875 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004876 break;
4877
4878 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004879 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004880 return false;
4881 }
4882
4883 return true;
4884}
4885
Jamie Madill5b772312018-03-08 20:28:32 -05004886bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004887{
4888 if (program == 0)
4889 {
4890 return false;
4891 }
4892
4893 if (!context->getProgram(program))
4894 {
4895 if (context->getShader(program))
4896 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004897 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004898 return false;
4899 }
4900 else
4901 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004902 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004903 return false;
4904 }
4905 }
4906
4907 return true;
4908}
4909
Jamie Madill5b772312018-03-08 20:28:32 -05004910bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004911{
4912 if (shader == 0)
4913 {
4914 return false;
4915 }
4916
4917 if (!context->getShader(shader))
4918 {
4919 if (context->getProgram(shader))
4920 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004921 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004922 return false;
4923 }
4924 else
4925 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004926 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004927 return false;
4928 }
4929 }
4930
4931 return true;
4932}
4933
Jamie Madill5b772312018-03-08 20:28:32 -05004934bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004935{
4936 switch (func)
4937 {
4938 case GL_NEVER:
4939 case GL_ALWAYS:
4940 case GL_LESS:
4941 case GL_LEQUAL:
4942 case GL_EQUAL:
4943 case GL_GREATER:
4944 case GL_GEQUAL:
4945 case GL_NOTEQUAL:
4946 break;
4947
4948 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004949 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004950 return false;
4951 }
4952
4953 return true;
4954}
4955
Jamie Madill5b772312018-03-08 20:28:32 -05004956bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004957{
4958 return true;
4959}
4960
Jamie Madill5b772312018-03-08 20:28:32 -05004961bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004962{
4963 Program *programObject = GetValidProgram(context, program);
4964 if (!programObject)
4965 {
4966 return false;
4967 }
4968
4969 Shader *shaderObject = GetValidShader(context, shader);
4970 if (!shaderObject)
4971 {
4972 return false;
4973 }
4974
Jiawei Shao385b3e02018-03-21 09:43:28 +08004975 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004976 if (attachedShader != shaderObject)
4977 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004978 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004979 return false;
4980 }
4981
4982 return true;
4983}
4984
Jamie Madill5b772312018-03-08 20:28:32 -05004985bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004986{
4987 if (index >= MAX_VERTEX_ATTRIBS)
4988 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004989 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004990 return false;
4991 }
4992
4993 return true;
4994}
4995
Jamie Madill5b772312018-03-08 20:28:32 -05004996bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004997{
4998 if (index >= MAX_VERTEX_ATTRIBS)
4999 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005000 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005001 return false;
5002 }
5003
5004 return true;
5005}
5006
Jamie Madill5b772312018-03-08 20:28:32 -05005007bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005008{
5009 return true;
5010}
5011
Jamie Madill5b772312018-03-08 20:28:32 -05005012bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005013{
5014 return true;
5015}
5016
Jamie Madill5b772312018-03-08 20:28:32 -05005017bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005018{
5019 switch (mode)
5020 {
5021 case GL_CW:
5022 case GL_CCW:
5023 break;
5024 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005025 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005026 return false;
5027 }
5028
5029 return true;
5030}
5031
Jamie Madill5b772312018-03-08 20:28:32 -05005032bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005033 GLuint program,
5034 GLuint index,
5035 GLsizei bufsize,
5036 GLsizei *length,
5037 GLint *size,
5038 GLenum *type,
5039 GLchar *name)
5040{
5041 if (bufsize < 0)
5042 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005043 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005044 return false;
5045 }
5046
5047 Program *programObject = GetValidProgram(context, program);
5048
5049 if (!programObject)
5050 {
5051 return false;
5052 }
5053
5054 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5055 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005056 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005057 return false;
5058 }
5059
5060 return true;
5061}
5062
Jamie Madill5b772312018-03-08 20:28:32 -05005063bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005064 GLuint program,
5065 GLuint index,
5066 GLsizei bufsize,
5067 GLsizei *length,
5068 GLint *size,
5069 GLenum *type,
5070 GLchar *name)
5071{
5072 if (bufsize < 0)
5073 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005074 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005075 return false;
5076 }
5077
5078 Program *programObject = GetValidProgram(context, program);
5079
5080 if (!programObject)
5081 {
5082 return false;
5083 }
5084
5085 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5086 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005087 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005088 return false;
5089 }
5090
5091 return true;
5092}
5093
Jamie Madill5b772312018-03-08 20:28:32 -05005094bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005095 GLuint program,
5096 GLsizei maxcount,
5097 GLsizei *count,
5098 GLuint *shaders)
5099{
5100 if (maxcount < 0)
5101 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005102 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005103 return false;
5104 }
5105
5106 Program *programObject = GetValidProgram(context, program);
5107
5108 if (!programObject)
5109 {
5110 return false;
5111 }
5112
5113 return true;
5114}
5115
Jamie Madill5b772312018-03-08 20:28:32 -05005116bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005117{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005118 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5119 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005120 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005121 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005122 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005123 return false;
5124 }
5125
Jamie Madillc1d770e2017-04-13 17:31:24 -04005126 Program *programObject = GetValidProgram(context, program);
5127
5128 if (!programObject)
5129 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005130 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005131 return false;
5132 }
5133
5134 if (!programObject->isLinked())
5135 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005136 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005137 return false;
5138 }
5139
5140 return true;
5141}
5142
Jamie Madill5b772312018-03-08 20:28:32 -05005143bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005144{
5145 GLenum nativeType;
5146 unsigned int numParams = 0;
5147 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5148}
5149
Jamie Madill5b772312018-03-08 20:28:32 -05005150bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005151{
5152 return true;
5153}
5154
Jamie Madill5b772312018-03-08 20:28:32 -05005155bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005156{
5157 GLenum nativeType;
5158 unsigned int numParams = 0;
5159 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5160}
5161
Jamie Madill5b772312018-03-08 20:28:32 -05005162bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005163{
5164 GLenum nativeType;
5165 unsigned int numParams = 0;
5166 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5167}
5168
Jamie Madill5b772312018-03-08 20:28:32 -05005169bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005170 GLuint program,
5171 GLsizei bufsize,
5172 GLsizei *length,
5173 GLchar *infolog)
5174{
5175 if (bufsize < 0)
5176 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005177 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005178 return false;
5179 }
5180
5181 Program *programObject = GetValidProgram(context, program);
5182 if (!programObject)
5183 {
5184 return false;
5185 }
5186
5187 return true;
5188}
5189
Jamie Madill5b772312018-03-08 20:28:32 -05005190bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005191 GLuint shader,
5192 GLsizei bufsize,
5193 GLsizei *length,
5194 GLchar *infolog)
5195{
5196 if (bufsize < 0)
5197 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005198 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005199 return false;
5200 }
5201
5202 Shader *shaderObject = GetValidShader(context, shader);
5203 if (!shaderObject)
5204 {
5205 return false;
5206 }
5207
5208 return true;
5209}
5210
Jamie Madill5b772312018-03-08 20:28:32 -05005211bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005212 GLenum shadertype,
5213 GLenum precisiontype,
5214 GLint *range,
5215 GLint *precision)
5216{
5217 switch (shadertype)
5218 {
5219 case GL_VERTEX_SHADER:
5220 case GL_FRAGMENT_SHADER:
5221 break;
5222 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005223 context->handleError(InvalidOperation()
5224 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005225 return false;
5226 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005227 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005228 return false;
5229 }
5230
5231 switch (precisiontype)
5232 {
5233 case GL_LOW_FLOAT:
5234 case GL_MEDIUM_FLOAT:
5235 case GL_HIGH_FLOAT:
5236 case GL_LOW_INT:
5237 case GL_MEDIUM_INT:
5238 case GL_HIGH_INT:
5239 break;
5240
5241 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005242 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005243 return false;
5244 }
5245
5246 return true;
5247}
5248
Jamie Madill5b772312018-03-08 20:28:32 -05005249bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005250 GLuint shader,
5251 GLsizei bufsize,
5252 GLsizei *length,
5253 GLchar *source)
5254{
5255 if (bufsize < 0)
5256 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005257 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005258 return false;
5259 }
5260
5261 Shader *shaderObject = GetValidShader(context, shader);
5262 if (!shaderObject)
5263 {
5264 return false;
5265 }
5266
5267 return true;
5268}
5269
Jamie Madill5b772312018-03-08 20:28:32 -05005270bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005271{
5272 if (strstr(name, "gl_") == name)
5273 {
5274 return false;
5275 }
5276
Geoff Langfc32e8b2017-05-31 14:16:59 -04005277 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5278 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005279 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005280 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005281 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005282 return false;
5283 }
5284
Jamie Madillc1d770e2017-04-13 17:31:24 -04005285 Program *programObject = GetValidProgram(context, program);
5286
5287 if (!programObject)
5288 {
5289 return false;
5290 }
5291
5292 if (!programObject->isLinked())
5293 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005294 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005295 return false;
5296 }
5297
5298 return true;
5299}
5300
Jamie Madill5b772312018-03-08 20:28:32 -05005301bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005302{
5303 switch (mode)
5304 {
5305 case GL_FASTEST:
5306 case GL_NICEST:
5307 case GL_DONT_CARE:
5308 break;
5309
5310 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005311 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005312 return false;
5313 }
5314
5315 switch (target)
5316 {
5317 case GL_GENERATE_MIPMAP_HINT:
5318 break;
5319
Geoff Lange7bd2182017-06-16 16:13:13 -04005320 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5321 if (context->getClientVersion() < ES_3_0 &&
5322 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005323 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005324 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005325 return false;
5326 }
5327 break;
5328
5329 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005330 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005331 return false;
5332 }
5333
5334 return true;
5335}
5336
Jamie Madill5b772312018-03-08 20:28:32 -05005337bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005338{
5339 return true;
5340}
5341
Jamie Madill5b772312018-03-08 20:28:32 -05005342bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005343{
5344 return true;
5345}
5346
Jamie Madill5b772312018-03-08 20:28:32 -05005347bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005348{
5349 return true;
5350}
5351
Jamie Madill5b772312018-03-08 20:28:32 -05005352bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005353{
5354 return true;
5355}
5356
Jamie Madill5b772312018-03-08 20:28:32 -05005357bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005358{
5359 return true;
5360}
5361
Jamie Madill5b772312018-03-08 20:28:32 -05005362bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005363{
5364 return true;
5365}
5366
Jamie Madill5b772312018-03-08 20:28:32 -05005367bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368{
5369 if (context->getClientMajorVersion() < 3)
5370 {
5371 switch (pname)
5372 {
5373 case GL_UNPACK_IMAGE_HEIGHT:
5374 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005375 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005376 return false;
5377
5378 case GL_UNPACK_ROW_LENGTH:
5379 case GL_UNPACK_SKIP_ROWS:
5380 case GL_UNPACK_SKIP_PIXELS:
5381 if (!context->getExtensions().unpackSubimage)
5382 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005383 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005384 return false;
5385 }
5386 break;
5387
5388 case GL_PACK_ROW_LENGTH:
5389 case GL_PACK_SKIP_ROWS:
5390 case GL_PACK_SKIP_PIXELS:
5391 if (!context->getExtensions().packSubimage)
5392 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005393 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005394 return false;
5395 }
5396 break;
5397 }
5398 }
5399
5400 if (param < 0)
5401 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005402 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005403 return false;
5404 }
5405
5406 switch (pname)
5407 {
5408 case GL_UNPACK_ALIGNMENT:
5409 if (param != 1 && param != 2 && param != 4 && param != 8)
5410 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005411 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005412 return false;
5413 }
5414 break;
5415
5416 case GL_PACK_ALIGNMENT:
5417 if (param != 1 && param != 2 && param != 4 && param != 8)
5418 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005419 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005420 return false;
5421 }
5422 break;
5423
5424 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005425 if (!context->getExtensions().packReverseRowOrder)
5426 {
5427 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5428 }
5429 break;
5430
Jamie Madillc1d770e2017-04-13 17:31:24 -04005431 case GL_UNPACK_ROW_LENGTH:
5432 case GL_UNPACK_IMAGE_HEIGHT:
5433 case GL_UNPACK_SKIP_IMAGES:
5434 case GL_UNPACK_SKIP_ROWS:
5435 case GL_UNPACK_SKIP_PIXELS:
5436 case GL_PACK_ROW_LENGTH:
5437 case GL_PACK_SKIP_ROWS:
5438 case GL_PACK_SKIP_PIXELS:
5439 break;
5440
5441 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005442 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005443 return false;
5444 }
5445
5446 return true;
5447}
5448
Jamie Madill5b772312018-03-08 20:28:32 -05005449bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005450{
5451 return true;
5452}
5453
Jamie Madill5b772312018-03-08 20:28:32 -05005454bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005455{
5456 return true;
5457}
5458
Jamie Madill5b772312018-03-08 20:28:32 -05005459bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005460{
5461 return true;
5462}
5463
Jamie Madill5b772312018-03-08 20:28:32 -05005464bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005465{
5466 if (width < 0 || height < 0)
5467 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005468 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005469 return false;
5470 }
5471
5472 return true;
5473}
5474
Jamie Madill5b772312018-03-08 20:28:32 -05005475bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005476 GLsizei n,
5477 const GLuint *shaders,
5478 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005479 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005480 GLsizei length)
5481{
5482 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5483 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5484 shaderBinaryFormats.end())
5485 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005486 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005487 return false;
5488 }
5489
5490 return true;
5491}
5492
Jamie Madill5b772312018-03-08 20:28:32 -05005493bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494 GLuint shader,
5495 GLsizei count,
5496 const GLchar *const *string,
5497 const GLint *length)
5498{
5499 if (count < 0)
5500 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005501 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005502 return false;
5503 }
5504
Geoff Langfc32e8b2017-05-31 14:16:59 -04005505 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5506 // shader-related entry points
5507 if (context->getExtensions().webglCompatibility)
5508 {
5509 for (GLsizei i = 0; i < count; i++)
5510 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005511 size_t len =
5512 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005513
5514 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005515 if (!IsValidESSLShaderSourceString(string[i], len,
5516 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005517 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005518 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005519 return false;
5520 }
5521 }
5522 }
5523
Jamie Madillc1d770e2017-04-13 17:31:24 -04005524 Shader *shaderObject = GetValidShader(context, shader);
5525 if (!shaderObject)
5526 {
5527 return false;
5528 }
5529
5530 return true;
5531}
5532
Jamie Madill5b772312018-03-08 20:28:32 -05005533bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005534{
5535 if (!IsValidStencilFunc(func))
5536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005537 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005538 return false;
5539 }
5540
5541 return true;
5542}
5543
Jamie Madill5b772312018-03-08 20:28:32 -05005544bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005545{
5546 if (!IsValidStencilFace(face))
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 if (!IsValidStencilFunc(func))
5553 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005554 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005555 return false;
5556 }
5557
5558 return true;
5559}
5560
Jamie Madill5b772312018-03-08 20:28:32 -05005561bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005562{
5563 return true;
5564}
5565
Jamie Madill5b772312018-03-08 20:28:32 -05005566bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005567{
5568 if (!IsValidStencilFace(face))
5569 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005570 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005571 return false;
5572 }
5573
5574 return true;
5575}
5576
Jamie Madill5b772312018-03-08 20:28:32 -05005577bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005578{
5579 if (!IsValidStencilOp(fail))
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(zfail))
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 if (!IsValidStencilOp(zpass))
5592 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005593 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005594 return false;
5595 }
5596
5597 return true;
5598}
5599
Jamie Madill5b772312018-03-08 20:28:32 -05005600bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005601 GLenum face,
5602 GLenum fail,
5603 GLenum zfail,
5604 GLenum zpass)
5605{
5606 if (!IsValidStencilFace(face))
5607 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005609 return false;
5610 }
5611
5612 return ValidateStencilOp(context, fail, zfail, zpass);
5613}
5614
Jamie Madill5b772312018-03-08 20:28:32 -05005615bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005616{
5617 return ValidateUniform(context, GL_FLOAT, location, 1);
5618}
5619
Jamie Madill5b772312018-03-08 20:28:32 -05005620bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005621{
5622 return ValidateUniform(context, GL_FLOAT, location, count);
5623}
5624
Jamie Madill5b772312018-03-08 20:28:32 -05005625bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005626{
5627 return ValidateUniform1iv(context, location, 1, &x);
5628}
5629
Jamie Madill5b772312018-03-08 20:28:32 -05005630bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005631{
5632 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5633}
5634
Jamie Madill5b772312018-03-08 20:28:32 -05005635bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005636{
5637 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5638}
5639
Jamie Madill5b772312018-03-08 20:28:32 -05005640bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005641{
5642 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5643}
5644
Jamie Madill5b772312018-03-08 20:28:32 -05005645bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005646{
5647 return ValidateUniform(context, GL_INT_VEC2, location, count);
5648}
5649
Jamie Madill5b772312018-03-08 20:28:32 -05005650bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005651{
5652 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5653}
5654
Jamie Madill5b772312018-03-08 20:28:32 -05005655bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005656{
5657 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5658}
5659
Jamie Madill5b772312018-03-08 20:28:32 -05005660bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005661{
5662 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5663}
5664
Jamie Madill5b772312018-03-08 20:28:32 -05005665bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005666{
5667 return ValidateUniform(context, GL_INT_VEC3, location, count);
5668}
5669
Jamie Madill5b772312018-03-08 20:28:32 -05005670bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005671{
5672 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5673}
5674
Jamie Madill5b772312018-03-08 20:28:32 -05005675bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005676{
5677 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5678}
5679
Jamie Madill5b772312018-03-08 20:28:32 -05005680bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005681{
5682 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5683}
5684
Jamie Madill5b772312018-03-08 20:28:32 -05005685bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005686{
5687 return ValidateUniform(context, GL_INT_VEC4, location, count);
5688}
5689
Jamie Madill5b772312018-03-08 20:28:32 -05005690bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005691 GLint location,
5692 GLsizei count,
5693 GLboolean transpose,
5694 const GLfloat *value)
5695{
5696 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5697}
5698
Jamie Madill5b772312018-03-08 20:28:32 -05005699bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005700 GLint location,
5701 GLsizei count,
5702 GLboolean transpose,
5703 const GLfloat *value)
5704{
5705 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5706}
5707
Jamie Madill5b772312018-03-08 20:28:32 -05005708bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005709 GLint location,
5710 GLsizei count,
5711 GLboolean transpose,
5712 const GLfloat *value)
5713{
5714 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5715}
5716
Jamie Madill5b772312018-03-08 20:28:32 -05005717bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005718{
5719 Program *programObject = GetValidProgram(context, program);
5720
5721 if (!programObject)
5722 {
5723 return false;
5724 }
5725
5726 return true;
5727}
5728
Jamie Madill5b772312018-03-08 20:28:32 -05005729bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005730{
5731 return ValidateVertexAttribIndex(context, index);
5732}
5733
Jamie Madill5b772312018-03-08 20:28:32 -05005734bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005735{
5736 return ValidateVertexAttribIndex(context, index);
5737}
5738
Jamie Madill5b772312018-03-08 20:28:32 -05005739bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005740{
5741 return ValidateVertexAttribIndex(context, index);
5742}
5743
Jamie Madill5b772312018-03-08 20:28:32 -05005744bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005745{
5746 return ValidateVertexAttribIndex(context, index);
5747}
5748
Jamie Madill5b772312018-03-08 20:28:32 -05005749bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005750{
5751 return ValidateVertexAttribIndex(context, index);
5752}
5753
Jamie Madill5b772312018-03-08 20:28:32 -05005754bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005755{
5756 return ValidateVertexAttribIndex(context, index);
5757}
5758
Jamie Madill5b772312018-03-08 20:28:32 -05005759bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005760 GLuint index,
5761 GLfloat x,
5762 GLfloat y,
5763 GLfloat z,
5764 GLfloat w)
5765{
5766 return ValidateVertexAttribIndex(context, index);
5767}
5768
Jamie Madill5b772312018-03-08 20:28:32 -05005769bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005770{
5771 return ValidateVertexAttribIndex(context, index);
5772}
5773
Jamie Madill5b772312018-03-08 20:28:32 -05005774bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005775{
5776 if (width < 0 || height < 0)
5777 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005778 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005779 return false;
5780 }
5781
5782 return true;
5783}
5784
Jamie Madill493f9572018-05-24 19:52:15 -04005785bool ValidateDrawArrays(Context *context, PrimitiveMode mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005786{
5787 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5788}
5789
Jamie Madill5b772312018-03-08 20:28:32 -05005790bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005791 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005792 GLsizei count,
5793 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005794 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005795{
5796 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5797}
5798
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005799bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005800 GLenum target,
5801 GLenum attachment,
5802 GLenum pname,
5803 GLint *params)
5804{
5805 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5806 nullptr);
5807}
5808
Jamie Madill5b772312018-03-08 20:28:32 -05005809bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005810{
5811 return ValidateGetProgramivBase(context, program, pname, nullptr);
5812}
5813
Jamie Madill5b772312018-03-08 20:28:32 -05005814bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005815 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005816 GLint level,
5817 GLenum internalformat,
5818 GLint x,
5819 GLint y,
5820 GLsizei width,
5821 GLsizei height,
5822 GLint border)
5823{
5824 if (context->getClientMajorVersion() < 3)
5825 {
5826 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5827 0, x, y, width, height, border);
5828 }
5829
5830 ASSERT(context->getClientMajorVersion() == 3);
5831 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5832 0, x, y, width, height, border);
5833}
5834
5835bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005836 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005837 GLint level,
5838 GLint xoffset,
5839 GLint yoffset,
5840 GLint x,
5841 GLint y,
5842 GLsizei width,
5843 GLsizei height)
5844{
5845 if (context->getClientMajorVersion() < 3)
5846 {
5847 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5848 yoffset, x, y, width, height, 0);
5849 }
5850
5851 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5852 yoffset, 0, x, y, width, height, 0);
5853}
5854
5855bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5856{
5857 return ValidateGenOrDelete(context, n);
5858}
5859
5860bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5861{
5862 return ValidateGenOrDelete(context, n);
5863}
5864
5865bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5866{
5867 return ValidateGenOrDelete(context, n);
5868}
5869
5870bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5871{
5872 return ValidateGenOrDelete(context, n);
5873}
5874
5875bool ValidateDisable(Context *context, GLenum cap)
5876{
5877 if (!ValidCap(context, cap, false))
5878 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005879 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005880 return false;
5881 }
5882
5883 return true;
5884}
5885
5886bool ValidateEnable(Context *context, GLenum cap)
5887{
5888 if (!ValidCap(context, cap, false))
5889 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005890 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005891 return false;
5892 }
5893
5894 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5895 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5896 {
5897 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005898 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005899
5900 // We also output an error message to the debugger window if tracing is active, so that
5901 // developers can see the error message.
5902 ERR() << errorMessage;
5903 return false;
5904 }
5905
5906 return true;
5907}
5908
5909bool ValidateFramebufferRenderbuffer(Context *context,
5910 GLenum target,
5911 GLenum attachment,
5912 GLenum renderbuffertarget,
5913 GLuint renderbuffer)
5914{
Geoff Lange8afa902017-09-27 15:00:43 -04005915 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005916 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005917 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5918 return false;
5919 }
5920
5921 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5922 {
5923 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005924 return false;
5925 }
5926
5927 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5928 renderbuffertarget, renderbuffer);
5929}
5930
5931bool ValidateFramebufferTexture2D(Context *context,
5932 GLenum target,
5933 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005934 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005935 GLuint texture,
5936 GLint level)
5937{
5938 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5939 // extension
5940 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5941 level != 0)
5942 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005943 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005944 return false;
5945 }
5946
5947 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5948 {
5949 return false;
5950 }
5951
5952 if (texture != 0)
5953 {
5954 gl::Texture *tex = context->getTexture(texture);
5955 ASSERT(tex);
5956
5957 const gl::Caps &caps = context->getCaps();
5958
5959 switch (textarget)
5960 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005961 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005962 {
5963 if (level > gl::log2(caps.max2DTextureSize))
5964 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005965 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005966 return false;
5967 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005968 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005969 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005970 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005971 return false;
5972 }
5973 }
5974 break;
5975
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005976 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005977 {
5978 if (level != 0)
5979 {
5980 context->handleError(InvalidValue());
5981 return false;
5982 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005983 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005984 {
5985 context->handleError(InvalidOperation()
5986 << "Textarget must match the texture target type.");
5987 return false;
5988 }
5989 }
5990 break;
5991
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005992 case TextureTarget::CubeMapNegativeX:
5993 case TextureTarget::CubeMapNegativeY:
5994 case TextureTarget::CubeMapNegativeZ:
5995 case TextureTarget::CubeMapPositiveX:
5996 case TextureTarget::CubeMapPositiveY:
5997 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005998 {
5999 if (level > gl::log2(caps.maxCubeMapTextureSize))
6000 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006001 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006002 return false;
6003 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006004 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006006 context->handleError(InvalidOperation()
6007 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006008 return false;
6009 }
6010 }
6011 break;
6012
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006013 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006014 {
6015 if (context->getClientVersion() < ES_3_1)
6016 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006017 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006018 return false;
6019 }
6020
6021 if (level != 0)
6022 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006023 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006024 return false;
6025 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006026 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006027 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006028 context->handleError(InvalidOperation()
6029 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006030 return false;
6031 }
6032 }
6033 break;
6034
6035 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006036 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 return false;
6038 }
6039
6040 const Format &format = tex->getFormat(textarget, level);
6041 if (format.info->compressed)
6042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006043 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006044 return false;
6045 }
6046 }
6047
6048 return true;
6049}
6050
6051bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6052{
6053 return ValidateGenOrDelete(context, n);
6054}
6055
6056bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6057{
6058 return ValidateGenOrDelete(context, n);
6059}
6060
6061bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6062{
6063 return ValidateGenOrDelete(context, n);
6064}
6065
6066bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6067{
6068 return ValidateGenOrDelete(context, n);
6069}
6070
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006071bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006072{
6073 if (!ValidTextureTarget(context, target))
6074 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006075 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006076 return false;
6077 }
6078
6079 Texture *texture = context->getTargetTexture(target);
6080
6081 if (texture == nullptr)
6082 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006083 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006084 return false;
6085 }
6086
6087 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6088
6089 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6090 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6091 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6092 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006093 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006094 return false;
6095 }
6096
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006097 TextureTarget baseTarget = (target == TextureType::CubeMap)
6098 ? TextureTarget::CubeMapPositiveX
6099 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006100 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6101 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6102 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006103 {
6104 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6105 return false;
6106 }
6107
Geoff Lang536eca12017-09-13 11:23:35 -04006108 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6109 bool formatUnsized = !format.sized;
6110 bool formatColorRenderableAndFilterable =
6111 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6112 format.renderSupport(context->getClientVersion(), context->getExtensions());
6113 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006114 {
Geoff Lang536eca12017-09-13 11:23:35 -04006115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006116 return false;
6117 }
6118
Geoff Lang536eca12017-09-13 11:23:35 -04006119 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6120 // generation
6121 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6122 {
6123 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6124 return false;
6125 }
6126
6127 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
Geoff Lange24032a2018-03-28 15:41:46 -04006128 // not. Differentiate the ES3 format from the extension format by checking if the format is
6129 // sized, GL_EXT_sRGB does not add any sized formats.
6130 bool supportsSRGBMipmapGeneration = context->getExtensions().webglCompatibility;
6131 if (!supportsSRGBMipmapGeneration && !format.sized && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006132 {
Geoff Lang536eca12017-09-13 11:23:35 -04006133 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006134 return false;
6135 }
6136
6137 // Non-power of 2 ES2 check
6138 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6139 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6140 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6141 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006142 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6143 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006145 return false;
6146 }
6147
6148 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006149 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006150 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006152 return false;
6153 }
6154
6155 return true;
6156}
6157
Jamie Madill5b772312018-03-08 20:28:32 -05006158bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006159 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006160 GLenum pname,
6161 GLint *params)
6162{
6163 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6164}
6165
6166bool ValidateGetRenderbufferParameteriv(Context *context,
6167 GLenum target,
6168 GLenum pname,
6169 GLint *params)
6170{
6171 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6172}
6173
6174bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6175{
6176 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6177}
6178
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006179bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006180{
6181 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6182}
6183
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006184bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006185{
6186 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6187}
6188
6189bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6190{
6191 return ValidateGetUniformBase(context, program, location);
6192}
6193
6194bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6195{
6196 return ValidateGetUniformBase(context, program, location);
6197}
6198
6199bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6200{
6201 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6202}
6203
6204bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6205{
6206 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6207}
6208
6209bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6210{
6211 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6212}
6213
6214bool ValidateIsEnabled(Context *context, GLenum cap)
6215{
6216 if (!ValidCap(context, cap, true))
6217 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006218 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006219 return false;
6220 }
6221
6222 return true;
6223}
6224
6225bool ValidateLinkProgram(Context *context, GLuint program)
6226{
6227 if (context->hasActiveTransformFeedback(program))
6228 {
6229 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006230 context->handleError(InvalidOperation() << "Cannot link program while program is "
6231 "associated with an active transform "
6232 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006233 return false;
6234 }
6235
6236 Program *programObject = GetValidProgram(context, program);
6237 if (!programObject)
6238 {
6239 return false;
6240 }
6241
6242 return true;
6243}
6244
Jamie Madill4928b7c2017-06-20 12:57:39 -04006245bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006246 GLint x,
6247 GLint y,
6248 GLsizei width,
6249 GLsizei height,
6250 GLenum format,
6251 GLenum type,
6252 void *pixels)
6253{
6254 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6255 nullptr, pixels);
6256}
6257
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006258bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006259{
6260 return ValidateTexParameterBase(context, target, pname, -1, &param);
6261}
6262
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006263bool ValidateTexParameterfv(Context *context,
6264 TextureType target,
6265 GLenum pname,
6266 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006267{
6268 return ValidateTexParameterBase(context, target, pname, -1, params);
6269}
6270
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006271bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006272{
6273 return ValidateTexParameterBase(context, target, pname, -1, &param);
6274}
6275
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006276bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006277{
6278 return ValidateTexParameterBase(context, target, pname, -1, params);
6279}
6280
6281bool ValidateUseProgram(Context *context, GLuint program)
6282{
6283 if (program != 0)
6284 {
6285 Program *programObject = context->getProgram(program);
6286 if (!programObject)
6287 {
6288 // ES 3.1.0 section 7.3 page 72
6289 if (context->getShader(program))
6290 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006291 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006292 return false;
6293 }
6294 else
6295 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006296 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006297 return false;
6298 }
6299 }
6300 if (!programObject->isLinked())
6301 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006302 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006303 return false;
6304 }
6305 }
6306 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6307 {
6308 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006309 context
6310 ->handleError(InvalidOperation()
6311 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006312 return false;
6313 }
6314
6315 return true;
6316}
6317
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006318bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6319{
6320 if (!context->getExtensions().fence)
6321 {
6322 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6323 return false;
6324 }
6325
6326 if (n < 0)
6327 {
6328 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6329 return false;
6330 }
6331
6332 return true;
6333}
6334
6335bool ValidateFinishFenceNV(Context *context, GLuint fence)
6336{
6337 if (!context->getExtensions().fence)
6338 {
6339 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6340 return false;
6341 }
6342
6343 FenceNV *fenceObject = context->getFenceNV(fence);
6344
6345 if (fenceObject == nullptr)
6346 {
6347 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6348 return false;
6349 }
6350
6351 if (!fenceObject->isSet())
6352 {
6353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6354 return false;
6355 }
6356
6357 return true;
6358}
6359
6360bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6361{
6362 if (!context->getExtensions().fence)
6363 {
6364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6365 return false;
6366 }
6367
6368 if (n < 0)
6369 {
6370 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6371 return false;
6372 }
6373
6374 return true;
6375}
6376
6377bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6378{
6379 if (!context->getExtensions().fence)
6380 {
6381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6382 return false;
6383 }
6384
6385 FenceNV *fenceObject = context->getFenceNV(fence);
6386
6387 if (fenceObject == nullptr)
6388 {
6389 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6390 return false;
6391 }
6392
6393 if (!fenceObject->isSet())
6394 {
6395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6396 return false;
6397 }
6398
6399 switch (pname)
6400 {
6401 case GL_FENCE_STATUS_NV:
6402 case GL_FENCE_CONDITION_NV:
6403 break;
6404
6405 default:
6406 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6407 return false;
6408 }
6409
6410 return true;
6411}
6412
6413bool ValidateGetGraphicsResetStatusEXT(Context *context)
6414{
6415 if (!context->getExtensions().robustness)
6416 {
6417 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6418 return false;
6419 }
6420
6421 return true;
6422}
6423
6424bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6425 GLuint shader,
6426 GLsizei bufsize,
6427 GLsizei *length,
6428 GLchar *source)
6429{
6430 if (!context->getExtensions().translatedShaderSource)
6431 {
6432 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6433 return false;
6434 }
6435
6436 if (bufsize < 0)
6437 {
6438 context->handleError(InvalidValue());
6439 return false;
6440 }
6441
6442 Shader *shaderObject = context->getShader(shader);
6443
6444 if (!shaderObject)
6445 {
6446 context->handleError(InvalidOperation());
6447 return false;
6448 }
6449
6450 return true;
6451}
6452
6453bool ValidateIsFenceNV(Context *context, GLuint fence)
6454{
6455 if (!context->getExtensions().fence)
6456 {
6457 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6458 return false;
6459 }
6460
6461 return true;
6462}
6463
Jamie Madill007530e2017-12-28 14:27:04 -05006464bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6465{
6466 if (!context->getExtensions().fence)
6467 {
6468 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6469 return false;
6470 }
6471
6472 if (condition != GL_ALL_COMPLETED_NV)
6473 {
6474 context->handleError(InvalidEnum());
6475 return false;
6476 }
6477
6478 FenceNV *fenceObject = context->getFenceNV(fence);
6479
6480 if (fenceObject == nullptr)
6481 {
6482 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6483 return false;
6484 }
6485
6486 return true;
6487}
6488
6489bool ValidateTestFenceNV(Context *context, GLuint fence)
6490{
6491 if (!context->getExtensions().fence)
6492 {
6493 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6494 return false;
6495 }
6496
6497 FenceNV *fenceObject = context->getFenceNV(fence);
6498
6499 if (fenceObject == nullptr)
6500 {
6501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6502 return false;
6503 }
6504
6505 if (fenceObject->isSet() != GL_TRUE)
6506 {
6507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6508 return false;
6509 }
6510
6511 return true;
6512}
6513
6514bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006515 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006516 GLsizei levels,
6517 GLenum internalformat,
6518 GLsizei width,
6519 GLsizei height)
6520{
6521 if (!context->getExtensions().textureStorage)
6522 {
6523 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6524 return false;
6525 }
6526
6527 if (context->getClientMajorVersion() < 3)
6528 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006529 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006530 height);
6531 }
6532
6533 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006534 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006535 1);
6536}
6537
6538bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6539{
6540 if (!context->getExtensions().instancedArrays)
6541 {
6542 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6543 return false;
6544 }
6545
6546 if (index >= MAX_VERTEX_ATTRIBS)
6547 {
6548 context->handleError(InvalidValue());
6549 return false;
6550 }
6551
6552 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6553 {
6554 if (index == 0 && divisor != 0)
6555 {
6556 const char *errorMessage =
6557 "The current context doesn't support setting a non-zero divisor on the "
6558 "attribute with index zero. "
6559 "Please reorder the attributes in your vertex shader so that attribute zero "
6560 "can have a zero divisor.";
6561 context->handleError(InvalidOperation() << errorMessage);
6562
6563 // We also output an error message to the debugger window if tracing is active, so
6564 // that developers can see the error message.
6565 ERR() << errorMessage;
6566 return false;
6567 }
6568 }
6569
6570 return true;
6571}
6572
6573bool ValidateTexImage3DOES(Context *context,
6574 GLenum target,
6575 GLint level,
6576 GLenum internalformat,
6577 GLsizei width,
6578 GLsizei height,
6579 GLsizei depth,
6580 GLint border,
6581 GLenum format,
6582 GLenum type,
6583 const void *pixels)
6584{
6585 UNIMPLEMENTED(); // FIXME
6586 return false;
6587}
6588
6589bool ValidatePopGroupMarkerEXT(Context *context)
6590{
6591 if (!context->getExtensions().debugMarker)
6592 {
6593 // The debug marker calls should not set error state
6594 // However, it seems reasonable to set an error state if the extension is not enabled
6595 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6596 return false;
6597 }
6598
6599 return true;
6600}
6601
Jamie Madillfa920eb2018-01-04 11:45:50 -05006602bool ValidateTexStorage1DEXT(Context *context,
6603 GLenum target,
6604 GLsizei levels,
6605 GLenum internalformat,
6606 GLsizei width)
6607{
6608 UNIMPLEMENTED();
6609 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6610 return false;
6611}
6612
6613bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006614 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006615 GLsizei levels,
6616 GLenum internalformat,
6617 GLsizei width,
6618 GLsizei height,
6619 GLsizei depth)
6620{
6621 if (!context->getExtensions().textureStorage)
6622 {
6623 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6624 return false;
6625 }
6626
6627 if (context->getClientMajorVersion() < 3)
6628 {
6629 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6630 return false;
6631 }
6632
6633 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6634 depth);
6635}
6636
Jamie Madillc29968b2016-01-20 11:17:23 -05006637} // namespace gl