blob: 1fa378108211d7a86eb0060ea968d03c64b6480d [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 Yang7ba3f422018-06-01 09:43:04 -0700820 case GL_FOG:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700821 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700822 case GL_POINT_SIZE_ARRAY_OES:
823 return context->getClientVersion() < Version(2, 0) &&
824 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700825 case GL_TEXTURE_CUBE_MAP:
826 return context->getClientVersion() < Version(2, 0) &&
827 context->getExtensions().textureCubeMap;
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700828
Jamie Madillbe849e42017-05-02 15:49:00 -0400829 default:
830 return false;
831 }
832}
833
Geoff Langfc32e8b2017-05-31 14:16:59 -0400834// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
835// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400836bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400837{
838 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400839 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
840 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400841 {
842 return true;
843 }
844
845 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
846 if (c >= 9 && c <= 13)
847 {
848 return true;
849 }
850
851 return false;
852}
853
Geoff Langcab92ee2017-07-19 17:32:07 -0400854bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400855{
Geoff Langa71a98e2017-06-19 15:15:00 -0400856 for (size_t i = 0; i < len; i++)
857 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400858 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400859 {
860 return false;
861 }
862 }
863
864 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400865}
866
Geoff Langcab92ee2017-07-19 17:32:07 -0400867bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
868{
869 enum class ParseState
870 {
871 // Have not seen an ASCII non-whitespace character yet on
872 // this line. Possible that we might see a preprocessor
873 // directive.
874 BEGINING_OF_LINE,
875
876 // Have seen at least one ASCII non-whitespace character
877 // on this line.
878 MIDDLE_OF_LINE,
879
880 // Handling a preprocessor directive. Passes through all
881 // characters up to the end of the line. Disables comment
882 // processing.
883 IN_PREPROCESSOR_DIRECTIVE,
884
885 // Handling a single-line comment. The comment text is
886 // replaced with a single space.
887 IN_SINGLE_LINE_COMMENT,
888
889 // Handling a multi-line comment. Newlines are passed
890 // through to preserve line numbers.
891 IN_MULTI_LINE_COMMENT
892 };
893
894 ParseState state = ParseState::BEGINING_OF_LINE;
895 size_t pos = 0;
896
897 while (pos < len)
898 {
899 char c = str[pos];
900 char next = pos + 1 < len ? str[pos + 1] : 0;
901
902 // Check for newlines
903 if (c == '\n' || c == '\r')
904 {
905 if (state != ParseState::IN_MULTI_LINE_COMMENT)
906 {
907 state = ParseState::BEGINING_OF_LINE;
908 }
909
910 pos++;
911 continue;
912 }
913
914 switch (state)
915 {
916 case ParseState::BEGINING_OF_LINE:
917 if (c == ' ')
918 {
919 // Maintain the BEGINING_OF_LINE state until a non-space is seen
920 pos++;
921 }
922 else if (c == '#')
923 {
924 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
925 pos++;
926 }
927 else
928 {
929 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
930 state = ParseState::MIDDLE_OF_LINE;
931 }
932 break;
933
934 case ParseState::MIDDLE_OF_LINE:
935 if (c == '/' && next == '/')
936 {
937 state = ParseState::IN_SINGLE_LINE_COMMENT;
938 pos++;
939 }
940 else if (c == '/' && next == '*')
941 {
942 state = ParseState::IN_MULTI_LINE_COMMENT;
943 pos++;
944 }
945 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
946 {
947 // Skip line continuation characters
948 }
949 else if (!IsValidESSLCharacter(c))
950 {
951 return false;
952 }
953 pos++;
954 break;
955
956 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700957 // Line-continuation characters may not be permitted.
958 // Otherwise, just pass it through. Do not parse comments in this state.
959 if (!lineContinuationAllowed && c == '\\')
960 {
961 return false;
962 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400963 pos++;
964 break;
965
966 case ParseState::IN_SINGLE_LINE_COMMENT:
967 // Line-continuation characters are processed before comment processing.
968 // Advance string if a new line character is immediately behind
969 // line-continuation character.
970 if (c == '\\' && (next == '\n' || next == '\r'))
971 {
972 pos++;
973 }
974 pos++;
975 break;
976
977 case ParseState::IN_MULTI_LINE_COMMENT:
978 if (c == '*' && next == '/')
979 {
980 state = ParseState::MIDDLE_OF_LINE;
981 pos++;
982 }
983 pos++;
984 break;
985 }
986 }
987
988 return true;
989}
990
Jamie Madill5b772312018-03-08 20:28:32 -0500991bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700992{
993 ASSERT(context->isWebGL());
994
995 // WebGL 1.0 [Section 6.16] GLSL Constructs
996 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
997 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
998 {
999 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1000 return false;
1001 }
1002
1003 return true;
1004}
1005
Jamie Madill5b772312018-03-08 20:28:32 -05001006bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001007{
1008 ASSERT(context->isWebGL());
1009
1010 if (context->isWebGL1() && length > 256)
1011 {
1012 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1013 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1014 // locations.
1015 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1016
1017 return false;
1018 }
1019 else if (length > 1024)
1020 {
1021 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1022 // uniform and attribute locations.
1023 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1024 return false;
1025 }
1026
1027 return true;
1028}
1029
Jamie Madill007530e2017-12-28 14:27:04 -05001030bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1031{
1032 if (!context->getExtensions().pathRendering)
1033 {
1034 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1035 return false;
1036 }
1037
1038 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1039 {
1040 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1041 return false;
1042 }
1043 return true;
1044}
Jamie Madillc29968b2016-01-20 11:17:23 -05001045} // anonymous namespace
1046
Geoff Langff5b2d52016-09-07 11:32:23 -04001047bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001048 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001049 GLint level,
1050 GLenum internalformat,
1051 bool isCompressed,
1052 bool isSubImage,
1053 GLint xoffset,
1054 GLint yoffset,
1055 GLsizei width,
1056 GLsizei height,
1057 GLint border,
1058 GLenum format,
1059 GLenum type,
1060 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001061 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001062{
Jamie Madill6f38f822014-06-06 17:12:20 -04001063 if (!ValidTexture2DDestinationTarget(context, target))
1064 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001065 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001066 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001067 }
1068
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001069 TextureType texType = TextureTargetToType(target);
1070 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001072 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001073 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001074 }
1075
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001076 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001077 {
1078 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1079 return false;
1080 }
1081
1082 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001083 std::numeric_limits<GLsizei>::max() - yoffset < height)
1084 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001085 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001086 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001087 }
1088
Geoff Lang6e898aa2017-06-02 11:17:26 -04001089 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1090 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1091 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1092 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1093 // case.
1094 bool nonEqualFormatsAllowed =
1095 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1096 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1097
1098 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001099 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001100 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001101 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001102 }
1103
Geoff Langaae65a42014-05-26 12:43:44 -04001104 const gl::Caps &caps = context->getCaps();
1105
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001106 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001107 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001108 case TextureType::_2D:
1109 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1110 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1111 {
1112 context->handleError(InvalidValue());
1113 return false;
1114 }
1115 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001116
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001117 case TextureType::Rectangle:
1118 ASSERT(level == 0);
1119 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1120 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1121 {
1122 context->handleError(InvalidValue());
1123 return false;
1124 }
1125 if (isCompressed)
1126 {
1127 context->handleError(InvalidEnum()
1128 << "Rectangle texture cannot have a compressed format.");
1129 return false;
1130 }
1131 break;
1132
1133 case TextureType::CubeMap:
1134 if (!isSubImage && width != height)
1135 {
1136 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1137 return false;
1138 }
1139
1140 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1141 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1142 {
1143 context->handleError(InvalidValue());
1144 return false;
1145 }
1146 break;
1147
1148 default:
1149 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001150 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001151 }
1152
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001153 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001154 if (!texture)
1155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001156 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001157 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001158 }
1159
Geoff Langa9be0dc2014-12-17 12:34:40 -05001160 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001161 {
Geoff Langca271392017-04-05 12:30:00 -04001162 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1163 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001164 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001165 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001166 return false;
1167 }
1168
Geoff Langa9be0dc2014-12-17 12:34:40 -05001169 if (format != GL_NONE)
1170 {
Geoff Langca271392017-04-05 12:30:00 -04001171 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1172 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001173 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001174 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001175 return false;
1176 }
1177 }
1178
1179 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1180 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001182 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001183 return false;
1184 }
Geoff Langfb052642017-10-24 13:42:09 -04001185
1186 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001187 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001188 {
1189 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1190 return false;
1191 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001192 }
1193 else
1194 {
Geoff Lang69cce582015-09-17 13:20:36 -04001195 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001196 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001197 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001198 return false;
1199 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001200 }
1201
1202 // Verify zero border
1203 if (border != 0)
1204 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001205 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001206 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001207 }
1208
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001209 if (isCompressed)
1210 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001211 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001212 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1213 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001214
1215 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1216
1217 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001218 {
Geoff Lange88e4542018-05-03 15:05:57 -04001219 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1220 return false;
1221 }
1222
1223 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1224 context->getExtensions()))
1225 {
1226 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1227 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001228 }
Geoff Lang966c9402017-04-18 12:38:27 -04001229
1230 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001231 {
Geoff Lange88e4542018-05-03 15:05:57 -04001232 // From the OES_compressed_ETC1_RGB8_texture spec:
1233 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1234 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1235 // ETC1_RGB8_OES.
1236 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1237 {
1238 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1239 return false;
1240 }
1241
Geoff Lang966c9402017-04-18 12:38:27 -04001242 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1243 height, texture->getWidth(target, level),
1244 texture->getHeight(target, level)))
1245 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001246 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001247 return false;
1248 }
1249
1250 if (format != actualInternalFormat)
1251 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001252 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001253 return false;
1254 }
1255 }
1256 else
1257 {
1258 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1259 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001260 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001261 return false;
1262 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001263 }
1264 }
1265 else
1266 {
1267 // validate <type> by itself (used as secondary key below)
1268 switch (type)
1269 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001270 case GL_UNSIGNED_BYTE:
1271 case GL_UNSIGNED_SHORT_5_6_5:
1272 case GL_UNSIGNED_SHORT_4_4_4_4:
1273 case GL_UNSIGNED_SHORT_5_5_5_1:
1274 case GL_UNSIGNED_SHORT:
1275 case GL_UNSIGNED_INT:
1276 case GL_UNSIGNED_INT_24_8_OES:
1277 case GL_HALF_FLOAT_OES:
1278 case GL_FLOAT:
1279 break;
1280 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001281 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001282 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001283 }
1284
1285 // validate <format> + <type> combinations
1286 // - invalid <format> -> sets INVALID_ENUM
1287 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1288 switch (format)
1289 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001290 case GL_ALPHA:
1291 case GL_LUMINANCE:
1292 case GL_LUMINANCE_ALPHA:
1293 switch (type)
1294 {
1295 case GL_UNSIGNED_BYTE:
1296 case GL_FLOAT:
1297 case GL_HALF_FLOAT_OES:
1298 break;
1299 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001300 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001301 return false;
1302 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001303 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001304 case GL_RED:
1305 case GL_RG:
1306 if (!context->getExtensions().textureRG)
1307 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001308 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001309 return false;
1310 }
1311 switch (type)
1312 {
1313 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001314 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001315 case GL_FLOAT:
1316 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001317 if (!context->getExtensions().textureFloat)
1318 {
1319 context->handleError(InvalidEnum());
1320 return false;
1321 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001322 break;
1323 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001324 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001325 return false;
1326 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001327 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001328 case GL_RGB:
1329 switch (type)
1330 {
1331 case GL_UNSIGNED_BYTE:
1332 case GL_UNSIGNED_SHORT_5_6_5:
1333 case GL_FLOAT:
1334 case GL_HALF_FLOAT_OES:
1335 break;
1336 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001337 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001338 return false;
1339 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001340 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001341 case GL_RGBA:
1342 switch (type)
1343 {
1344 case GL_UNSIGNED_BYTE:
1345 case GL_UNSIGNED_SHORT_4_4_4_4:
1346 case GL_UNSIGNED_SHORT_5_5_5_1:
1347 case GL_FLOAT:
1348 case GL_HALF_FLOAT_OES:
1349 break;
1350 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001351 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001352 return false;
1353 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001354 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001355 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001356 if (!context->getExtensions().textureFormatBGRA8888)
1357 {
1358 context->handleError(InvalidEnum());
1359 return false;
1360 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001361 switch (type)
1362 {
1363 case GL_UNSIGNED_BYTE:
1364 break;
1365 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001366 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001367 return false;
1368 }
1369 break;
1370 case GL_SRGB_EXT:
1371 case GL_SRGB_ALPHA_EXT:
1372 if (!context->getExtensions().sRGB)
1373 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001374 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001375 return false;
1376 }
1377 switch (type)
1378 {
1379 case GL_UNSIGNED_BYTE:
1380 break;
1381 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001383 return false;
1384 }
1385 break;
1386 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1387 // handled below
1388 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1389 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1390 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1391 break;
1392 case GL_DEPTH_COMPONENT:
1393 switch (type)
1394 {
1395 case GL_UNSIGNED_SHORT:
1396 case GL_UNSIGNED_INT:
1397 break;
1398 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001400 return false;
1401 }
1402 break;
1403 case GL_DEPTH_STENCIL_OES:
1404 switch (type)
1405 {
1406 case GL_UNSIGNED_INT_24_8_OES:
1407 break;
1408 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001409 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001410 return false;
1411 }
1412 break;
1413 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001414 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001415 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001416 }
1417
1418 switch (format)
1419 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001420 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1421 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1422 if (context->getExtensions().textureCompressionDXT1)
1423 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001424 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001425 return false;
1426 }
1427 else
1428 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001429 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001430 return false;
1431 }
1432 break;
1433 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1434 if (context->getExtensions().textureCompressionDXT3)
1435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001436 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001437 return false;
1438 }
1439 else
1440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001441 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001442 return false;
1443 }
1444 break;
1445 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1446 if (context->getExtensions().textureCompressionDXT5)
1447 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001448 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001449 return false;
1450 }
1451 else
1452 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001453 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001454 return false;
1455 }
1456 break;
1457 case GL_ETC1_RGB8_OES:
1458 if (context->getExtensions().compressedETC1RGB8Texture)
1459 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001460 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001461 return false;
1462 }
1463 else
1464 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001465 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001466 return false;
1467 }
1468 break;
1469 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001470 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1471 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1472 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1473 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001474 if (context->getExtensions().lossyETCDecode)
1475 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001476 context->handleError(InvalidOperation()
1477 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001478 return false;
1479 }
1480 else
1481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001482 context->handleError(InvalidEnum()
1483 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001484 return false;
1485 }
1486 break;
1487 case GL_DEPTH_COMPONENT:
1488 case GL_DEPTH_STENCIL_OES:
1489 if (!context->getExtensions().depthTextures)
1490 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001491 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001492 return false;
1493 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001494 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001495 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001496 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 return false;
1498 }
1499 // OES_depth_texture supports loading depth data and multiple levels,
1500 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001501 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001502 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001503 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1504 return false;
1505 }
1506 if (level != 0)
1507 {
1508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001509 return false;
1510 }
1511 break;
1512 default:
1513 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001514 }
1515
Geoff Lang6e898aa2017-06-02 11:17:26 -04001516 if (!isSubImage)
1517 {
1518 switch (internalformat)
1519 {
1520 case GL_RGBA32F:
1521 if (!context->getExtensions().colorBufferFloatRGBA)
1522 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001523 context->handleError(InvalidValue()
1524 << "Sized GL_RGBA32F internal format requires "
1525 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001526 return false;
1527 }
1528 if (type != GL_FLOAT)
1529 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001530 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001531 return false;
1532 }
1533 if (format != GL_RGBA)
1534 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001535 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001536 return false;
1537 }
1538 break;
1539
1540 case GL_RGB32F:
1541 if (!context->getExtensions().colorBufferFloatRGB)
1542 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001543 context->handleError(InvalidValue()
1544 << "Sized GL_RGB32F internal format requires "
1545 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001546 return false;
1547 }
1548 if (type != GL_FLOAT)
1549 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001550 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001551 return false;
1552 }
1553 if (format != GL_RGB)
1554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001555 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001556 return false;
1557 }
1558 break;
1559
1560 default:
1561 break;
1562 }
1563 }
1564
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001565 if (type == GL_FLOAT)
1566 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001567 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001568 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001569 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001570 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001571 }
1572 }
1573 else if (type == GL_HALF_FLOAT_OES)
1574 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001575 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001576 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001577 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001578 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001579 }
1580 }
1581 }
1582
Geoff Langdbcced82017-06-06 15:55:54 -04001583 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001584 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001585 imageSize))
1586 {
1587 return false;
1588 }
1589
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001590 return true;
1591}
1592
He Yunchaoced53ae2016-11-29 15:00:51 +08001593bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001594 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001595 GLsizei levels,
1596 GLenum internalformat,
1597 GLsizei width,
1598 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001599{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001600 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1601 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001602 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001603 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001604 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001605 }
1606
1607 if (width < 1 || height < 1 || levels < 1)
1608 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001609 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001610 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001611 }
1612
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001613 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001614 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001615 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001616 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001617 }
1618
1619 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1620 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001621 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001622 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001623 }
1624
Geoff Langca271392017-04-05 12:30:00 -04001625 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001626 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001627 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001628 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001629 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001630 }
1631
Geoff Langaae65a42014-05-26 12:43:44 -04001632 const gl::Caps &caps = context->getCaps();
1633
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001634 switch (target)
1635 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001636 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001637 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1638 static_cast<GLuint>(height) > caps.max2DTextureSize)
1639 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001640 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001641 return false;
1642 }
1643 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001644 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001645 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1646 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1647 {
1648 context->handleError(InvalidValue());
1649 return false;
1650 }
1651 if (formatInfo.compressed)
1652 {
1653 context->handleError(InvalidEnum()
1654 << "Rectangle texture cannot have a compressed format.");
1655 return false;
1656 }
1657 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001658 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001659 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1660 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1661 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001662 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001663 return false;
1664 }
1665 break;
1666 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001667 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001668 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001669 }
1670
Geoff Langc0b9ef42014-07-02 10:02:37 -04001671 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001672 {
1673 if (!gl::isPow2(width) || !gl::isPow2(height))
1674 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001675 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001676 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001677 }
1678 }
1679
1680 switch (internalformat)
1681 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001682 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1683 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1684 if (!context->getExtensions().textureCompressionDXT1)
1685 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001686 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001687 return false;
1688 }
1689 break;
1690 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1691 if (!context->getExtensions().textureCompressionDXT3)
1692 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001693 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001694 return false;
1695 }
1696 break;
1697 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1698 if (!context->getExtensions().textureCompressionDXT5)
1699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001700 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001701 return false;
1702 }
1703 break;
1704 case GL_ETC1_RGB8_OES:
1705 if (!context->getExtensions().compressedETC1RGB8Texture)
1706 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001707 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001708 return false;
1709 }
1710 break;
1711 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001712 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1713 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1714 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1715 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001716 if (!context->getExtensions().lossyETCDecode)
1717 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001718 context->handleError(InvalidEnum()
1719 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001720 return false;
1721 }
1722 break;
1723 case GL_RGBA32F_EXT:
1724 case GL_RGB32F_EXT:
1725 case GL_ALPHA32F_EXT:
1726 case GL_LUMINANCE32F_EXT:
1727 case GL_LUMINANCE_ALPHA32F_EXT:
1728 if (!context->getExtensions().textureFloat)
1729 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001730 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001731 return false;
1732 }
1733 break;
1734 case GL_RGBA16F_EXT:
1735 case GL_RGB16F_EXT:
1736 case GL_ALPHA16F_EXT:
1737 case GL_LUMINANCE16F_EXT:
1738 case GL_LUMINANCE_ALPHA16F_EXT:
1739 if (!context->getExtensions().textureHalfFloat)
1740 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001741 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001742 return false;
1743 }
1744 break;
1745 case GL_R8_EXT:
1746 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001747 if (!context->getExtensions().textureRG)
1748 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001749 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001750 return false;
1751 }
1752 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001753 case GL_R16F_EXT:
1754 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001755 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1756 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001757 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001758 return false;
1759 }
1760 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001761 case GL_R32F_EXT:
1762 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001763 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001764 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001765 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001766 return false;
1767 }
1768 break;
1769 case GL_DEPTH_COMPONENT16:
1770 case GL_DEPTH_COMPONENT32_OES:
1771 case GL_DEPTH24_STENCIL8_OES:
1772 if (!context->getExtensions().depthTextures)
1773 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001774 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001775 return false;
1776 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001777 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001778 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001779 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001780 return false;
1781 }
1782 // ANGLE_depth_texture only supports 1-level textures
1783 if (levels != 1)
1784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001785 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001786 return false;
1787 }
1788 break;
1789 default:
1790 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001791 }
1792
Geoff Lang691e58c2014-12-19 17:03:25 -05001793 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001794 if (!texture || texture->id() == 0)
1795 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001796 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001797 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001798 }
1799
Geoff Lang69cce582015-09-17 13:20:36 -04001800 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001801 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001802 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001803 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001804 }
1805
1806 return true;
1807}
1808
He Yunchaoced53ae2016-11-29 15:00:51 +08001809bool ValidateDiscardFramebufferEXT(Context *context,
1810 GLenum target,
1811 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001812 const GLenum *attachments)
1813{
Jamie Madillc29968b2016-01-20 11:17:23 -05001814 if (!context->getExtensions().discardFramebuffer)
1815 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001816 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001817 return false;
1818 }
1819
Austin Kinross08332632015-05-05 13:35:47 -07001820 bool defaultFramebuffer = false;
1821
1822 switch (target)
1823 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001824 case GL_FRAMEBUFFER:
1825 defaultFramebuffer =
1826 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1827 break;
1828 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001829 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001830 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001831 }
1832
He Yunchaoced53ae2016-11-29 15:00:51 +08001833 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1834 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001835}
1836
Austin Kinrossbc781f32015-10-26 09:27:38 -07001837bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1838{
1839 if (!context->getExtensions().vertexArrayObject)
1840 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001841 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001842 return false;
1843 }
1844
1845 return ValidateBindVertexArrayBase(context, array);
1846}
1847
Jamie Madilld7576732017-08-26 18:49:50 -04001848bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001849{
1850 if (!context->getExtensions().vertexArrayObject)
1851 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001852 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001853 return false;
1854 }
1855
Olli Etuaho41997e72016-03-10 13:38:39 +02001856 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001857}
1858
Jamie Madilld7576732017-08-26 18:49:50 -04001859bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001860{
1861 if (!context->getExtensions().vertexArrayObject)
1862 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001863 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001864 return false;
1865 }
1866
Olli Etuaho41997e72016-03-10 13:38:39 +02001867 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001868}
1869
Jamie Madilld7576732017-08-26 18:49:50 -04001870bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001871{
1872 if (!context->getExtensions().vertexArrayObject)
1873 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001874 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001875 return false;
1876 }
1877
1878 return true;
1879}
Geoff Langc5629752015-12-07 16:29:04 -05001880
1881bool ValidateProgramBinaryOES(Context *context,
1882 GLuint program,
1883 GLenum binaryFormat,
1884 const void *binary,
1885 GLint length)
1886{
1887 if (!context->getExtensions().getProgramBinary)
1888 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001889 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001890 return false;
1891 }
1892
1893 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1894}
1895
1896bool ValidateGetProgramBinaryOES(Context *context,
1897 GLuint program,
1898 GLsizei bufSize,
1899 GLsizei *length,
1900 GLenum *binaryFormat,
1901 void *binary)
1902{
1903 if (!context->getExtensions().getProgramBinary)
1904 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001905 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001906 return false;
1907 }
1908
1909 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1910}
Geoff Lange102fee2015-12-10 11:23:30 -05001911
Geoff Lang70d0f492015-12-10 17:45:46 -05001912static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1913{
1914 switch (source)
1915 {
1916 case GL_DEBUG_SOURCE_API:
1917 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1918 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1919 case GL_DEBUG_SOURCE_OTHER:
1920 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1921 return !mustBeThirdPartyOrApplication;
1922
1923 case GL_DEBUG_SOURCE_THIRD_PARTY:
1924 case GL_DEBUG_SOURCE_APPLICATION:
1925 return true;
1926
1927 default:
1928 return false;
1929 }
1930}
1931
1932static bool ValidDebugType(GLenum type)
1933{
1934 switch (type)
1935 {
1936 case GL_DEBUG_TYPE_ERROR:
1937 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1938 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1939 case GL_DEBUG_TYPE_PERFORMANCE:
1940 case GL_DEBUG_TYPE_PORTABILITY:
1941 case GL_DEBUG_TYPE_OTHER:
1942 case GL_DEBUG_TYPE_MARKER:
1943 case GL_DEBUG_TYPE_PUSH_GROUP:
1944 case GL_DEBUG_TYPE_POP_GROUP:
1945 return true;
1946
1947 default:
1948 return false;
1949 }
1950}
1951
1952static bool ValidDebugSeverity(GLenum severity)
1953{
1954 switch (severity)
1955 {
1956 case GL_DEBUG_SEVERITY_HIGH:
1957 case GL_DEBUG_SEVERITY_MEDIUM:
1958 case GL_DEBUG_SEVERITY_LOW:
1959 case GL_DEBUG_SEVERITY_NOTIFICATION:
1960 return true;
1961
1962 default:
1963 return false;
1964 }
1965}
1966
Geoff Lange102fee2015-12-10 11:23:30 -05001967bool ValidateDebugMessageControlKHR(Context *context,
1968 GLenum source,
1969 GLenum type,
1970 GLenum severity,
1971 GLsizei count,
1972 const GLuint *ids,
1973 GLboolean enabled)
1974{
1975 if (!context->getExtensions().debug)
1976 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001977 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001978 return false;
1979 }
1980
Geoff Lang70d0f492015-12-10 17:45:46 -05001981 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1982 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001983 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001984 return false;
1985 }
1986
1987 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1988 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001989 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001990 return false;
1991 }
1992
1993 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1994 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001995 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001996 return false;
1997 }
1998
1999 if (count > 0)
2000 {
2001 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2002 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002003 context->handleError(
2004 InvalidOperation()
2005 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002006 return false;
2007 }
2008
2009 if (severity != GL_DONT_CARE)
2010 {
Jamie Madill437fa652016-05-03 15:13:24 -04002011 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002012 InvalidOperation()
2013 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002014 return false;
2015 }
2016 }
2017
Geoff Lange102fee2015-12-10 11:23:30 -05002018 return true;
2019}
2020
2021bool ValidateDebugMessageInsertKHR(Context *context,
2022 GLenum source,
2023 GLenum type,
2024 GLuint id,
2025 GLenum severity,
2026 GLsizei length,
2027 const GLchar *buf)
2028{
2029 if (!context->getExtensions().debug)
2030 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002031 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002032 return false;
2033 }
2034
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002035 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002036 {
2037 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2038 // not generate an error.
2039 return false;
2040 }
2041
2042 if (!ValidDebugSeverity(severity))
2043 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002044 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002045 return false;
2046 }
2047
2048 if (!ValidDebugType(type))
2049 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002051 return false;
2052 }
2053
2054 if (!ValidDebugSource(source, true))
2055 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002056 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002057 return false;
2058 }
2059
2060 size_t messageLength = (length < 0) ? strlen(buf) : length;
2061 if (messageLength > context->getExtensions().maxDebugMessageLength)
2062 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002063 context->handleError(InvalidValue()
2064 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002065 return false;
2066 }
2067
Geoff Lange102fee2015-12-10 11:23:30 -05002068 return true;
2069}
2070
2071bool ValidateDebugMessageCallbackKHR(Context *context,
2072 GLDEBUGPROCKHR callback,
2073 const void *userParam)
2074{
2075 if (!context->getExtensions().debug)
2076 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002077 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002078 return false;
2079 }
2080
Geoff Lange102fee2015-12-10 11:23:30 -05002081 return true;
2082}
2083
2084bool ValidateGetDebugMessageLogKHR(Context *context,
2085 GLuint count,
2086 GLsizei bufSize,
2087 GLenum *sources,
2088 GLenum *types,
2089 GLuint *ids,
2090 GLenum *severities,
2091 GLsizei *lengths,
2092 GLchar *messageLog)
2093{
2094 if (!context->getExtensions().debug)
2095 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002096 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002097 return false;
2098 }
2099
Geoff Lang70d0f492015-12-10 17:45:46 -05002100 if (bufSize < 0 && messageLog != nullptr)
2101 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002102 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002103 return false;
2104 }
2105
Geoff Lange102fee2015-12-10 11:23:30 -05002106 return true;
2107}
2108
2109bool ValidatePushDebugGroupKHR(Context *context,
2110 GLenum source,
2111 GLuint id,
2112 GLsizei length,
2113 const GLchar *message)
2114{
2115 if (!context->getExtensions().debug)
2116 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002117 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002118 return false;
2119 }
2120
Geoff Lang70d0f492015-12-10 17:45:46 -05002121 if (!ValidDebugSource(source, true))
2122 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002123 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002124 return false;
2125 }
2126
2127 size_t messageLength = (length < 0) ? strlen(message) : length;
2128 if (messageLength > context->getExtensions().maxDebugMessageLength)
2129 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002130 context->handleError(InvalidValue()
2131 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002132 return false;
2133 }
2134
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002135 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002136 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2137 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002138 context
2139 ->handleError(StackOverflow()
2140 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002141 return false;
2142 }
2143
Geoff Lange102fee2015-12-10 11:23:30 -05002144 return true;
2145}
2146
2147bool ValidatePopDebugGroupKHR(Context *context)
2148{
2149 if (!context->getExtensions().debug)
2150 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002152 return false;
2153 }
2154
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002155 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002156 if (currentStackSize <= 1)
2157 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002158 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002159 return false;
2160 }
2161
2162 return true;
2163}
2164
2165static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2166{
2167 switch (identifier)
2168 {
2169 case GL_BUFFER:
2170 if (context->getBuffer(name) == nullptr)
2171 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002172 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002173 return false;
2174 }
2175 return true;
2176
2177 case GL_SHADER:
2178 if (context->getShader(name) == nullptr)
2179 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002180 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002181 return false;
2182 }
2183 return true;
2184
2185 case GL_PROGRAM:
2186 if (context->getProgram(name) == nullptr)
2187 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002188 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002189 return false;
2190 }
2191 return true;
2192
2193 case GL_VERTEX_ARRAY:
2194 if (context->getVertexArray(name) == nullptr)
2195 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002196 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002197 return false;
2198 }
2199 return true;
2200
2201 case GL_QUERY:
2202 if (context->getQuery(name) == nullptr)
2203 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002204 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002205 return false;
2206 }
2207 return true;
2208
2209 case GL_TRANSFORM_FEEDBACK:
2210 if (context->getTransformFeedback(name) == nullptr)
2211 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002212 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002213 return false;
2214 }
2215 return true;
2216
2217 case GL_SAMPLER:
2218 if (context->getSampler(name) == nullptr)
2219 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002220 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002221 return false;
2222 }
2223 return true;
2224
2225 case GL_TEXTURE:
2226 if (context->getTexture(name) == nullptr)
2227 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002228 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002229 return false;
2230 }
2231 return true;
2232
2233 case GL_RENDERBUFFER:
2234 if (context->getRenderbuffer(name) == nullptr)
2235 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002236 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002237 return false;
2238 }
2239 return true;
2240
2241 case GL_FRAMEBUFFER:
2242 if (context->getFramebuffer(name) == nullptr)
2243 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002244 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002245 return false;
2246 }
2247 return true;
2248
2249 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002250 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002251 return false;
2252 }
Geoff Lange102fee2015-12-10 11:23:30 -05002253}
2254
Martin Radev9d901792016-07-15 15:58:58 +03002255static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2256{
2257 size_t labelLength = 0;
2258
2259 if (length < 0)
2260 {
2261 if (label != nullptr)
2262 {
2263 labelLength = strlen(label);
2264 }
2265 }
2266 else
2267 {
2268 labelLength = static_cast<size_t>(length);
2269 }
2270
2271 if (labelLength > context->getExtensions().maxLabelLength)
2272 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002273 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002274 return false;
2275 }
2276
2277 return true;
2278}
2279
Geoff Lange102fee2015-12-10 11:23:30 -05002280bool ValidateObjectLabelKHR(Context *context,
2281 GLenum identifier,
2282 GLuint name,
2283 GLsizei length,
2284 const GLchar *label)
2285{
2286 if (!context->getExtensions().debug)
2287 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002288 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002289 return false;
2290 }
2291
Geoff Lang70d0f492015-12-10 17:45:46 -05002292 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2293 {
2294 return false;
2295 }
2296
Martin Radev9d901792016-07-15 15:58:58 +03002297 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002298 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002299 return false;
2300 }
2301
Geoff Lange102fee2015-12-10 11:23:30 -05002302 return true;
2303}
2304
2305bool ValidateGetObjectLabelKHR(Context *context,
2306 GLenum identifier,
2307 GLuint name,
2308 GLsizei bufSize,
2309 GLsizei *length,
2310 GLchar *label)
2311{
2312 if (!context->getExtensions().debug)
2313 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002314 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002315 return false;
2316 }
2317
Geoff Lang70d0f492015-12-10 17:45:46 -05002318 if (bufSize < 0)
2319 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002320 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002321 return false;
2322 }
2323
2324 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2325 {
2326 return false;
2327 }
2328
Martin Radev9d901792016-07-15 15:58:58 +03002329 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002330}
2331
2332static bool ValidateObjectPtrName(Context *context, const void *ptr)
2333{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002334 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002335 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002336 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002337 return false;
2338 }
2339
Geoff Lange102fee2015-12-10 11:23:30 -05002340 return true;
2341}
2342
2343bool ValidateObjectPtrLabelKHR(Context *context,
2344 const void *ptr,
2345 GLsizei length,
2346 const GLchar *label)
2347{
2348 if (!context->getExtensions().debug)
2349 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002351 return false;
2352 }
2353
Geoff Lang70d0f492015-12-10 17:45:46 -05002354 if (!ValidateObjectPtrName(context, ptr))
2355 {
2356 return false;
2357 }
2358
Martin Radev9d901792016-07-15 15:58:58 +03002359 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002360 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002361 return false;
2362 }
2363
Geoff Lange102fee2015-12-10 11:23:30 -05002364 return true;
2365}
2366
2367bool ValidateGetObjectPtrLabelKHR(Context *context,
2368 const void *ptr,
2369 GLsizei bufSize,
2370 GLsizei *length,
2371 GLchar *label)
2372{
2373 if (!context->getExtensions().debug)
2374 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002375 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002376 return false;
2377 }
2378
Geoff Lang70d0f492015-12-10 17:45:46 -05002379 if (bufSize < 0)
2380 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002381 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002382 return false;
2383 }
2384
2385 if (!ValidateObjectPtrName(context, ptr))
2386 {
2387 return false;
2388 }
2389
Martin Radev9d901792016-07-15 15:58:58 +03002390 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002391}
2392
2393bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2394{
2395 if (!context->getExtensions().debug)
2396 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002397 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002398 return false;
2399 }
2400
Geoff Lang70d0f492015-12-10 17:45:46 -05002401 // TODO: represent this in Context::getQueryParameterInfo.
2402 switch (pname)
2403 {
2404 case GL_DEBUG_CALLBACK_FUNCTION:
2405 case GL_DEBUG_CALLBACK_USER_PARAM:
2406 break;
2407
2408 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002409 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002410 return false;
2411 }
2412
Geoff Lange102fee2015-12-10 11:23:30 -05002413 return true;
2414}
Jamie Madillc29968b2016-01-20 11:17:23 -05002415
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002416bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2417 GLenum pname,
2418 GLsizei bufSize,
2419 GLsizei *length,
2420 void **params)
2421{
2422 UNIMPLEMENTED();
2423 return false;
2424}
2425
Jamie Madillc29968b2016-01-20 11:17:23 -05002426bool ValidateBlitFramebufferANGLE(Context *context,
2427 GLint srcX0,
2428 GLint srcY0,
2429 GLint srcX1,
2430 GLint srcY1,
2431 GLint dstX0,
2432 GLint dstY0,
2433 GLint dstX1,
2434 GLint dstY1,
2435 GLbitfield mask,
2436 GLenum filter)
2437{
2438 if (!context->getExtensions().framebufferBlit)
2439 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002440 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002441 return false;
2442 }
2443
2444 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2445 {
2446 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002447 context->handleError(InvalidOperation() << "Scaling and flipping in "
2448 "BlitFramebufferANGLE not supported by this "
2449 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002450 return false;
2451 }
2452
2453 if (filter == GL_LINEAR)
2454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002455 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002456 return false;
2457 }
2458
Jamie Madill51f40ec2016-06-15 14:06:00 -04002459 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2460 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002461
2462 if (mask & GL_COLOR_BUFFER_BIT)
2463 {
2464 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2465 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2466
2467 if (readColorAttachment && drawColorAttachment)
2468 {
2469 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002470 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002471 readColorAttachment->type() != GL_RENDERBUFFER &&
2472 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2473 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002474 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002475 return false;
2476 }
2477
Geoff Langa15472a2015-08-11 11:48:03 -04002478 for (size_t drawbufferIdx = 0;
2479 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002480 {
Geoff Langa15472a2015-08-11 11:48:03 -04002481 const FramebufferAttachment *attachment =
2482 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2483 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002484 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002485 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002486 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002487 attachment->type() != GL_RENDERBUFFER &&
2488 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002490 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 return false;
2492 }
2493
2494 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002495 if (!Format::EquivalentForBlit(attachment->getFormat(),
2496 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002497 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002498 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002499 return false;
2500 }
2501 }
2502 }
2503
Jamie Madill427064d2018-04-13 16:20:34 -04002504 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002505 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002506 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2507 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2508 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002509 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002510 return false;
2511 }
2512 }
2513 }
2514
2515 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2516 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2517 for (size_t i = 0; i < 2; i++)
2518 {
2519 if (mask & masks[i])
2520 {
2521 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002522 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002523 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002524 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002525
2526 if (readBuffer && drawBuffer)
2527 {
2528 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2529 dstX0, dstY0, dstX1, dstY1))
2530 {
2531 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002532 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2533 "stencil blits are supported by "
2534 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002535 return false;
2536 }
2537
2538 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2539 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002540 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002541 return false;
2542 }
2543 }
2544 }
2545 }
2546
2547 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2548 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002549}
Jamie Madillc29968b2016-01-20 11:17:23 -05002550
Jamie Madill5b772312018-03-08 20:28:32 -05002551bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002552{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002553 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002554
Jamie Madill427064d2018-04-13 16:20:34 -04002555 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002556 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002557 return false;
2558 }
2559
2560 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2561 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002562 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002563 return false;
2564 }
2565
Geoff Lang76e65652017-03-27 14:58:02 -04002566 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2567 {
2568 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2569 GL_SIGNED_NORMALIZED};
2570
Corentin Wallez59c41592017-07-11 13:19:54 -04002571 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002572 drawBufferIdx++)
2573 {
2574 if (!ValidateWebGLFramebufferAttachmentClearType(
2575 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2576 {
2577 return false;
2578 }
2579 }
2580 }
2581
Jamie Madillc29968b2016-01-20 11:17:23 -05002582 return true;
2583}
2584
Jamie Madill5b772312018-03-08 20:28:32 -05002585bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002586{
2587 if (!context->getExtensions().drawBuffers)
2588 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002589 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002590 return false;
2591 }
2592
2593 return ValidateDrawBuffersBase(context, n, bufs);
2594}
2595
Jamie Madill73a84962016-02-12 09:27:23 -05002596bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002597 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002598 GLint level,
2599 GLint internalformat,
2600 GLsizei width,
2601 GLsizei height,
2602 GLint border,
2603 GLenum format,
2604 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002605 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002606{
Martin Radev1be913c2016-07-11 17:59:16 +03002607 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002608 {
2609 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002610 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002611 }
2612
Martin Radev1be913c2016-07-11 17:59:16 +03002613 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002614 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002615 0, 0, width, height, 1, border, format, type, -1,
2616 pixels);
2617}
2618
Brandon Jones416aaf92018-04-10 08:10:16 -07002619bool ValidateTexImage2DRobustANGLE(Context *context,
2620 TextureTarget target,
2621 GLint level,
2622 GLint internalformat,
2623 GLsizei width,
2624 GLsizei height,
2625 GLint border,
2626 GLenum format,
2627 GLenum type,
2628 GLsizei bufSize,
2629 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002630{
2631 if (!ValidateRobustEntryPoint(context, bufSize))
2632 {
2633 return false;
2634 }
2635
2636 if (context->getClientMajorVersion() < 3)
2637 {
2638 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2639 0, 0, width, height, border, format, type, bufSize,
2640 pixels);
2641 }
2642
2643 ASSERT(context->getClientMajorVersion() >= 3);
2644 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2645 0, 0, width, height, 1, border, format, type, bufSize,
2646 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002647}
2648
2649bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002650 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002651 GLint level,
2652 GLint xoffset,
2653 GLint yoffset,
2654 GLsizei width,
2655 GLsizei height,
2656 GLenum format,
2657 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002658 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002659{
2660
Martin Radev1be913c2016-07-11 17:59:16 +03002661 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002662 {
2663 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002664 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002665 }
2666
Martin Radev1be913c2016-07-11 17:59:16 +03002667 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002668 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002669 yoffset, 0, width, height, 1, 0, format, type, -1,
2670 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002671}
2672
Geoff Langc52f6f12016-10-14 10:18:00 -04002673bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002674 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002675 GLint level,
2676 GLint xoffset,
2677 GLint yoffset,
2678 GLsizei width,
2679 GLsizei height,
2680 GLenum format,
2681 GLenum type,
2682 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002683 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002684{
2685 if (!ValidateRobustEntryPoint(context, bufSize))
2686 {
2687 return false;
2688 }
2689
2690 if (context->getClientMajorVersion() < 3)
2691 {
2692 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2693 yoffset, width, height, 0, format, type, bufSize,
2694 pixels);
2695 }
2696
2697 ASSERT(context->getClientMajorVersion() >= 3);
2698 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2699 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2700 pixels);
2701}
2702
Jamie Madill73a84962016-02-12 09:27:23 -05002703bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002704 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002705 GLint level,
2706 GLenum internalformat,
2707 GLsizei width,
2708 GLsizei height,
2709 GLint border,
2710 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002711 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002712{
Martin Radev1be913c2016-07-11 17:59:16 +03002713 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002714 {
2715 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002716 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002717 {
2718 return false;
2719 }
2720 }
2721 else
2722 {
Martin Radev1be913c2016-07-11 17:59:16 +03002723 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002724 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002725 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002726 data))
2727 {
2728 return false;
2729 }
2730 }
2731
Geoff Langca271392017-04-05 12:30:00 -04002732 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002733 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002734 if (blockSizeOrErr.isError())
2735 {
2736 context->handleError(blockSizeOrErr.getError());
2737 return false;
2738 }
2739
2740 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002741 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002742 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002743 return false;
2744 }
2745
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002746 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002747 {
2748 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2749 return false;
2750 }
2751
Jamie Madill73a84962016-02-12 09:27:23 -05002752 return true;
2753}
2754
Corentin Wallezb2931602017-04-11 15:58:57 -04002755bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002756 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002757 GLint level,
2758 GLenum internalformat,
2759 GLsizei width,
2760 GLsizei height,
2761 GLint border,
2762 GLsizei imageSize,
2763 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002764 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002765{
2766 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2767 {
2768 return false;
2769 }
2770
2771 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2772 border, imageSize, data);
2773}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002774
Corentin Wallezb2931602017-04-11 15:58:57 -04002775bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002776 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002777 GLint level,
2778 GLint xoffset,
2779 GLint yoffset,
2780 GLsizei width,
2781 GLsizei height,
2782 GLenum format,
2783 GLsizei imageSize,
2784 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002785 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002786{
2787 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2788 {
2789 return false;
2790 }
2791
2792 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2793 format, imageSize, data);
2794}
2795
Jamie Madill73a84962016-02-12 09:27:23 -05002796bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002797 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002798 GLint level,
2799 GLint xoffset,
2800 GLint yoffset,
2801 GLsizei width,
2802 GLsizei height,
2803 GLenum format,
2804 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002805 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002806{
Martin Radev1be913c2016-07-11 17:59:16 +03002807 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002808 {
2809 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002810 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002811 {
2812 return false;
2813 }
2814 }
2815 else
2816 {
Martin Radev1be913c2016-07-11 17:59:16 +03002817 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002818 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002819 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002820 data))
2821 {
2822 return false;
2823 }
2824 }
2825
Geoff Langca271392017-04-05 12:30:00 -04002826 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002827 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002828 if (blockSizeOrErr.isError())
2829 {
2830 context->handleError(blockSizeOrErr.getError());
2831 return false;
2832 }
2833
2834 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002835 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002836 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002837 return false;
2838 }
2839
2840 return true;
2841}
2842
Corentin Wallez336129f2017-10-17 15:55:40 -04002843bool ValidateGetBufferPointervOES(Context *context,
2844 BufferBinding target,
2845 GLenum pname,
2846 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002847{
Geoff Lang496c02d2016-10-20 11:38:11 -07002848 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002849}
2850
Corentin Wallez336129f2017-10-17 15:55:40 -04002851bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002852{
2853 if (!context->getExtensions().mapBuffer)
2854 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002855 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002856 return false;
2857 }
2858
Corentin Walleze4477002017-12-01 14:39:58 -05002859 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002860 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002861 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002862 return false;
2863 }
2864
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002865 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002866
2867 if (buffer == nullptr)
2868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002869 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002870 return false;
2871 }
2872
2873 if (access != GL_WRITE_ONLY_OES)
2874 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002875 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002876 return false;
2877 }
2878
2879 if (buffer->isMapped())
2880 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002881 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002882 return false;
2883 }
2884
Geoff Lang79f71042017-08-14 16:43:43 -04002885 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002886}
2887
Corentin Wallez336129f2017-10-17 15:55:40 -04002888bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002889{
2890 if (!context->getExtensions().mapBuffer)
2891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002892 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002893 return false;
2894 }
2895
2896 return ValidateUnmapBufferBase(context, target);
2897}
2898
2899bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002900 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002901 GLintptr offset,
2902 GLsizeiptr length,
2903 GLbitfield access)
2904{
2905 if (!context->getExtensions().mapBufferRange)
2906 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002907 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002908 return false;
2909 }
2910
2911 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2912}
2913
Corentin Wallez336129f2017-10-17 15:55:40 -04002914bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002915{
2916 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2917 ASSERT(buffer != nullptr);
2918
2919 // Check if this buffer is currently being used as a transform feedback output buffer
2920 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2921 if (transformFeedback != nullptr && transformFeedback->isActive())
2922 {
2923 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2924 {
2925 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2926 if (transformFeedbackBuffer.get() == buffer)
2927 {
2928 context->handleError(InvalidOperation()
2929 << "Buffer is currently bound for transform feedback.");
2930 return false;
2931 }
2932 }
2933 }
2934
James Darpiniane8a93c62018-01-04 18:02:24 -08002935 if (context->getExtensions().webglCompatibility &&
2936 buffer->isBoundForTransformFeedbackAndOtherUse())
2937 {
2938 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2939 return false;
2940 }
2941
Geoff Lang79f71042017-08-14 16:43:43 -04002942 return true;
2943}
2944
Olli Etuaho4f667482016-03-30 15:56:35 +03002945bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002946 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002947 GLintptr offset,
2948 GLsizeiptr length)
2949{
2950 if (!context->getExtensions().mapBufferRange)
2951 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002952 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002953 return false;
2954 }
2955
2956 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2957}
2958
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002959bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002960{
2961 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002962 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002963 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002964 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002965 return false;
2966 }
2967
Geoff Langf41a7152016-09-19 15:11:17 -04002968 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2969 !context->isTextureGenerated(texture))
2970 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002971 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002972 return false;
2973 }
2974
Ian Ewell54f87462016-03-10 13:47:21 -05002975 switch (target)
2976 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002977 case TextureType::_2D:
2978 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002979 break;
2980
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002981 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002982 if (!context->getExtensions().textureRectangle)
2983 {
2984 context->handleError(InvalidEnum()
2985 << "Context does not support GL_ANGLE_texture_rectangle");
2986 return false;
2987 }
2988 break;
2989
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002990 case TextureType::_3D:
2991 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002992 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002993 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002994 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002995 return false;
2996 }
2997 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002998
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002999 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003000 if (context->getClientVersion() < Version(3, 1))
3001 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003002 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003003 return false;
3004 }
Geoff Lang3b573612016-10-31 14:08:10 -04003005 break;
3006
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003007 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003008 if (!context->getExtensions().eglImageExternal &&
3009 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003011 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003012 return false;
3013 }
3014 break;
3015 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003016 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003017 return false;
3018 }
3019
3020 return true;
3021}
3022
Geoff Langd8605522016-04-13 10:19:12 -04003023bool ValidateBindUniformLocationCHROMIUM(Context *context,
3024 GLuint program,
3025 GLint location,
3026 const GLchar *name)
3027{
3028 if (!context->getExtensions().bindUniformLocation)
3029 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003030 context->handleError(InvalidOperation()
3031 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003032 return false;
3033 }
3034
3035 Program *programObject = GetValidProgram(context, program);
3036 if (!programObject)
3037 {
3038 return false;
3039 }
3040
3041 if (location < 0)
3042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003043 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003044 return false;
3045 }
3046
3047 const Caps &caps = context->getCaps();
3048 if (static_cast<size_t>(location) >=
3049 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3050 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003051 context->handleError(InvalidValue() << "Location must be less than "
3052 "(MAX_VERTEX_UNIFORM_VECTORS + "
3053 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003054 return false;
3055 }
3056
Geoff Langfc32e8b2017-05-31 14:16:59 -04003057 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3058 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003059 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003060 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003061 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003062 return false;
3063 }
3064
Geoff Langd8605522016-04-13 10:19:12 -04003065 if (strncmp(name, "gl_", 3) == 0)
3066 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003067 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003068 return false;
3069 }
3070
3071 return true;
3072}
3073
Jamie Madille2e406c2016-06-02 13:04:10 -04003074bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003075{
3076 if (!context->getExtensions().framebufferMixedSamples)
3077 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003078 context->handleError(InvalidOperation()
3079 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003080 return false;
3081 }
3082 switch (components)
3083 {
3084 case GL_RGB:
3085 case GL_RGBA:
3086 case GL_ALPHA:
3087 case GL_NONE:
3088 break;
3089 default:
3090 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003091 InvalidEnum()
3092 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003093 return false;
3094 }
3095
3096 return true;
3097}
3098
Sami Väisänene45e53b2016-05-25 10:36:04 +03003099// CHROMIUM_path_rendering
3100
Jamie Madill007530e2017-12-28 14:27:04 -05003101bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003102{
Jamie Madill007530e2017-12-28 14:27:04 -05003103 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003104 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003105 return false;
3106 }
Jamie Madill007530e2017-12-28 14:27:04 -05003107
Sami Väisänene45e53b2016-05-25 10:36:04 +03003108 if (matrix == nullptr)
3109 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003110 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111 return false;
3112 }
Jamie Madill007530e2017-12-28 14:27:04 -05003113
Sami Väisänene45e53b2016-05-25 10:36:04 +03003114 return true;
3115}
3116
Jamie Madill007530e2017-12-28 14:27:04 -05003117bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003118{
Jamie Madill007530e2017-12-28 14:27:04 -05003119 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003120}
3121
Jamie Madill007530e2017-12-28 14:27:04 -05003122bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003123{
3124 if (!context->getExtensions().pathRendering)
3125 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003126 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003127 return false;
3128 }
3129
3130 // range = 0 is undefined in NV_path_rendering.
3131 // we add stricter semantic check here and require a non zero positive range.
3132 if (range <= 0)
3133 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003134 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003135 return false;
3136 }
3137
3138 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3139 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003140 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003141 return false;
3142 }
3143
3144 return true;
3145}
3146
Jamie Madill007530e2017-12-28 14:27:04 -05003147bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003148{
3149 if (!context->getExtensions().pathRendering)
3150 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003151 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003152 return false;
3153 }
3154
3155 // range = 0 is undefined in NV_path_rendering.
3156 // we add stricter semantic check here and require a non zero positive range.
3157 if (range <= 0)
3158 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003159 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003160 return false;
3161 }
3162
3163 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3164 checkedRange += range;
3165
3166 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3167 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003168 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003169 return false;
3170 }
3171 return true;
3172}
3173
Jamie Madill007530e2017-12-28 14:27:04 -05003174bool ValidatePathCommandsCHROMIUM(Context *context,
3175 GLuint path,
3176 GLsizei numCommands,
3177 const GLubyte *commands,
3178 GLsizei numCoords,
3179 GLenum coordType,
3180 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181{
3182 if (!context->getExtensions().pathRendering)
3183 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003184 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003185 return false;
3186 }
Brandon Jones59770802018-04-02 13:18:42 -07003187 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003188 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003189 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003190 return false;
3191 }
3192
3193 if (numCommands < 0)
3194 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003195 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003196 return false;
3197 }
3198 else if (numCommands > 0)
3199 {
3200 if (!commands)
3201 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003202 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003203 return false;
3204 }
3205 }
3206
3207 if (numCoords < 0)
3208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003209 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003210 return false;
3211 }
3212 else if (numCoords > 0)
3213 {
3214 if (!coords)
3215 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003216 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003217 return false;
3218 }
3219 }
3220
3221 std::uint32_t coordTypeSize = 0;
3222 switch (coordType)
3223 {
3224 case GL_BYTE:
3225 coordTypeSize = sizeof(GLbyte);
3226 break;
3227
3228 case GL_UNSIGNED_BYTE:
3229 coordTypeSize = sizeof(GLubyte);
3230 break;
3231
3232 case GL_SHORT:
3233 coordTypeSize = sizeof(GLshort);
3234 break;
3235
3236 case GL_UNSIGNED_SHORT:
3237 coordTypeSize = sizeof(GLushort);
3238 break;
3239
3240 case GL_FLOAT:
3241 coordTypeSize = sizeof(GLfloat);
3242 break;
3243
3244 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003245 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003246 return false;
3247 }
3248
3249 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3250 checkedSize += (coordTypeSize * numCoords);
3251 if (!checkedSize.IsValid())
3252 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003253 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003254 return false;
3255 }
3256
3257 // early return skips command data validation when it doesn't exist.
3258 if (!commands)
3259 return true;
3260
3261 GLsizei expectedNumCoords = 0;
3262 for (GLsizei i = 0; i < numCommands; ++i)
3263 {
3264 switch (commands[i])
3265 {
3266 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3267 break;
3268 case GL_MOVE_TO_CHROMIUM:
3269 case GL_LINE_TO_CHROMIUM:
3270 expectedNumCoords += 2;
3271 break;
3272 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3273 expectedNumCoords += 4;
3274 break;
3275 case GL_CUBIC_CURVE_TO_CHROMIUM:
3276 expectedNumCoords += 6;
3277 break;
3278 case GL_CONIC_CURVE_TO_CHROMIUM:
3279 expectedNumCoords += 5;
3280 break;
3281 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003282 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003283 return false;
3284 }
3285 }
3286 if (expectedNumCoords != numCoords)
3287 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003288 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003289 return false;
3290 }
3291
3292 return true;
3293}
3294
Jamie Madill007530e2017-12-28 14:27:04 -05003295bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003296{
3297 if (!context->getExtensions().pathRendering)
3298 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003299 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003300 return false;
3301 }
Brandon Jones59770802018-04-02 13:18:42 -07003302 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003303 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003304 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003305 return false;
3306 }
3307
3308 switch (pname)
3309 {
3310 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3311 if (value < 0.0f)
3312 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003313 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003314 return false;
3315 }
3316 break;
3317 case GL_PATH_END_CAPS_CHROMIUM:
3318 switch (static_cast<GLenum>(value))
3319 {
3320 case GL_FLAT_CHROMIUM:
3321 case GL_SQUARE_CHROMIUM:
3322 case GL_ROUND_CHROMIUM:
3323 break;
3324 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003325 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003326 return false;
3327 }
3328 break;
3329 case GL_PATH_JOIN_STYLE_CHROMIUM:
3330 switch (static_cast<GLenum>(value))
3331 {
3332 case GL_MITER_REVERT_CHROMIUM:
3333 case GL_BEVEL_CHROMIUM:
3334 case GL_ROUND_CHROMIUM:
3335 break;
3336 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003337 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003338 return false;
3339 }
Nico Weber41b072b2018-02-09 10:01:32 -05003340 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003341 case GL_PATH_MITER_LIMIT_CHROMIUM:
3342 if (value < 0.0f)
3343 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003344 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003345 return false;
3346 }
3347 break;
3348
3349 case GL_PATH_STROKE_BOUND_CHROMIUM:
3350 // no errors, only clamping.
3351 break;
3352
3353 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003354 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003355 return false;
3356 }
3357 return true;
3358}
3359
Jamie Madill007530e2017-12-28 14:27:04 -05003360bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3361{
3362 // TODO(jmadill): Use proper clamping cast.
3363 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3364}
3365
3366bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003367{
3368 if (!context->getExtensions().pathRendering)
3369 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003370 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003371 return false;
3372 }
3373
Brandon Jones59770802018-04-02 13:18:42 -07003374 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003375 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003376 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003377 return false;
3378 }
3379 if (!value)
3380 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003381 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003382 return false;
3383 }
3384
3385 switch (pname)
3386 {
3387 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3388 case GL_PATH_END_CAPS_CHROMIUM:
3389 case GL_PATH_JOIN_STYLE_CHROMIUM:
3390 case GL_PATH_MITER_LIMIT_CHROMIUM:
3391 case GL_PATH_STROKE_BOUND_CHROMIUM:
3392 break;
3393
3394 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003395 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003396 return false;
3397 }
3398
3399 return true;
3400}
3401
Jamie Madill007530e2017-12-28 14:27:04 -05003402bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3403{
3404 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3405 reinterpret_cast<GLfloat *>(value));
3406}
3407
3408bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003409{
3410 if (!context->getExtensions().pathRendering)
3411 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003412 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003413 return false;
3414 }
3415
3416 switch (func)
3417 {
3418 case GL_NEVER:
3419 case GL_ALWAYS:
3420 case GL_LESS:
3421 case GL_LEQUAL:
3422 case GL_EQUAL:
3423 case GL_GEQUAL:
3424 case GL_GREATER:
3425 case GL_NOTEQUAL:
3426 break;
3427 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003428 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003429 return false;
3430 }
3431
3432 return true;
3433}
3434
3435// Note that the spec specifies that for the path drawing commands
3436// if the path object is not an existing path object the command
3437// does nothing and no error is generated.
3438// However if the path object exists but has not been specified any
3439// commands then an error is generated.
3440
Jamie Madill007530e2017-12-28 14:27:04 -05003441bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003442{
3443 if (!context->getExtensions().pathRendering)
3444 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003445 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003446 return false;
3447 }
Brandon Jones59770802018-04-02 13:18:42 -07003448 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003449 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003450 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003451 return false;
3452 }
3453
3454 switch (fillMode)
3455 {
3456 case GL_COUNT_UP_CHROMIUM:
3457 case GL_COUNT_DOWN_CHROMIUM:
3458 break;
3459 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003460 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003461 return false;
3462 }
3463
3464 if (!isPow2(mask + 1))
3465 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003466 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003467 return false;
3468 }
3469
3470 return true;
3471}
3472
Jamie Madill007530e2017-12-28 14:27:04 -05003473bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474{
3475 if (!context->getExtensions().pathRendering)
3476 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003477 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003478 return false;
3479 }
Brandon Jones59770802018-04-02 13:18:42 -07003480 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003482 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003483 return false;
3484 }
3485
3486 return true;
3487}
3488
Brandon Jonesd1049182018-03-28 10:02:20 -07003489bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3490{
3491 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3492}
3493
3494bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3495{
3496 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3497}
3498
Jamie Madill007530e2017-12-28 14:27:04 -05003499bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003500{
3501 if (!context->getExtensions().pathRendering)
3502 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003503 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003504 return false;
3505 }
Brandon Jones59770802018-04-02 13:18:42 -07003506 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003507 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003509 return false;
3510 }
3511
3512 switch (coverMode)
3513 {
3514 case GL_CONVEX_HULL_CHROMIUM:
3515 case GL_BOUNDING_BOX_CHROMIUM:
3516 break;
3517 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003518 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003519 return false;
3520 }
3521 return true;
3522}
3523
Jamie Madill007530e2017-12-28 14:27:04 -05003524bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3525 GLuint path,
3526 GLenum fillMode,
3527 GLuint mask,
3528 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003529{
Jamie Madill007530e2017-12-28 14:27:04 -05003530 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3531 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003532}
3533
Jamie Madill007530e2017-12-28 14:27:04 -05003534bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3535 GLuint path,
3536 GLint reference,
3537 GLuint mask,
3538 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003539{
Jamie Madill007530e2017-12-28 14:27:04 -05003540 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3541 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542}
3543
Brandon Jonesd1049182018-03-28 10:02:20 -07003544bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003545{
3546 if (!context->getExtensions().pathRendering)
3547 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003548 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003549 return false;
3550 }
3551 return true;
3552}
3553
Jamie Madill007530e2017-12-28 14:27:04 -05003554bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3555 GLsizei numPaths,
3556 GLenum pathNameType,
3557 const void *paths,
3558 GLuint pathBase,
3559 GLenum coverMode,
3560 GLenum transformType,
3561 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003562{
3563 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3564 transformType, transformValues))
3565 return false;
3566
3567 switch (coverMode)
3568 {
3569 case GL_CONVEX_HULL_CHROMIUM:
3570 case GL_BOUNDING_BOX_CHROMIUM:
3571 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3572 break;
3573 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003574 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003575 return false;
3576 }
3577
3578 return true;
3579}
3580
Jamie Madill007530e2017-12-28 14:27:04 -05003581bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3582 GLsizei numPaths,
3583 GLenum pathNameType,
3584 const void *paths,
3585 GLuint pathBase,
3586 GLenum coverMode,
3587 GLenum transformType,
3588 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003589{
3590 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3591 transformType, transformValues))
3592 return false;
3593
3594 switch (coverMode)
3595 {
3596 case GL_CONVEX_HULL_CHROMIUM:
3597 case GL_BOUNDING_BOX_CHROMIUM:
3598 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3599 break;
3600 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003602 return false;
3603 }
3604
3605 return true;
3606}
3607
Jamie Madill007530e2017-12-28 14:27:04 -05003608bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3609 GLsizei numPaths,
3610 GLenum pathNameType,
3611 const void *paths,
3612 GLuint pathBase,
3613 GLenum fillMode,
3614 GLuint mask,
3615 GLenum transformType,
3616 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003617{
3618
3619 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3620 transformType, transformValues))
3621 return false;
3622
3623 switch (fillMode)
3624 {
3625 case GL_COUNT_UP_CHROMIUM:
3626 case GL_COUNT_DOWN_CHROMIUM:
3627 break;
3628 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003629 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003630 return false;
3631 }
3632 if (!isPow2(mask + 1))
3633 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003634 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003635 return false;
3636 }
3637 return true;
3638}
3639
Jamie Madill007530e2017-12-28 14:27:04 -05003640bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3641 GLsizei numPaths,
3642 GLenum pathNameType,
3643 const void *paths,
3644 GLuint pathBase,
3645 GLint reference,
3646 GLuint mask,
3647 GLenum transformType,
3648 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003649{
3650 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3651 transformType, transformValues))
3652 return false;
3653
3654 // no more validation here.
3655
3656 return true;
3657}
3658
Jamie Madill007530e2017-12-28 14:27:04 -05003659bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3660 GLsizei numPaths,
3661 GLenum pathNameType,
3662 const void *paths,
3663 GLuint pathBase,
3664 GLenum fillMode,
3665 GLuint mask,
3666 GLenum coverMode,
3667 GLenum transformType,
3668 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003669{
3670 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3671 transformType, transformValues))
3672 return false;
3673
3674 switch (coverMode)
3675 {
3676 case GL_CONVEX_HULL_CHROMIUM:
3677 case GL_BOUNDING_BOX_CHROMIUM:
3678 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3679 break;
3680 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003682 return false;
3683 }
3684
3685 switch (fillMode)
3686 {
3687 case GL_COUNT_UP_CHROMIUM:
3688 case GL_COUNT_DOWN_CHROMIUM:
3689 break;
3690 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003691 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003692 return false;
3693 }
3694 if (!isPow2(mask + 1))
3695 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003696 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003697 return false;
3698 }
3699
3700 return true;
3701}
3702
Jamie Madill007530e2017-12-28 14:27:04 -05003703bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3704 GLsizei numPaths,
3705 GLenum pathNameType,
3706 const void *paths,
3707 GLuint pathBase,
3708 GLint reference,
3709 GLuint mask,
3710 GLenum coverMode,
3711 GLenum transformType,
3712 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003713{
3714 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3715 transformType, transformValues))
3716 return false;
3717
3718 switch (coverMode)
3719 {
3720 case GL_CONVEX_HULL_CHROMIUM:
3721 case GL_BOUNDING_BOX_CHROMIUM:
3722 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3723 break;
3724 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003725 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003726 return false;
3727 }
3728
3729 return true;
3730}
3731
Jamie Madill007530e2017-12-28 14:27:04 -05003732bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3733 GLuint program,
3734 GLint location,
3735 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003736{
3737 if (!context->getExtensions().pathRendering)
3738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003739 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003740 return false;
3741 }
3742
3743 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3744 if (location >= MaxLocation)
3745 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003746 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003747 return false;
3748 }
3749
3750 const auto *programObject = context->getProgram(program);
3751 if (!programObject)
3752 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003753 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003754 return false;
3755 }
3756
3757 if (!name)
3758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003759 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003760 return false;
3761 }
3762
3763 if (angle::BeginsWith(name, "gl_"))
3764 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003765 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003766 return false;
3767 }
3768
3769 return true;
3770}
3771
Jamie Madill007530e2017-12-28 14:27:04 -05003772bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3773 GLuint program,
3774 GLint location,
3775 GLenum genMode,
3776 GLint components,
3777 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003778{
3779 if (!context->getExtensions().pathRendering)
3780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003781 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003782 return false;
3783 }
3784
3785 const auto *programObject = context->getProgram(program);
3786 if (!programObject || programObject->isFlaggedForDeletion())
3787 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003788 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003789 return false;
3790 }
3791
3792 if (!programObject->isLinked())
3793 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003794 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003795 return false;
3796 }
3797
3798 switch (genMode)
3799 {
3800 case GL_NONE:
3801 if (components != 0)
3802 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003803 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003804 return false;
3805 }
3806 break;
3807
3808 case GL_OBJECT_LINEAR_CHROMIUM:
3809 case GL_EYE_LINEAR_CHROMIUM:
3810 case GL_CONSTANT_CHROMIUM:
3811 if (components < 1 || components > 4)
3812 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003813 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003814 return false;
3815 }
3816 if (!coeffs)
3817 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003818 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003819 return false;
3820 }
3821 break;
3822
3823 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003824 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003825 return false;
3826 }
3827
3828 // If the location is -1 then the command is silently ignored
3829 // and no further validation is needed.
3830 if (location == -1)
3831 return true;
3832
Jamie Madillbd044ed2017-06-05 12:59:21 -04003833 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003834
3835 if (!binding.valid)
3836 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003837 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003838 return false;
3839 }
3840
3841 if (binding.type != GL_NONE)
3842 {
3843 GLint expectedComponents = 0;
3844 switch (binding.type)
3845 {
3846 case GL_FLOAT:
3847 expectedComponents = 1;
3848 break;
3849 case GL_FLOAT_VEC2:
3850 expectedComponents = 2;
3851 break;
3852 case GL_FLOAT_VEC3:
3853 expectedComponents = 3;
3854 break;
3855 case GL_FLOAT_VEC4:
3856 expectedComponents = 4;
3857 break;
3858 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003859 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003860 InvalidOperation()
3861 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003862 return false;
3863 }
3864 if (expectedComponents != components && genMode != GL_NONE)
3865 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003866 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003867 return false;
3868 }
3869 }
3870 return true;
3871}
3872
Geoff Lang97073d12016-04-20 10:42:34 -07003873bool ValidateCopyTextureCHROMIUM(Context *context,
3874 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003875 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003876 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003877 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003878 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003879 GLint internalFormat,
3880 GLenum destType,
3881 GLboolean unpackFlipY,
3882 GLboolean unpackPremultiplyAlpha,
3883 GLboolean unpackUnmultiplyAlpha)
3884{
3885 if (!context->getExtensions().copyTexture)
3886 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003887 context->handleError(InvalidOperation()
3888 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003889 return false;
3890 }
3891
Geoff Lang4f0e0032017-05-01 16:04:35 -04003892 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003893 if (source == nullptr)
3894 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003895 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003896 return false;
3897 }
3898
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003899 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003900 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003901 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003902 return false;
3903 }
3904
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003905 TextureType sourceType = source->getType();
3906 ASSERT(sourceType != TextureType::CubeMap);
3907 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003908
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003909 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003910 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003911 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003912 return false;
3913 }
3914
Geoff Lang4f0e0032017-05-01 16:04:35 -04003915 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3916 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3917 if (sourceWidth == 0 || sourceHeight == 0)
3918 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003919 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003920 return false;
3921 }
3922
3923 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3924 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003925 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003926 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003927 return false;
3928 }
3929
Geoff Lang63458a32017-10-30 15:16:53 -04003930 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3931 {
3932 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3933 return false;
3934 }
3935
Geoff Lang4f0e0032017-05-01 16:04:35 -04003936 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003937 if (dest == nullptr)
3938 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003939 context->handleError(InvalidValue()
3940 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003941 return false;
3942 }
3943
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003944 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003945 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003946 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003947 return false;
3948 }
3949
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003950 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003951 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003952 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003953 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003954 return false;
3955 }
3956
Geoff Lang97073d12016-04-20 10:42:34 -07003957 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3958 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003959 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003960 return false;
3961 }
3962
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003963 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003964 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003965 context->handleError(
3966 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003967 return false;
3968 }
3969
Geoff Lang97073d12016-04-20 10:42:34 -07003970 if (dest->getImmutableFormat())
3971 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003972 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003973 return false;
3974 }
3975
3976 return true;
3977}
3978
3979bool ValidateCopySubTextureCHROMIUM(Context *context,
3980 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003981 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003982 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003983 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003984 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003985 GLint xoffset,
3986 GLint yoffset,
3987 GLint x,
3988 GLint y,
3989 GLsizei width,
3990 GLsizei height,
3991 GLboolean unpackFlipY,
3992 GLboolean unpackPremultiplyAlpha,
3993 GLboolean unpackUnmultiplyAlpha)
3994{
3995 if (!context->getExtensions().copyTexture)
3996 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003997 context->handleError(InvalidOperation()
3998 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003999 return false;
4000 }
4001
Geoff Lang4f0e0032017-05-01 16:04:35 -04004002 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004003 if (source == nullptr)
4004 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004005 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004006 return false;
4007 }
4008
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004009 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004011 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004012 return false;
4013 }
4014
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004015 TextureType sourceType = source->getType();
4016 ASSERT(sourceType != TextureType::CubeMap);
4017 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004018
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004019 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004020 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004021 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004022 return false;
4023 }
4024
4025 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4026 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004027 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004028 context->handleError(InvalidValue()
4029 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004030 return false;
4031 }
4032
4033 if (x < 0 || y < 0)
4034 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004035 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004036 return false;
4037 }
4038
4039 if (width < 0 || height < 0)
4040 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004041 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004042 return false;
4043 }
4044
Geoff Lang4f0e0032017-05-01 16:04:35 -04004045 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4046 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004047 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004048 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004049 return false;
4050 }
4051
Geoff Lang4f0e0032017-05-01 16:04:35 -04004052 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4053 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004054 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004055 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004056 return false;
4057 }
4058
Geoff Lang63458a32017-10-30 15:16:53 -04004059 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4060 {
4061 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4062 return false;
4063 }
4064
Geoff Lang4f0e0032017-05-01 16:04:35 -04004065 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004066 if (dest == nullptr)
4067 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004068 context->handleError(InvalidValue()
4069 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004070 return false;
4071 }
4072
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004073 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004075 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004076 return false;
4077 }
4078
Brandon Jones28783792018-03-05 09:37:32 -08004079 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4080 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004081 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004082 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004083 return false;
4084 }
4085
Geoff Lang4f0e0032017-05-01 16:04:35 -04004086 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4087 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004088 context
4089 ->handleError(InvalidOperation()
4090 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004091 return false;
4092 }
4093
4094 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4095 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004096 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004097 context->handleError(InvalidOperation()
4098 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004099 return false;
4100 }
4101
4102 if (xoffset < 0 || yoffset < 0)
4103 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004104 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004105 return false;
4106 }
4107
Geoff Lang4f0e0032017-05-01 16:04:35 -04004108 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4109 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004110 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004111 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004112 return false;
4113 }
4114
4115 return true;
4116}
4117
Geoff Lang47110bf2016-04-20 11:13:22 -07004118bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4119{
4120 if (!context->getExtensions().copyCompressedTexture)
4121 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004122 context->handleError(InvalidOperation()
4123 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004124 return false;
4125 }
4126
4127 const gl::Texture *source = context->getTexture(sourceId);
4128 if (source == nullptr)
4129 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004130 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004131 return false;
4132 }
4133
Corentin Wallez99d492c2018-02-27 15:17:10 -05004134 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004135 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004136 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004137 return false;
4138 }
4139
Corentin Wallez99d492c2018-02-27 15:17:10 -05004140 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4141 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004143 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004144 return false;
4145 }
4146
Corentin Wallez99d492c2018-02-27 15:17:10 -05004147 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004148 if (!sourceFormat.info->compressed)
4149 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004150 context->handleError(InvalidOperation()
4151 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004152 return false;
4153 }
4154
4155 const gl::Texture *dest = context->getTexture(destId);
4156 if (dest == nullptr)
4157 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004158 context->handleError(InvalidValue()
4159 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004160 return false;
4161 }
4162
Corentin Wallez99d492c2018-02-27 15:17:10 -05004163 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004164 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004165 context->handleError(InvalidValue()
4166 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004167 return false;
4168 }
4169
4170 if (dest->getImmutableFormat())
4171 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004172 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004173 return false;
4174 }
4175
4176 return true;
4177}
4178
Jiawei Shao385b3e02018-03-21 09:43:28 +08004179bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004180{
4181 switch (type)
4182 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004183 case ShaderType::Vertex:
4184 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004185 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004186
Jiawei Shao385b3e02018-03-21 09:43:28 +08004187 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004188 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004189 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004190 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004191 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004192 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004193 break;
4194
Jiawei Shao385b3e02018-03-21 09:43:28 +08004195 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004196 if (!context->getExtensions().geometryShader)
4197 {
4198 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4199 return false;
4200 }
4201 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004202 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004203 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004204 return false;
4205 }
Jamie Madill29639852016-09-02 15:00:09 -04004206
4207 return true;
4208}
4209
Jamie Madill5b772312018-03-08 20:28:32 -05004210bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004211 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004212 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004213 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004214 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004215{
4216 if (size < 0)
4217 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004218 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004219 return false;
4220 }
4221
4222 switch (usage)
4223 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004224 case BufferUsage::StreamDraw:
4225 case BufferUsage::StaticDraw:
4226 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004227 break;
4228
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004229 case BufferUsage::StreamRead:
4230 case BufferUsage::StaticRead:
4231 case BufferUsage::DynamicRead:
4232 case BufferUsage::StreamCopy:
4233 case BufferUsage::StaticCopy:
4234 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004235 if (context->getClientMajorVersion() < 3)
4236 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004237 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004238 return false;
4239 }
4240 break;
4241
4242 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004243 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004244 return false;
4245 }
4246
Corentin Walleze4477002017-12-01 14:39:58 -05004247 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004248 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004249 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004250 return false;
4251 }
4252
4253 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4254
4255 if (!buffer)
4256 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004257 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004258 return false;
4259 }
4260
James Darpiniane8a93c62018-01-04 18:02:24 -08004261 if (context->getExtensions().webglCompatibility &&
4262 buffer->isBoundForTransformFeedbackAndOtherUse())
4263 {
4264 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4265 return false;
4266 }
4267
Jamie Madill29639852016-09-02 15:00:09 -04004268 return true;
4269}
4270
Jamie Madill5b772312018-03-08 20:28:32 -05004271bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004272 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004273 GLintptr offset,
4274 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004275 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004276{
Brandon Jones6cad5662017-06-14 13:25:13 -07004277 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004278 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004279 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4280 return false;
4281 }
4282
4283 if (offset < 0)
4284 {
4285 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004286 return false;
4287 }
4288
Corentin Walleze4477002017-12-01 14:39:58 -05004289 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004290 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004291 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004292 return false;
4293 }
4294
4295 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4296
4297 if (!buffer)
4298 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004299 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004300 return false;
4301 }
4302
4303 if (buffer->isMapped())
4304 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004305 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004306 return false;
4307 }
4308
James Darpiniane8a93c62018-01-04 18:02:24 -08004309 if (context->getExtensions().webglCompatibility &&
4310 buffer->isBoundForTransformFeedbackAndOtherUse())
4311 {
4312 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4313 return false;
4314 }
4315
Jamie Madill29639852016-09-02 15:00:09 -04004316 // Check for possible overflow of size + offset
4317 angle::CheckedNumeric<size_t> checkedSize(size);
4318 checkedSize += offset;
4319 if (!checkedSize.IsValid())
4320 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004321 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004322 return false;
4323 }
4324
4325 if (size + offset > buffer->getSize())
4326 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004327 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004328 return false;
4329 }
4330
Martin Radev4c4c8e72016-08-04 12:25:34 +03004331 return true;
4332}
4333
Geoff Lang111a99e2017-10-17 10:58:41 -04004334bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004335{
Geoff Langc339c4e2016-11-29 10:37:36 -05004336 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004337 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004338 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004339 return false;
4340 }
4341
Geoff Lang111a99e2017-10-17 10:58:41 -04004342 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004343 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004344 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004345 return false;
4346 }
4347
4348 return true;
4349}
4350
Jamie Madill5b772312018-03-08 20:28:32 -05004351bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004352{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004353 if (context->getClientMajorVersion() < 2)
4354 {
4355 return ValidateMultitextureUnit(context, texture);
4356 }
4357
Jamie Madillef300b12016-10-07 15:12:09 -04004358 if (texture < GL_TEXTURE0 ||
4359 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4360 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004361 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004362 return false;
4363 }
4364
4365 return true;
4366}
4367
Jamie Madill5b772312018-03-08 20:28:32 -05004368bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004369{
4370 Program *programObject = GetValidProgram(context, program);
4371 if (!programObject)
4372 {
4373 return false;
4374 }
4375
4376 Shader *shaderObject = GetValidShader(context, shader);
4377 if (!shaderObject)
4378 {
4379 return false;
4380 }
4381
Jiawei Shao385b3e02018-03-21 09:43:28 +08004382 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004383 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004384 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4385 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004386 }
4387
4388 return true;
4389}
4390
Jamie Madill5b772312018-03-08 20:28:32 -05004391bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004392{
4393 if (index >= MAX_VERTEX_ATTRIBS)
4394 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004395 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004396 return false;
4397 }
4398
4399 if (strncmp(name, "gl_", 3) == 0)
4400 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004401 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004402 return false;
4403 }
4404
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004405 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004406 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004407 const size_t length = strlen(name);
4408
4409 if (!IsValidESSLString(name, length))
4410 {
4411 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4412 // for shader-related entry points
4413 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4414 return false;
4415 }
4416
4417 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4418 {
4419 return false;
4420 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004421 }
4422
Jamie Madill01a80ee2016-11-07 12:06:18 -05004423 return GetValidProgram(context, program) != nullptr;
4424}
4425
Jamie Madill5b772312018-03-08 20:28:32 -05004426bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004427{
Corentin Walleze4477002017-12-01 14:39:58 -05004428 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004429 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004430 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004431 return false;
4432 }
4433
4434 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4435 !context->isBufferGenerated(buffer))
4436 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004437 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004438 return false;
4439 }
4440
4441 return true;
4442}
4443
Jamie Madill5b772312018-03-08 20:28:32 -05004444bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004445{
Geoff Lange8afa902017-09-27 15:00:43 -04004446 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004447 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004448 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004449 return false;
4450 }
4451
4452 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4453 !context->isFramebufferGenerated(framebuffer))
4454 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004455 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004456 return false;
4457 }
4458
4459 return true;
4460}
4461
Jamie Madill5b772312018-03-08 20:28:32 -05004462bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004463{
4464 if (target != GL_RENDERBUFFER)
4465 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004466 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004467 return false;
4468 }
4469
4470 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4471 !context->isRenderbufferGenerated(renderbuffer))
4472 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004473 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004474 return false;
4475 }
4476
4477 return true;
4478}
4479
Jamie Madill5b772312018-03-08 20:28:32 -05004480static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004481{
4482 switch (mode)
4483 {
4484 case GL_FUNC_ADD:
4485 case GL_FUNC_SUBTRACT:
4486 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004487 return true;
4488
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004489 case GL_MIN:
4490 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004491 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004492
4493 default:
4494 return false;
4495 }
4496}
4497
Jamie Madill5b772312018-03-08 20:28:32 -05004498bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004499{
4500 return true;
4501}
4502
Jamie Madill5b772312018-03-08 20:28:32 -05004503bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004504{
Geoff Lang50cac572017-09-26 17:37:43 -04004505 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004506 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004507 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004508 return false;
4509 }
4510
4511 return true;
4512}
4513
Jamie Madill5b772312018-03-08 20:28:32 -05004514bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004515{
Geoff Lang50cac572017-09-26 17:37:43 -04004516 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004517 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004518 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004519 return false;
4520 }
4521
Geoff Lang50cac572017-09-26 17:37:43 -04004522 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004523 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004524 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004525 return false;
4526 }
4527
4528 return true;
4529}
4530
Jamie Madill5b772312018-03-08 20:28:32 -05004531bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004532{
4533 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4534}
4535
4536static bool ValidSrcBlendFunc(GLenum srcBlend)
4537{
4538 switch (srcBlend)
4539 {
4540 case GL_ZERO:
4541 case GL_ONE:
4542 case GL_SRC_COLOR:
4543 case GL_ONE_MINUS_SRC_COLOR:
4544 case GL_DST_COLOR:
4545 case GL_ONE_MINUS_DST_COLOR:
4546 case GL_SRC_ALPHA:
4547 case GL_ONE_MINUS_SRC_ALPHA:
4548 case GL_DST_ALPHA:
4549 case GL_ONE_MINUS_DST_ALPHA:
4550 case GL_CONSTANT_COLOR:
4551 case GL_ONE_MINUS_CONSTANT_COLOR:
4552 case GL_CONSTANT_ALPHA:
4553 case GL_ONE_MINUS_CONSTANT_ALPHA:
4554 case GL_SRC_ALPHA_SATURATE:
4555 return true;
4556
4557 default:
4558 return false;
4559 }
4560}
4561
4562static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4563{
4564 switch (dstBlend)
4565 {
4566 case GL_ZERO:
4567 case GL_ONE:
4568 case GL_SRC_COLOR:
4569 case GL_ONE_MINUS_SRC_COLOR:
4570 case GL_DST_COLOR:
4571 case GL_ONE_MINUS_DST_COLOR:
4572 case GL_SRC_ALPHA:
4573 case GL_ONE_MINUS_SRC_ALPHA:
4574 case GL_DST_ALPHA:
4575 case GL_ONE_MINUS_DST_ALPHA:
4576 case GL_CONSTANT_COLOR:
4577 case GL_ONE_MINUS_CONSTANT_COLOR:
4578 case GL_CONSTANT_ALPHA:
4579 case GL_ONE_MINUS_CONSTANT_ALPHA:
4580 return true;
4581
4582 case GL_SRC_ALPHA_SATURATE:
4583 return (contextMajorVersion >= 3);
4584
4585 default:
4586 return false;
4587 }
4588}
4589
Jamie Madill5b772312018-03-08 20:28:32 -05004590bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004591 GLenum srcRGB,
4592 GLenum dstRGB,
4593 GLenum srcAlpha,
4594 GLenum dstAlpha)
4595{
4596 if (!ValidSrcBlendFunc(srcRGB))
4597 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004598 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004599 return false;
4600 }
4601
4602 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4603 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004604 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004605 return false;
4606 }
4607
4608 if (!ValidSrcBlendFunc(srcAlpha))
4609 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004610 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004611 return false;
4612 }
4613
4614 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4615 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004616 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004617 return false;
4618 }
4619
Frank Henigman146e8a12017-03-02 23:22:37 -05004620 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4621 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004622 {
4623 bool constantColorUsed =
4624 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4625 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4626
4627 bool constantAlphaUsed =
4628 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4629 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4630
4631 if (constantColorUsed && constantAlphaUsed)
4632 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004633 const char *msg;
4634 if (context->getExtensions().webglCompatibility)
4635 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004636 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004637 }
4638 else
4639 {
4640 msg =
4641 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4642 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4643 "implementation.";
4644 ERR() << msg;
4645 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004646 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004647 return false;
4648 }
4649 }
4650
4651 return true;
4652}
4653
Geoff Langc339c4e2016-11-29 10:37:36 -05004654bool ValidateGetString(Context *context, GLenum name)
4655{
4656 switch (name)
4657 {
4658 case GL_VENDOR:
4659 case GL_RENDERER:
4660 case GL_VERSION:
4661 case GL_SHADING_LANGUAGE_VERSION:
4662 case GL_EXTENSIONS:
4663 break;
4664
4665 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4666 if (!context->getExtensions().requestExtension)
4667 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004668 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004669 return false;
4670 }
4671 break;
4672
4673 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004674 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004675 return false;
4676 }
4677
4678 return true;
4679}
4680
Jamie Madill5b772312018-03-08 20:28:32 -05004681bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004682{
4683 if (width <= 0.0f || isNaN(width))
4684 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004685 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004686 return false;
4687 }
4688
4689 return true;
4690}
4691
Jamie Madill5b772312018-03-08 20:28:32 -05004692bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004693 GLuint index,
4694 GLint size,
4695 GLenum type,
4696 GLboolean normalized,
4697 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004698 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004699{
Shao80957d92017-02-20 21:25:59 +08004700 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004701 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004702 return false;
4703 }
4704
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004705 if (stride < 0)
4706 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004707 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004708 return false;
4709 }
4710
Shao80957d92017-02-20 21:25:59 +08004711 const Caps &caps = context->getCaps();
4712 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004713 {
Shao80957d92017-02-20 21:25:59 +08004714 if (stride > caps.maxVertexAttribStride)
4715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004716 context->handleError(InvalidValue()
4717 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004718 return false;
4719 }
4720
4721 if (index >= caps.maxVertexAttribBindings)
4722 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004723 context->handleError(InvalidValue()
4724 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004725 return false;
4726 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004727 }
4728
4729 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4730 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4731 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4732 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004733 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4734 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004735 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4736 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004737 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004738 context
4739 ->handleError(InvalidOperation()
4740 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004741 return false;
4742 }
4743
4744 if (context->getExtensions().webglCompatibility)
4745 {
4746 // WebGL 1.0 [Section 6.14] Fixed point support
4747 // The WebGL API does not support the GL_FIXED data type.
4748 if (type == GL_FIXED)
4749 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004750 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004751 return false;
4752 }
4753
Geoff Lang2d62ab72017-03-23 16:54:40 -04004754 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004755 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004756 return false;
4757 }
4758 }
4759
4760 return true;
4761}
4762
Jamie Madill5b772312018-03-08 20:28:32 -05004763bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004764{
4765 if (context->getExtensions().webglCompatibility && zNear > zFar)
4766 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004767 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004768 return false;
4769 }
4770
4771 return true;
4772}
4773
Jamie Madill5b772312018-03-08 20:28:32 -05004774bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004775 GLenum target,
4776 GLenum internalformat,
4777 GLsizei width,
4778 GLsizei height)
4779{
4780 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4781 height);
4782}
4783
Jamie Madill5b772312018-03-08 20:28:32 -05004784bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004785 GLenum target,
4786 GLsizei samples,
4787 GLenum internalformat,
4788 GLsizei width,
4789 GLsizei height)
4790{
4791 if (!context->getExtensions().framebufferMultisample)
4792 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004793 context->handleError(InvalidOperation()
4794 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004795 return false;
4796 }
4797
4798 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4799 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4800 // generated.
4801 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4802 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004803 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004804 return false;
4805 }
4806
4807 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4808 // the specified storage. This is different than ES 3.0 in which a sample number higher
4809 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4810 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4811 if (context->getClientMajorVersion() >= 3)
4812 {
4813 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4814 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4815 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004816 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004817 return false;
4818 }
4819 }
4820
4821 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4822 width, height);
4823}
4824
Jamie Madill5b772312018-03-08 20:28:32 -05004825bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004826{
Geoff Lange8afa902017-09-27 15:00:43 -04004827 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004828 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004829 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004830 return false;
4831 }
4832
4833 return true;
4834}
4835
Jamie Madill5b772312018-03-08 20:28:32 -05004836bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004837{
4838 return true;
4839}
4840
Jamie Madill5b772312018-03-08 20:28:32 -05004841bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004842{
4843 return true;
4844}
4845
Jamie Madill5b772312018-03-08 20:28:32 -05004846bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004847{
4848 return true;
4849}
4850
Jamie Madill5b772312018-03-08 20:28:32 -05004851bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004852 GLboolean red,
4853 GLboolean green,
4854 GLboolean blue,
4855 GLboolean alpha)
4856{
4857 return true;
4858}
4859
Jamie Madill5b772312018-03-08 20:28:32 -05004860bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004861{
4862 return true;
4863}
4864
Jamie Madill5b772312018-03-08 20:28:32 -05004865bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004866{
4867 return true;
4868}
4869
Jamie Madill5b772312018-03-08 20:28:32 -05004870bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004871{
4872 switch (mode)
4873 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004874 case CullFaceMode::Front:
4875 case CullFaceMode::Back:
4876 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004877 break;
4878
4879 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004880 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004881 return false;
4882 }
4883
4884 return true;
4885}
4886
Jamie Madill5b772312018-03-08 20:28:32 -05004887bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004888{
4889 if (program == 0)
4890 {
4891 return false;
4892 }
4893
4894 if (!context->getProgram(program))
4895 {
4896 if (context->getShader(program))
4897 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004898 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004899 return false;
4900 }
4901 else
4902 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004903 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004904 return false;
4905 }
4906 }
4907
4908 return true;
4909}
4910
Jamie Madill5b772312018-03-08 20:28:32 -05004911bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004912{
4913 if (shader == 0)
4914 {
4915 return false;
4916 }
4917
4918 if (!context->getShader(shader))
4919 {
4920 if (context->getProgram(shader))
4921 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004922 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004923 return false;
4924 }
4925 else
4926 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004927 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004928 return false;
4929 }
4930 }
4931
4932 return true;
4933}
4934
Jamie Madill5b772312018-03-08 20:28:32 -05004935bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004936{
4937 switch (func)
4938 {
4939 case GL_NEVER:
4940 case GL_ALWAYS:
4941 case GL_LESS:
4942 case GL_LEQUAL:
4943 case GL_EQUAL:
4944 case GL_GREATER:
4945 case GL_GEQUAL:
4946 case GL_NOTEQUAL:
4947 break;
4948
4949 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004950 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004951 return false;
4952 }
4953
4954 return true;
4955}
4956
Jamie Madill5b772312018-03-08 20:28:32 -05004957bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004958{
4959 return true;
4960}
4961
Jamie Madill5b772312018-03-08 20:28:32 -05004962bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004963{
4964 Program *programObject = GetValidProgram(context, program);
4965 if (!programObject)
4966 {
4967 return false;
4968 }
4969
4970 Shader *shaderObject = GetValidShader(context, shader);
4971 if (!shaderObject)
4972 {
4973 return false;
4974 }
4975
Jiawei Shao385b3e02018-03-21 09:43:28 +08004976 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004977 if (attachedShader != shaderObject)
4978 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004979 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004980 return false;
4981 }
4982
4983 return true;
4984}
4985
Jamie Madill5b772312018-03-08 20:28:32 -05004986bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004987{
4988 if (index >= MAX_VERTEX_ATTRIBS)
4989 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004990 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004991 return false;
4992 }
4993
4994 return true;
4995}
4996
Jamie Madill5b772312018-03-08 20:28:32 -05004997bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004998{
4999 if (index >= MAX_VERTEX_ATTRIBS)
5000 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005001 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005002 return false;
5003 }
5004
5005 return true;
5006}
5007
Jamie Madill5b772312018-03-08 20:28:32 -05005008bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005009{
5010 return true;
5011}
5012
Jamie Madill5b772312018-03-08 20:28:32 -05005013bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005014{
5015 return true;
5016}
5017
Jamie Madill5b772312018-03-08 20:28:32 -05005018bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005019{
5020 switch (mode)
5021 {
5022 case GL_CW:
5023 case GL_CCW:
5024 break;
5025 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005026 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005027 return false;
5028 }
5029
5030 return true;
5031}
5032
Jamie Madill5b772312018-03-08 20:28:32 -05005033bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005034 GLuint program,
5035 GLuint index,
5036 GLsizei bufsize,
5037 GLsizei *length,
5038 GLint *size,
5039 GLenum *type,
5040 GLchar *name)
5041{
5042 if (bufsize < 0)
5043 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005044 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005045 return false;
5046 }
5047
5048 Program *programObject = GetValidProgram(context, program);
5049
5050 if (!programObject)
5051 {
5052 return false;
5053 }
5054
5055 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5056 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005057 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005058 return false;
5059 }
5060
5061 return true;
5062}
5063
Jamie Madill5b772312018-03-08 20:28:32 -05005064bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005065 GLuint program,
5066 GLuint index,
5067 GLsizei bufsize,
5068 GLsizei *length,
5069 GLint *size,
5070 GLenum *type,
5071 GLchar *name)
5072{
5073 if (bufsize < 0)
5074 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005075 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005076 return false;
5077 }
5078
5079 Program *programObject = GetValidProgram(context, program);
5080
5081 if (!programObject)
5082 {
5083 return false;
5084 }
5085
5086 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5087 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005088 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005089 return false;
5090 }
5091
5092 return true;
5093}
5094
Jamie Madill5b772312018-03-08 20:28:32 -05005095bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005096 GLuint program,
5097 GLsizei maxcount,
5098 GLsizei *count,
5099 GLuint *shaders)
5100{
5101 if (maxcount < 0)
5102 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005103 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005104 return false;
5105 }
5106
5107 Program *programObject = GetValidProgram(context, program);
5108
5109 if (!programObject)
5110 {
5111 return false;
5112 }
5113
5114 return true;
5115}
5116
Jamie Madill5b772312018-03-08 20:28:32 -05005117bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005118{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005119 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5120 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005121 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005122 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005123 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005124 return false;
5125 }
5126
Jamie Madillc1d770e2017-04-13 17:31:24 -04005127 Program *programObject = GetValidProgram(context, program);
5128
5129 if (!programObject)
5130 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005131 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005132 return false;
5133 }
5134
5135 if (!programObject->isLinked())
5136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005137 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005138 return false;
5139 }
5140
5141 return true;
5142}
5143
Jamie Madill5b772312018-03-08 20:28:32 -05005144bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005145{
5146 GLenum nativeType;
5147 unsigned int numParams = 0;
5148 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5149}
5150
Jamie Madill5b772312018-03-08 20:28:32 -05005151bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005152{
5153 return true;
5154}
5155
Jamie Madill5b772312018-03-08 20:28:32 -05005156bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005157{
5158 GLenum nativeType;
5159 unsigned int numParams = 0;
5160 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5161}
5162
Jamie Madill5b772312018-03-08 20:28:32 -05005163bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005164{
5165 GLenum nativeType;
5166 unsigned int numParams = 0;
5167 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5168}
5169
Jamie Madill5b772312018-03-08 20:28:32 -05005170bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005171 GLuint program,
5172 GLsizei bufsize,
5173 GLsizei *length,
5174 GLchar *infolog)
5175{
5176 if (bufsize < 0)
5177 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005178 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005179 return false;
5180 }
5181
5182 Program *programObject = GetValidProgram(context, program);
5183 if (!programObject)
5184 {
5185 return false;
5186 }
5187
5188 return true;
5189}
5190
Jamie Madill5b772312018-03-08 20:28:32 -05005191bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005192 GLuint shader,
5193 GLsizei bufsize,
5194 GLsizei *length,
5195 GLchar *infolog)
5196{
5197 if (bufsize < 0)
5198 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005199 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005200 return false;
5201 }
5202
5203 Shader *shaderObject = GetValidShader(context, shader);
5204 if (!shaderObject)
5205 {
5206 return false;
5207 }
5208
5209 return true;
5210}
5211
Jamie Madill5b772312018-03-08 20:28:32 -05005212bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 GLenum shadertype,
5214 GLenum precisiontype,
5215 GLint *range,
5216 GLint *precision)
5217{
5218 switch (shadertype)
5219 {
5220 case GL_VERTEX_SHADER:
5221 case GL_FRAGMENT_SHADER:
5222 break;
5223 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005224 context->handleError(InvalidOperation()
5225 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005226 return false;
5227 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005228 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005229 return false;
5230 }
5231
5232 switch (precisiontype)
5233 {
5234 case GL_LOW_FLOAT:
5235 case GL_MEDIUM_FLOAT:
5236 case GL_HIGH_FLOAT:
5237 case GL_LOW_INT:
5238 case GL_MEDIUM_INT:
5239 case GL_HIGH_INT:
5240 break;
5241
5242 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005243 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005244 return false;
5245 }
5246
5247 return true;
5248}
5249
Jamie Madill5b772312018-03-08 20:28:32 -05005250bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005251 GLuint shader,
5252 GLsizei bufsize,
5253 GLsizei *length,
5254 GLchar *source)
5255{
5256 if (bufsize < 0)
5257 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005258 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005259 return false;
5260 }
5261
5262 Shader *shaderObject = GetValidShader(context, shader);
5263 if (!shaderObject)
5264 {
5265 return false;
5266 }
5267
5268 return true;
5269}
5270
Jamie Madill5b772312018-03-08 20:28:32 -05005271bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005272{
5273 if (strstr(name, "gl_") == name)
5274 {
5275 return false;
5276 }
5277
Geoff Langfc32e8b2017-05-31 14:16:59 -04005278 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5279 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005280 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005281 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005282 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005283 return false;
5284 }
5285
Jamie Madillc1d770e2017-04-13 17:31:24 -04005286 Program *programObject = GetValidProgram(context, program);
5287
5288 if (!programObject)
5289 {
5290 return false;
5291 }
5292
5293 if (!programObject->isLinked())
5294 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005296 return false;
5297 }
5298
5299 return true;
5300}
5301
Jamie Madill5b772312018-03-08 20:28:32 -05005302bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005303{
5304 switch (mode)
5305 {
5306 case GL_FASTEST:
5307 case GL_NICEST:
5308 case GL_DONT_CARE:
5309 break;
5310
5311 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005312 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005313 return false;
5314 }
5315
5316 switch (target)
5317 {
5318 case GL_GENERATE_MIPMAP_HINT:
5319 break;
5320
Geoff Lange7bd2182017-06-16 16:13:13 -04005321 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5322 if (context->getClientVersion() < ES_3_0 &&
5323 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005324 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005325 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005326 return false;
5327 }
5328 break;
5329
5330 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005331 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005332 return false;
5333 }
5334
5335 return true;
5336}
5337
Jamie Madill5b772312018-03-08 20:28:32 -05005338bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005339{
5340 return true;
5341}
5342
Jamie Madill5b772312018-03-08 20:28:32 -05005343bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005344{
5345 return true;
5346}
5347
Jamie Madill5b772312018-03-08 20:28:32 -05005348bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005349{
5350 return true;
5351}
5352
Jamie Madill5b772312018-03-08 20:28:32 -05005353bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005354{
5355 return true;
5356}
5357
Jamie Madill5b772312018-03-08 20:28:32 -05005358bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005359{
5360 return true;
5361}
5362
Jamie Madill5b772312018-03-08 20:28:32 -05005363bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005364{
5365 return true;
5366}
5367
Jamie Madill5b772312018-03-08 20:28:32 -05005368bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005369{
5370 if (context->getClientMajorVersion() < 3)
5371 {
5372 switch (pname)
5373 {
5374 case GL_UNPACK_IMAGE_HEIGHT:
5375 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005376 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005377 return false;
5378
5379 case GL_UNPACK_ROW_LENGTH:
5380 case GL_UNPACK_SKIP_ROWS:
5381 case GL_UNPACK_SKIP_PIXELS:
5382 if (!context->getExtensions().unpackSubimage)
5383 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005384 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385 return false;
5386 }
5387 break;
5388
5389 case GL_PACK_ROW_LENGTH:
5390 case GL_PACK_SKIP_ROWS:
5391 case GL_PACK_SKIP_PIXELS:
5392 if (!context->getExtensions().packSubimage)
5393 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005394 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005395 return false;
5396 }
5397 break;
5398 }
5399 }
5400
5401 if (param < 0)
5402 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005403 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005404 return false;
5405 }
5406
5407 switch (pname)
5408 {
5409 case GL_UNPACK_ALIGNMENT:
5410 if (param != 1 && param != 2 && param != 4 && param != 8)
5411 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005412 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005413 return false;
5414 }
5415 break;
5416
5417 case GL_PACK_ALIGNMENT:
5418 if (param != 1 && param != 2 && param != 4 && param != 8)
5419 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005420 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005421 return false;
5422 }
5423 break;
5424
5425 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005426 if (!context->getExtensions().packReverseRowOrder)
5427 {
5428 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5429 }
5430 break;
5431
Jamie Madillc1d770e2017-04-13 17:31:24 -04005432 case GL_UNPACK_ROW_LENGTH:
5433 case GL_UNPACK_IMAGE_HEIGHT:
5434 case GL_UNPACK_SKIP_IMAGES:
5435 case GL_UNPACK_SKIP_ROWS:
5436 case GL_UNPACK_SKIP_PIXELS:
5437 case GL_PACK_ROW_LENGTH:
5438 case GL_PACK_SKIP_ROWS:
5439 case GL_PACK_SKIP_PIXELS:
5440 break;
5441
5442 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005443 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444 return false;
5445 }
5446
5447 return true;
5448}
5449
Jamie Madill5b772312018-03-08 20:28:32 -05005450bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005451{
5452 return true;
5453}
5454
Jamie Madill5b772312018-03-08 20:28:32 -05005455bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005456{
5457 return true;
5458}
5459
Jamie Madill5b772312018-03-08 20:28:32 -05005460bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005461{
5462 return true;
5463}
5464
Jamie Madill5b772312018-03-08 20:28:32 -05005465bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005466{
5467 if (width < 0 || height < 0)
5468 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005469 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470 return false;
5471 }
5472
5473 return true;
5474}
5475
Jamie Madill5b772312018-03-08 20:28:32 -05005476bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477 GLsizei n,
5478 const GLuint *shaders,
5479 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005480 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005481 GLsizei length)
5482{
5483 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5484 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5485 shaderBinaryFormats.end())
5486 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005487 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005488 return false;
5489 }
5490
5491 return true;
5492}
5493
Jamie Madill5b772312018-03-08 20:28:32 -05005494bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005495 GLuint shader,
5496 GLsizei count,
5497 const GLchar *const *string,
5498 const GLint *length)
5499{
5500 if (count < 0)
5501 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005502 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005503 return false;
5504 }
5505
Geoff Langfc32e8b2017-05-31 14:16:59 -04005506 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5507 // shader-related entry points
5508 if (context->getExtensions().webglCompatibility)
5509 {
5510 for (GLsizei i = 0; i < count; i++)
5511 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005512 size_t len =
5513 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005514
5515 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005516 if (!IsValidESSLShaderSourceString(string[i], len,
5517 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005518 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005519 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005520 return false;
5521 }
5522 }
5523 }
5524
Jamie Madillc1d770e2017-04-13 17:31:24 -04005525 Shader *shaderObject = GetValidShader(context, shader);
5526 if (!shaderObject)
5527 {
5528 return false;
5529 }
5530
5531 return true;
5532}
5533
Jamie Madill5b772312018-03-08 20:28:32 -05005534bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005535{
5536 if (!IsValidStencilFunc(func))
5537 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005538 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005539 return false;
5540 }
5541
5542 return true;
5543}
5544
Jamie Madill5b772312018-03-08 20:28:32 -05005545bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005546{
5547 if (!IsValidStencilFace(face))
5548 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005549 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005550 return false;
5551 }
5552
5553 if (!IsValidStencilFunc(func))
5554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005555 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556 return false;
5557 }
5558
5559 return true;
5560}
5561
Jamie Madill5b772312018-03-08 20:28:32 -05005562bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005563{
5564 return true;
5565}
5566
Jamie Madill5b772312018-03-08 20:28:32 -05005567bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005568{
5569 if (!IsValidStencilFace(face))
5570 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005571 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005572 return false;
5573 }
5574
5575 return true;
5576}
5577
Jamie Madill5b772312018-03-08 20:28:32 -05005578bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005579{
5580 if (!IsValidStencilOp(fail))
5581 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005582 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005583 return false;
5584 }
5585
5586 if (!IsValidStencilOp(zfail))
5587 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005588 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005589 return false;
5590 }
5591
5592 if (!IsValidStencilOp(zpass))
5593 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005594 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005595 return false;
5596 }
5597
5598 return true;
5599}
5600
Jamie Madill5b772312018-03-08 20:28:32 -05005601bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602 GLenum face,
5603 GLenum fail,
5604 GLenum zfail,
5605 GLenum zpass)
5606{
5607 if (!IsValidStencilFace(face))
5608 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005609 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005610 return false;
5611 }
5612
5613 return ValidateStencilOp(context, fail, zfail, zpass);
5614}
5615
Jamie Madill5b772312018-03-08 20:28:32 -05005616bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005617{
5618 return ValidateUniform(context, GL_FLOAT, location, 1);
5619}
5620
Jamie Madill5b772312018-03-08 20:28:32 -05005621bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005622{
5623 return ValidateUniform(context, GL_FLOAT, location, count);
5624}
5625
Jamie Madill5b772312018-03-08 20:28:32 -05005626bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005627{
5628 return ValidateUniform1iv(context, location, 1, &x);
5629}
5630
Jamie Madill5b772312018-03-08 20:28:32 -05005631bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005632{
5633 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5634}
5635
Jamie Madill5b772312018-03-08 20:28:32 -05005636bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005637{
5638 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5639}
5640
Jamie Madill5b772312018-03-08 20:28:32 -05005641bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005642{
5643 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5644}
5645
Jamie Madill5b772312018-03-08 20:28:32 -05005646bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005647{
5648 return ValidateUniform(context, GL_INT_VEC2, location, count);
5649}
5650
Jamie Madill5b772312018-03-08 20:28:32 -05005651bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005652{
5653 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5654}
5655
Jamie Madill5b772312018-03-08 20:28:32 -05005656bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005657{
5658 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5659}
5660
Jamie Madill5b772312018-03-08 20:28:32 -05005661bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005662{
5663 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5664}
5665
Jamie Madill5b772312018-03-08 20:28:32 -05005666bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005667{
5668 return ValidateUniform(context, GL_INT_VEC3, location, count);
5669}
5670
Jamie Madill5b772312018-03-08 20:28:32 -05005671bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005672{
5673 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5674}
5675
Jamie Madill5b772312018-03-08 20:28:32 -05005676bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005677{
5678 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5679}
5680
Jamie Madill5b772312018-03-08 20:28:32 -05005681bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005682{
5683 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5684}
5685
Jamie Madill5b772312018-03-08 20:28:32 -05005686bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005687{
5688 return ValidateUniform(context, GL_INT_VEC4, location, count);
5689}
5690
Jamie Madill5b772312018-03-08 20:28:32 -05005691bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005692 GLint location,
5693 GLsizei count,
5694 GLboolean transpose,
5695 const GLfloat *value)
5696{
5697 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5698}
5699
Jamie Madill5b772312018-03-08 20:28:32 -05005700bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005701 GLint location,
5702 GLsizei count,
5703 GLboolean transpose,
5704 const GLfloat *value)
5705{
5706 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5707}
5708
Jamie Madill5b772312018-03-08 20:28:32 -05005709bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005710 GLint location,
5711 GLsizei count,
5712 GLboolean transpose,
5713 const GLfloat *value)
5714{
5715 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5716}
5717
Jamie Madill5b772312018-03-08 20:28:32 -05005718bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005719{
5720 Program *programObject = GetValidProgram(context, program);
5721
5722 if (!programObject)
5723 {
5724 return false;
5725 }
5726
5727 return true;
5728}
5729
Jamie Madill5b772312018-03-08 20:28:32 -05005730bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005731{
5732 return ValidateVertexAttribIndex(context, index);
5733}
5734
Jamie Madill5b772312018-03-08 20:28:32 -05005735bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005736{
5737 return ValidateVertexAttribIndex(context, index);
5738}
5739
Jamie Madill5b772312018-03-08 20:28:32 -05005740bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005741{
5742 return ValidateVertexAttribIndex(context, index);
5743}
5744
Jamie Madill5b772312018-03-08 20:28:32 -05005745bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005746{
5747 return ValidateVertexAttribIndex(context, index);
5748}
5749
Jamie Madill5b772312018-03-08 20:28:32 -05005750bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005751{
5752 return ValidateVertexAttribIndex(context, index);
5753}
5754
Jamie Madill5b772312018-03-08 20:28:32 -05005755bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005756{
5757 return ValidateVertexAttribIndex(context, index);
5758}
5759
Jamie Madill5b772312018-03-08 20:28:32 -05005760bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005761 GLuint index,
5762 GLfloat x,
5763 GLfloat y,
5764 GLfloat z,
5765 GLfloat w)
5766{
5767 return ValidateVertexAttribIndex(context, index);
5768}
5769
Jamie Madill5b772312018-03-08 20:28:32 -05005770bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005771{
5772 return ValidateVertexAttribIndex(context, index);
5773}
5774
Jamie Madill5b772312018-03-08 20:28:32 -05005775bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005776{
5777 if (width < 0 || height < 0)
5778 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005779 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005780 return false;
5781 }
5782
5783 return true;
5784}
5785
Jamie Madill493f9572018-05-24 19:52:15 -04005786bool ValidateDrawArrays(Context *context, PrimitiveMode mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005787{
5788 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5789}
5790
Jamie Madill5b772312018-03-08 20:28:32 -05005791bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005792 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005793 GLsizei count,
5794 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005795 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005796{
5797 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5798}
5799
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005800bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005801 GLenum target,
5802 GLenum attachment,
5803 GLenum pname,
5804 GLint *params)
5805{
5806 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5807 nullptr);
5808}
5809
Jamie Madill5b772312018-03-08 20:28:32 -05005810bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005811{
5812 return ValidateGetProgramivBase(context, program, pname, nullptr);
5813}
5814
Jamie Madill5b772312018-03-08 20:28:32 -05005815bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005816 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005817 GLint level,
5818 GLenum internalformat,
5819 GLint x,
5820 GLint y,
5821 GLsizei width,
5822 GLsizei height,
5823 GLint border)
5824{
5825 if (context->getClientMajorVersion() < 3)
5826 {
5827 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5828 0, x, y, width, height, border);
5829 }
5830
5831 ASSERT(context->getClientMajorVersion() == 3);
5832 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5833 0, x, y, width, height, border);
5834}
5835
5836bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005837 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005838 GLint level,
5839 GLint xoffset,
5840 GLint yoffset,
5841 GLint x,
5842 GLint y,
5843 GLsizei width,
5844 GLsizei height)
5845{
5846 if (context->getClientMajorVersion() < 3)
5847 {
5848 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5849 yoffset, x, y, width, height, 0);
5850 }
5851
5852 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5853 yoffset, 0, x, y, width, height, 0);
5854}
5855
5856bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5857{
5858 return ValidateGenOrDelete(context, n);
5859}
5860
5861bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5862{
5863 return ValidateGenOrDelete(context, n);
5864}
5865
5866bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5867{
5868 return ValidateGenOrDelete(context, n);
5869}
5870
5871bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5872{
5873 return ValidateGenOrDelete(context, n);
5874}
5875
5876bool ValidateDisable(Context *context, GLenum cap)
5877{
5878 if (!ValidCap(context, cap, false))
5879 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005880 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005881 return false;
5882 }
5883
5884 return true;
5885}
5886
5887bool ValidateEnable(Context *context, GLenum cap)
5888{
5889 if (!ValidCap(context, cap, false))
5890 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005891 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005892 return false;
5893 }
5894
5895 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5896 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5897 {
5898 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005899 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005900
5901 // We also output an error message to the debugger window if tracing is active, so that
5902 // developers can see the error message.
5903 ERR() << errorMessage;
5904 return false;
5905 }
5906
5907 return true;
5908}
5909
5910bool ValidateFramebufferRenderbuffer(Context *context,
5911 GLenum target,
5912 GLenum attachment,
5913 GLenum renderbuffertarget,
5914 GLuint renderbuffer)
5915{
Geoff Lange8afa902017-09-27 15:00:43 -04005916 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005917 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005918 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5919 return false;
5920 }
5921
5922 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5923 {
5924 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005925 return false;
5926 }
5927
5928 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5929 renderbuffertarget, renderbuffer);
5930}
5931
5932bool ValidateFramebufferTexture2D(Context *context,
5933 GLenum target,
5934 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005935 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005936 GLuint texture,
5937 GLint level)
5938{
5939 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5940 // extension
5941 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5942 level != 0)
5943 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005944 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005945 return false;
5946 }
5947
5948 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5949 {
5950 return false;
5951 }
5952
5953 if (texture != 0)
5954 {
5955 gl::Texture *tex = context->getTexture(texture);
5956 ASSERT(tex);
5957
5958 const gl::Caps &caps = context->getCaps();
5959
5960 switch (textarget)
5961 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005962 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005963 {
5964 if (level > gl::log2(caps.max2DTextureSize))
5965 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005966 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005967 return false;
5968 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005969 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005970 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005971 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005972 return false;
5973 }
5974 }
5975 break;
5976
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005977 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005978 {
5979 if (level != 0)
5980 {
5981 context->handleError(InvalidValue());
5982 return false;
5983 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005984 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005985 {
5986 context->handleError(InvalidOperation()
5987 << "Textarget must match the texture target type.");
5988 return false;
5989 }
5990 }
5991 break;
5992
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005993 case TextureTarget::CubeMapNegativeX:
5994 case TextureTarget::CubeMapNegativeY:
5995 case TextureTarget::CubeMapNegativeZ:
5996 case TextureTarget::CubeMapPositiveX:
5997 case TextureTarget::CubeMapPositiveY:
5998 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005999 {
6000 if (level > gl::log2(caps.maxCubeMapTextureSize))
6001 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006002 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006003 return false;
6004 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006005 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006007 context->handleError(InvalidOperation()
6008 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006009 return false;
6010 }
6011 }
6012 break;
6013
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006014 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006015 {
6016 if (context->getClientVersion() < ES_3_1)
6017 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006018 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006019 return false;
6020 }
6021
6022 if (level != 0)
6023 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006024 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006025 return false;
6026 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006027 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006028 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006029 context->handleError(InvalidOperation()
6030 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006031 return false;
6032 }
6033 }
6034 break;
6035
6036 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006037 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006038 return false;
6039 }
6040
6041 const Format &format = tex->getFormat(textarget, level);
6042 if (format.info->compressed)
6043 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006044 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 return false;
6046 }
6047 }
6048
6049 return true;
6050}
6051
6052bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6053{
6054 return ValidateGenOrDelete(context, n);
6055}
6056
6057bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6058{
6059 return ValidateGenOrDelete(context, n);
6060}
6061
6062bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6063{
6064 return ValidateGenOrDelete(context, n);
6065}
6066
6067bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6068{
6069 return ValidateGenOrDelete(context, n);
6070}
6071
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006072bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006073{
6074 if (!ValidTextureTarget(context, target))
6075 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006076 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006077 return false;
6078 }
6079
6080 Texture *texture = context->getTargetTexture(target);
6081
6082 if (texture == nullptr)
6083 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006084 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006085 return false;
6086 }
6087
6088 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6089
6090 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6091 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6092 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6093 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006094 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006095 return false;
6096 }
6097
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006098 TextureTarget baseTarget = (target == TextureType::CubeMap)
6099 ? TextureTarget::CubeMapPositiveX
6100 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006101 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6102 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6103 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006104 {
6105 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6106 return false;
6107 }
6108
Geoff Lang536eca12017-09-13 11:23:35 -04006109 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6110 bool formatUnsized = !format.sized;
6111 bool formatColorRenderableAndFilterable =
6112 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6113 format.renderSupport(context->getClientVersion(), context->getExtensions());
6114 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006115 {
Geoff Lang536eca12017-09-13 11:23:35 -04006116 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006117 return false;
6118 }
6119
Geoff Lang536eca12017-09-13 11:23:35 -04006120 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6121 // generation
6122 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6123 {
6124 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6125 return false;
6126 }
6127
6128 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
Geoff Lange24032a2018-03-28 15:41:46 -04006129 // not. Differentiate the ES3 format from the extension format by checking if the format is
6130 // sized, GL_EXT_sRGB does not add any sized formats.
6131 bool supportsSRGBMipmapGeneration = context->getExtensions().webglCompatibility;
6132 if (!supportsSRGBMipmapGeneration && !format.sized && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006133 {
Geoff Lang536eca12017-09-13 11:23:35 -04006134 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006135 return false;
6136 }
6137
6138 // Non-power of 2 ES2 check
6139 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6140 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6141 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6142 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006143 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6144 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006145 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006146 return false;
6147 }
6148
6149 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006150 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006151 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006152 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006153 return false;
6154 }
6155
6156 return true;
6157}
6158
Jamie Madill5b772312018-03-08 20:28:32 -05006159bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006160 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006161 GLenum pname,
6162 GLint *params)
6163{
6164 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6165}
6166
6167bool ValidateGetRenderbufferParameteriv(Context *context,
6168 GLenum target,
6169 GLenum pname,
6170 GLint *params)
6171{
6172 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6173}
6174
6175bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6176{
6177 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6178}
6179
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006180bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006181{
6182 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6183}
6184
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006185bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006186{
6187 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6188}
6189
6190bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6191{
6192 return ValidateGetUniformBase(context, program, location);
6193}
6194
6195bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6196{
6197 return ValidateGetUniformBase(context, program, location);
6198}
6199
6200bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6201{
6202 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6203}
6204
6205bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6206{
6207 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6208}
6209
6210bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6211{
6212 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6213}
6214
6215bool ValidateIsEnabled(Context *context, GLenum cap)
6216{
6217 if (!ValidCap(context, cap, true))
6218 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006219 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006220 return false;
6221 }
6222
6223 return true;
6224}
6225
6226bool ValidateLinkProgram(Context *context, GLuint program)
6227{
6228 if (context->hasActiveTransformFeedback(program))
6229 {
6230 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006231 context->handleError(InvalidOperation() << "Cannot link program while program is "
6232 "associated with an active transform "
6233 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006234 return false;
6235 }
6236
6237 Program *programObject = GetValidProgram(context, program);
6238 if (!programObject)
6239 {
6240 return false;
6241 }
6242
6243 return true;
6244}
6245
Jamie Madill4928b7c2017-06-20 12:57:39 -04006246bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006247 GLint x,
6248 GLint y,
6249 GLsizei width,
6250 GLsizei height,
6251 GLenum format,
6252 GLenum type,
6253 void *pixels)
6254{
6255 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6256 nullptr, pixels);
6257}
6258
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006259bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006260{
6261 return ValidateTexParameterBase(context, target, pname, -1, &param);
6262}
6263
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006264bool ValidateTexParameterfv(Context *context,
6265 TextureType target,
6266 GLenum pname,
6267 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006268{
6269 return ValidateTexParameterBase(context, target, pname, -1, params);
6270}
6271
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006272bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006273{
6274 return ValidateTexParameterBase(context, target, pname, -1, &param);
6275}
6276
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006277bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006278{
6279 return ValidateTexParameterBase(context, target, pname, -1, params);
6280}
6281
6282bool ValidateUseProgram(Context *context, GLuint program)
6283{
6284 if (program != 0)
6285 {
6286 Program *programObject = context->getProgram(program);
6287 if (!programObject)
6288 {
6289 // ES 3.1.0 section 7.3 page 72
6290 if (context->getShader(program))
6291 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006292 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006293 return false;
6294 }
6295 else
6296 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006297 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006298 return false;
6299 }
6300 }
6301 if (!programObject->isLinked())
6302 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006303 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006304 return false;
6305 }
6306 }
6307 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6308 {
6309 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006310 context
6311 ->handleError(InvalidOperation()
6312 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006313 return false;
6314 }
6315
6316 return true;
6317}
6318
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006319bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6320{
6321 if (!context->getExtensions().fence)
6322 {
6323 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6324 return false;
6325 }
6326
6327 if (n < 0)
6328 {
6329 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6330 return false;
6331 }
6332
6333 return true;
6334}
6335
6336bool ValidateFinishFenceNV(Context *context, GLuint fence)
6337{
6338 if (!context->getExtensions().fence)
6339 {
6340 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6341 return false;
6342 }
6343
6344 FenceNV *fenceObject = context->getFenceNV(fence);
6345
6346 if (fenceObject == nullptr)
6347 {
6348 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6349 return false;
6350 }
6351
6352 if (!fenceObject->isSet())
6353 {
6354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6355 return false;
6356 }
6357
6358 return true;
6359}
6360
6361bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6362{
6363 if (!context->getExtensions().fence)
6364 {
6365 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6366 return false;
6367 }
6368
6369 if (n < 0)
6370 {
6371 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6372 return false;
6373 }
6374
6375 return true;
6376}
6377
6378bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6379{
6380 if (!context->getExtensions().fence)
6381 {
6382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6383 return false;
6384 }
6385
6386 FenceNV *fenceObject = context->getFenceNV(fence);
6387
6388 if (fenceObject == nullptr)
6389 {
6390 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6391 return false;
6392 }
6393
6394 if (!fenceObject->isSet())
6395 {
6396 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6397 return false;
6398 }
6399
6400 switch (pname)
6401 {
6402 case GL_FENCE_STATUS_NV:
6403 case GL_FENCE_CONDITION_NV:
6404 break;
6405
6406 default:
6407 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6408 return false;
6409 }
6410
6411 return true;
6412}
6413
6414bool ValidateGetGraphicsResetStatusEXT(Context *context)
6415{
6416 if (!context->getExtensions().robustness)
6417 {
6418 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6419 return false;
6420 }
6421
6422 return true;
6423}
6424
6425bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6426 GLuint shader,
6427 GLsizei bufsize,
6428 GLsizei *length,
6429 GLchar *source)
6430{
6431 if (!context->getExtensions().translatedShaderSource)
6432 {
6433 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6434 return false;
6435 }
6436
6437 if (bufsize < 0)
6438 {
6439 context->handleError(InvalidValue());
6440 return false;
6441 }
6442
6443 Shader *shaderObject = context->getShader(shader);
6444
6445 if (!shaderObject)
6446 {
6447 context->handleError(InvalidOperation());
6448 return false;
6449 }
6450
6451 return true;
6452}
6453
6454bool ValidateIsFenceNV(Context *context, GLuint fence)
6455{
6456 if (!context->getExtensions().fence)
6457 {
6458 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6459 return false;
6460 }
6461
6462 return true;
6463}
6464
Jamie Madill007530e2017-12-28 14:27:04 -05006465bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6466{
6467 if (!context->getExtensions().fence)
6468 {
6469 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6470 return false;
6471 }
6472
6473 if (condition != GL_ALL_COMPLETED_NV)
6474 {
6475 context->handleError(InvalidEnum());
6476 return false;
6477 }
6478
6479 FenceNV *fenceObject = context->getFenceNV(fence);
6480
6481 if (fenceObject == nullptr)
6482 {
6483 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6484 return false;
6485 }
6486
6487 return true;
6488}
6489
6490bool ValidateTestFenceNV(Context *context, GLuint fence)
6491{
6492 if (!context->getExtensions().fence)
6493 {
6494 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6495 return false;
6496 }
6497
6498 FenceNV *fenceObject = context->getFenceNV(fence);
6499
6500 if (fenceObject == nullptr)
6501 {
6502 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6503 return false;
6504 }
6505
6506 if (fenceObject->isSet() != GL_TRUE)
6507 {
6508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6509 return false;
6510 }
6511
6512 return true;
6513}
6514
6515bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006516 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006517 GLsizei levels,
6518 GLenum internalformat,
6519 GLsizei width,
6520 GLsizei height)
6521{
6522 if (!context->getExtensions().textureStorage)
6523 {
6524 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6525 return false;
6526 }
6527
6528 if (context->getClientMajorVersion() < 3)
6529 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006530 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006531 height);
6532 }
6533
6534 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006535 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006536 1);
6537}
6538
6539bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6540{
6541 if (!context->getExtensions().instancedArrays)
6542 {
6543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6544 return false;
6545 }
6546
6547 if (index >= MAX_VERTEX_ATTRIBS)
6548 {
6549 context->handleError(InvalidValue());
6550 return false;
6551 }
6552
6553 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6554 {
6555 if (index == 0 && divisor != 0)
6556 {
6557 const char *errorMessage =
6558 "The current context doesn't support setting a non-zero divisor on the "
6559 "attribute with index zero. "
6560 "Please reorder the attributes in your vertex shader so that attribute zero "
6561 "can have a zero divisor.";
6562 context->handleError(InvalidOperation() << errorMessage);
6563
6564 // We also output an error message to the debugger window if tracing is active, so
6565 // that developers can see the error message.
6566 ERR() << errorMessage;
6567 return false;
6568 }
6569 }
6570
6571 return true;
6572}
6573
6574bool ValidateTexImage3DOES(Context *context,
6575 GLenum target,
6576 GLint level,
6577 GLenum internalformat,
6578 GLsizei width,
6579 GLsizei height,
6580 GLsizei depth,
6581 GLint border,
6582 GLenum format,
6583 GLenum type,
6584 const void *pixels)
6585{
6586 UNIMPLEMENTED(); // FIXME
6587 return false;
6588}
6589
6590bool ValidatePopGroupMarkerEXT(Context *context)
6591{
6592 if (!context->getExtensions().debugMarker)
6593 {
6594 // The debug marker calls should not set error state
6595 // However, it seems reasonable to set an error state if the extension is not enabled
6596 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6597 return false;
6598 }
6599
6600 return true;
6601}
6602
Jamie Madillfa920eb2018-01-04 11:45:50 -05006603bool ValidateTexStorage1DEXT(Context *context,
6604 GLenum target,
6605 GLsizei levels,
6606 GLenum internalformat,
6607 GLsizei width)
6608{
6609 UNIMPLEMENTED();
6610 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6611 return false;
6612}
6613
6614bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006615 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006616 GLsizei levels,
6617 GLenum internalformat,
6618 GLsizei width,
6619 GLsizei height,
6620 GLsizei depth)
6621{
6622 if (!context->getExtensions().textureStorage)
6623 {
6624 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6625 return false;
6626 }
6627
6628 if (context->getClientMajorVersion() < 3)
6629 {
6630 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6631 return false;
6632 }
6633
6634 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6635 depth);
6636}
6637
Jamie Madillc29968b2016-01-20 11:17:23 -05006638} // namespace gl