blob: 1a4af0149059a8f305fe216397984416372c6894 [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 Yang9c4c0922018-06-13 09:29:00 -0700821 case GL_POINT_SMOOTH:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700822 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700823 case GL_POINT_SIZE_ARRAY_OES:
824 return context->getClientVersion() < Version(2, 0) &&
825 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700826 case GL_TEXTURE_CUBE_MAP:
827 return context->getClientVersion() < Version(2, 0) &&
828 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700829 case GL_POINT_SPRITE_OES:
830 return context->getClientVersion() < Version(2, 0) &&
831 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400832 default:
833 return false;
834 }
835}
836
Geoff Langfc32e8b2017-05-31 14:16:59 -0400837// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
838// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400839bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400840{
841 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400842 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
843 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400844 {
845 return true;
846 }
847
848 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
849 if (c >= 9 && c <= 13)
850 {
851 return true;
852 }
853
854 return false;
855}
856
Geoff Langcab92ee2017-07-19 17:32:07 -0400857bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400858{
Geoff Langa71a98e2017-06-19 15:15:00 -0400859 for (size_t i = 0; i < len; i++)
860 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400861 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400862 {
863 return false;
864 }
865 }
866
867 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400868}
869
Geoff Langcab92ee2017-07-19 17:32:07 -0400870bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
871{
872 enum class ParseState
873 {
874 // Have not seen an ASCII non-whitespace character yet on
875 // this line. Possible that we might see a preprocessor
876 // directive.
877 BEGINING_OF_LINE,
878
879 // Have seen at least one ASCII non-whitespace character
880 // on this line.
881 MIDDLE_OF_LINE,
882
883 // Handling a preprocessor directive. Passes through all
884 // characters up to the end of the line. Disables comment
885 // processing.
886 IN_PREPROCESSOR_DIRECTIVE,
887
888 // Handling a single-line comment. The comment text is
889 // replaced with a single space.
890 IN_SINGLE_LINE_COMMENT,
891
892 // Handling a multi-line comment. Newlines are passed
893 // through to preserve line numbers.
894 IN_MULTI_LINE_COMMENT
895 };
896
897 ParseState state = ParseState::BEGINING_OF_LINE;
898 size_t pos = 0;
899
900 while (pos < len)
901 {
902 char c = str[pos];
903 char next = pos + 1 < len ? str[pos + 1] : 0;
904
905 // Check for newlines
906 if (c == '\n' || c == '\r')
907 {
908 if (state != ParseState::IN_MULTI_LINE_COMMENT)
909 {
910 state = ParseState::BEGINING_OF_LINE;
911 }
912
913 pos++;
914 continue;
915 }
916
917 switch (state)
918 {
919 case ParseState::BEGINING_OF_LINE:
920 if (c == ' ')
921 {
922 // Maintain the BEGINING_OF_LINE state until a non-space is seen
923 pos++;
924 }
925 else if (c == '#')
926 {
927 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
928 pos++;
929 }
930 else
931 {
932 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
933 state = ParseState::MIDDLE_OF_LINE;
934 }
935 break;
936
937 case ParseState::MIDDLE_OF_LINE:
938 if (c == '/' && next == '/')
939 {
940 state = ParseState::IN_SINGLE_LINE_COMMENT;
941 pos++;
942 }
943 else if (c == '/' && next == '*')
944 {
945 state = ParseState::IN_MULTI_LINE_COMMENT;
946 pos++;
947 }
948 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
949 {
950 // Skip line continuation characters
951 }
952 else if (!IsValidESSLCharacter(c))
953 {
954 return false;
955 }
956 pos++;
957 break;
958
959 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700960 // Line-continuation characters may not be permitted.
961 // Otherwise, just pass it through. Do not parse comments in this state.
962 if (!lineContinuationAllowed && c == '\\')
963 {
964 return false;
965 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400966 pos++;
967 break;
968
969 case ParseState::IN_SINGLE_LINE_COMMENT:
970 // Line-continuation characters are processed before comment processing.
971 // Advance string if a new line character is immediately behind
972 // line-continuation character.
973 if (c == '\\' && (next == '\n' || next == '\r'))
974 {
975 pos++;
976 }
977 pos++;
978 break;
979
980 case ParseState::IN_MULTI_LINE_COMMENT:
981 if (c == '*' && next == '/')
982 {
983 state = ParseState::MIDDLE_OF_LINE;
984 pos++;
985 }
986 pos++;
987 break;
988 }
989 }
990
991 return true;
992}
993
Jamie Madill5b772312018-03-08 20:28:32 -0500994bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700995{
996 ASSERT(context->isWebGL());
997
998 // WebGL 1.0 [Section 6.16] GLSL Constructs
999 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1000 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1001 {
1002 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1003 return false;
1004 }
1005
1006 return true;
1007}
1008
Jamie Madill5b772312018-03-08 20:28:32 -05001009bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001010{
1011 ASSERT(context->isWebGL());
1012
1013 if (context->isWebGL1() && length > 256)
1014 {
1015 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1016 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1017 // locations.
1018 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1019
1020 return false;
1021 }
1022 else if (length > 1024)
1023 {
1024 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1025 // uniform and attribute locations.
1026 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1027 return false;
1028 }
1029
1030 return true;
1031}
1032
Jamie Madill007530e2017-12-28 14:27:04 -05001033bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1034{
1035 if (!context->getExtensions().pathRendering)
1036 {
1037 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1038 return false;
1039 }
1040
1041 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1042 {
1043 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1044 return false;
1045 }
1046 return true;
1047}
Jamie Madillc29968b2016-01-20 11:17:23 -05001048} // anonymous namespace
1049
Geoff Langff5b2d52016-09-07 11:32:23 -04001050bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001051 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001052 GLint level,
1053 GLenum internalformat,
1054 bool isCompressed,
1055 bool isSubImage,
1056 GLint xoffset,
1057 GLint yoffset,
1058 GLsizei width,
1059 GLsizei height,
1060 GLint border,
1061 GLenum format,
1062 GLenum type,
1063 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001064 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001065{
Jamie Madill6f38f822014-06-06 17:12:20 -04001066 if (!ValidTexture2DDestinationTarget(context, target))
1067 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001068 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001069 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001070 }
1071
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001072 TextureType texType = TextureTargetToType(target);
1073 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001075 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001076 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001077 }
1078
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001079 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001080 {
1081 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1082 return false;
1083 }
1084
1085 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001086 std::numeric_limits<GLsizei>::max() - yoffset < height)
1087 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001088 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001089 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001090 }
1091
Geoff Lang6e898aa2017-06-02 11:17:26 -04001092 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1093 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1094 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1095 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1096 // case.
1097 bool nonEqualFormatsAllowed =
1098 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1099 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1100
1101 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001103 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001104 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001105 }
1106
Geoff Langaae65a42014-05-26 12:43:44 -04001107 const gl::Caps &caps = context->getCaps();
1108
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001109 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001110 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001111 case TextureType::_2D:
1112 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1113 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1114 {
1115 context->handleError(InvalidValue());
1116 return false;
1117 }
1118 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001119
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001120 case TextureType::Rectangle:
1121 ASSERT(level == 0);
1122 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1123 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1124 {
1125 context->handleError(InvalidValue());
1126 return false;
1127 }
1128 if (isCompressed)
1129 {
1130 context->handleError(InvalidEnum()
1131 << "Rectangle texture cannot have a compressed format.");
1132 return false;
1133 }
1134 break;
1135
1136 case TextureType::CubeMap:
1137 if (!isSubImage && width != height)
1138 {
1139 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1140 return false;
1141 }
1142
1143 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1144 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1145 {
1146 context->handleError(InvalidValue());
1147 return false;
1148 }
1149 break;
1150
1151 default:
1152 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001153 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001154 }
1155
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001156 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001157 if (!texture)
1158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001160 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001161 }
1162
Geoff Langa9be0dc2014-12-17 12:34:40 -05001163 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001164 {
Geoff Langca271392017-04-05 12:30:00 -04001165 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1166 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001168 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001169 return false;
1170 }
1171
Geoff Langa9be0dc2014-12-17 12:34:40 -05001172 if (format != GL_NONE)
1173 {
Geoff Langca271392017-04-05 12:30:00 -04001174 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1175 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001176 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001177 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001178 return false;
1179 }
1180 }
1181
1182 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1183 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001185 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001186 return false;
1187 }
Geoff Langfb052642017-10-24 13:42:09 -04001188
1189 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001190 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001191 {
1192 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1193 return false;
1194 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001195 }
1196 else
1197 {
Geoff Lang69cce582015-09-17 13:20:36 -04001198 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001200 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001201 return false;
1202 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001203 }
1204
1205 // Verify zero border
1206 if (border != 0)
1207 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001208 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001209 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001210 }
1211
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001212 if (isCompressed)
1213 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001214 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001215 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1216 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001217
1218 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1219
1220 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001221 {
Geoff Lange88e4542018-05-03 15:05:57 -04001222 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1223 return false;
1224 }
1225
1226 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1227 context->getExtensions()))
1228 {
1229 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1230 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001231 }
Geoff Lang966c9402017-04-18 12:38:27 -04001232
1233 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001234 {
Geoff Lange88e4542018-05-03 15:05:57 -04001235 // From the OES_compressed_ETC1_RGB8_texture spec:
1236 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1237 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1238 // ETC1_RGB8_OES.
1239 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1240 {
1241 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1242 return false;
1243 }
1244
Geoff Lang966c9402017-04-18 12:38:27 -04001245 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1246 height, texture->getWidth(target, level),
1247 texture->getHeight(target, level)))
1248 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001249 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001250 return false;
1251 }
1252
1253 if (format != actualInternalFormat)
1254 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001255 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001256 return false;
1257 }
1258 }
1259 else
1260 {
1261 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1262 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001263 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001264 return false;
1265 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001266 }
1267 }
1268 else
1269 {
1270 // validate <type> by itself (used as secondary key below)
1271 switch (type)
1272 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001273 case GL_UNSIGNED_BYTE:
1274 case GL_UNSIGNED_SHORT_5_6_5:
1275 case GL_UNSIGNED_SHORT_4_4_4_4:
1276 case GL_UNSIGNED_SHORT_5_5_5_1:
1277 case GL_UNSIGNED_SHORT:
1278 case GL_UNSIGNED_INT:
1279 case GL_UNSIGNED_INT_24_8_OES:
1280 case GL_HALF_FLOAT_OES:
1281 case GL_FLOAT:
1282 break;
1283 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001284 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001285 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001286 }
1287
1288 // validate <format> + <type> combinations
1289 // - invalid <format> -> sets INVALID_ENUM
1290 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1291 switch (format)
1292 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001293 case GL_ALPHA:
1294 case GL_LUMINANCE:
1295 case GL_LUMINANCE_ALPHA:
1296 switch (type)
1297 {
1298 case GL_UNSIGNED_BYTE:
1299 case GL_FLOAT:
1300 case GL_HALF_FLOAT_OES:
1301 break;
1302 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001303 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001304 return false;
1305 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001306 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001307 case GL_RED:
1308 case GL_RG:
1309 if (!context->getExtensions().textureRG)
1310 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001311 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001312 return false;
1313 }
1314 switch (type)
1315 {
1316 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001317 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001318 case GL_FLOAT:
1319 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001320 if (!context->getExtensions().textureFloat)
1321 {
1322 context->handleError(InvalidEnum());
1323 return false;
1324 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001325 break;
1326 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001327 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001328 return false;
1329 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001330 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001331 case GL_RGB:
1332 switch (type)
1333 {
1334 case GL_UNSIGNED_BYTE:
1335 case GL_UNSIGNED_SHORT_5_6_5:
1336 case GL_FLOAT:
1337 case GL_HALF_FLOAT_OES:
1338 break;
1339 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001340 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001341 return false;
1342 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001343 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001344 case GL_RGBA:
1345 switch (type)
1346 {
1347 case GL_UNSIGNED_BYTE:
1348 case GL_UNSIGNED_SHORT_4_4_4_4:
1349 case GL_UNSIGNED_SHORT_5_5_5_1:
1350 case GL_FLOAT:
1351 case GL_HALF_FLOAT_OES:
1352 break;
1353 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001355 return false;
1356 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001357 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001358 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001359 if (!context->getExtensions().textureFormatBGRA8888)
1360 {
1361 context->handleError(InvalidEnum());
1362 return false;
1363 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001364 switch (type)
1365 {
1366 case GL_UNSIGNED_BYTE:
1367 break;
1368 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001369 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001370 return false;
1371 }
1372 break;
1373 case GL_SRGB_EXT:
1374 case GL_SRGB_ALPHA_EXT:
1375 if (!context->getExtensions().sRGB)
1376 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001377 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001378 return false;
1379 }
1380 switch (type)
1381 {
1382 case GL_UNSIGNED_BYTE:
1383 break;
1384 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001385 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001386 return false;
1387 }
1388 break;
1389 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1390 // handled below
1391 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1392 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1393 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1394 break;
1395 case GL_DEPTH_COMPONENT:
1396 switch (type)
1397 {
1398 case GL_UNSIGNED_SHORT:
1399 case GL_UNSIGNED_INT:
1400 break;
1401 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001402 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001403 return false;
1404 }
1405 break;
1406 case GL_DEPTH_STENCIL_OES:
1407 switch (type)
1408 {
1409 case GL_UNSIGNED_INT_24_8_OES:
1410 break;
1411 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001412 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001413 return false;
1414 }
1415 break;
1416 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001417 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001418 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001419 }
1420
1421 switch (format)
1422 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001423 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1424 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1425 if (context->getExtensions().textureCompressionDXT1)
1426 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001427 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001428 return false;
1429 }
1430 else
1431 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001432 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 return false;
1434 }
1435 break;
1436 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1437 if (context->getExtensions().textureCompressionDXT3)
1438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001439 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001440 return false;
1441 }
1442 else
1443 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001444 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001445 return false;
1446 }
1447 break;
1448 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1449 if (context->getExtensions().textureCompressionDXT5)
1450 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001451 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001452 return false;
1453 }
1454 else
1455 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001456 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001457 return false;
1458 }
1459 break;
1460 case GL_ETC1_RGB8_OES:
1461 if (context->getExtensions().compressedETC1RGB8Texture)
1462 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001463 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001464 return false;
1465 }
1466 else
1467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001468 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001469 return false;
1470 }
1471 break;
1472 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001473 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1474 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1475 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1476 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001477 if (context->getExtensions().lossyETCDecode)
1478 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001479 context->handleError(InvalidOperation()
1480 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001481 return false;
1482 }
1483 else
1484 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001485 context->handleError(InvalidEnum()
1486 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 return false;
1488 }
1489 break;
1490 case GL_DEPTH_COMPONENT:
1491 case GL_DEPTH_STENCIL_OES:
1492 if (!context->getExtensions().depthTextures)
1493 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001494 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001495 return false;
1496 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001497 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001498 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001499 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001500 return false;
1501 }
1502 // OES_depth_texture supports loading depth data and multiple levels,
1503 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001504 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001505 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001506 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1507 return false;
1508 }
1509 if (level != 0)
1510 {
1511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001512 return false;
1513 }
1514 break;
1515 default:
1516 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001517 }
1518
Geoff Lang6e898aa2017-06-02 11:17:26 -04001519 if (!isSubImage)
1520 {
1521 switch (internalformat)
1522 {
1523 case GL_RGBA32F:
1524 if (!context->getExtensions().colorBufferFloatRGBA)
1525 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001526 context->handleError(InvalidValue()
1527 << "Sized GL_RGBA32F internal format requires "
1528 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001529 return false;
1530 }
1531 if (type != GL_FLOAT)
1532 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001533 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001534 return false;
1535 }
1536 if (format != GL_RGBA)
1537 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001538 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001539 return false;
1540 }
1541 break;
1542
1543 case GL_RGB32F:
1544 if (!context->getExtensions().colorBufferFloatRGB)
1545 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001546 context->handleError(InvalidValue()
1547 << "Sized GL_RGB32F internal format requires "
1548 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001549 return false;
1550 }
1551 if (type != GL_FLOAT)
1552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001553 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001554 return false;
1555 }
1556 if (format != GL_RGB)
1557 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001558 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001559 return false;
1560 }
1561 break;
1562
1563 default:
1564 break;
1565 }
1566 }
1567
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001568 if (type == GL_FLOAT)
1569 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001570 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001571 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001572 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001573 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001574 }
1575 }
1576 else if (type == GL_HALF_FLOAT_OES)
1577 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001578 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001579 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001580 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001581 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001582 }
1583 }
1584 }
1585
Geoff Langdbcced82017-06-06 15:55:54 -04001586 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001587 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001588 imageSize))
1589 {
1590 return false;
1591 }
1592
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001593 return true;
1594}
1595
He Yunchaoced53ae2016-11-29 15:00:51 +08001596bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001597 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001598 GLsizei levels,
1599 GLenum internalformat,
1600 GLsizei width,
1601 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001602{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001603 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1604 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001605 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001606 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001607 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001608 }
1609
1610 if (width < 1 || height < 1 || levels < 1)
1611 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001612 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001613 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001614 }
1615
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001616 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001617 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001618 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001619 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001620 }
1621
1622 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1623 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001624 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001625 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001626 }
1627
Geoff Langca271392017-04-05 12:30:00 -04001628 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001629 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001630 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001631 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001632 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 }
1634
Geoff Langaae65a42014-05-26 12:43:44 -04001635 const gl::Caps &caps = context->getCaps();
1636
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001637 switch (target)
1638 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001639 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001640 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1641 static_cast<GLuint>(height) > caps.max2DTextureSize)
1642 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001643 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001644 return false;
1645 }
1646 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001647 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001648 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1649 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1650 {
1651 context->handleError(InvalidValue());
1652 return false;
1653 }
1654 if (formatInfo.compressed)
1655 {
1656 context->handleError(InvalidEnum()
1657 << "Rectangle texture cannot have a compressed format.");
1658 return false;
1659 }
1660 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001661 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001662 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1663 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1664 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001665 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001666 return false;
1667 }
1668 break;
1669 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001670 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001671 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001672 }
1673
Geoff Langc0b9ef42014-07-02 10:02:37 -04001674 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001675 {
1676 if (!gl::isPow2(width) || !gl::isPow2(height))
1677 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001678 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001679 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001680 }
1681 }
1682
1683 switch (internalformat)
1684 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001685 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1686 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1687 if (!context->getExtensions().textureCompressionDXT1)
1688 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001689 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001690 return false;
1691 }
1692 break;
1693 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1694 if (!context->getExtensions().textureCompressionDXT3)
1695 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001696 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001697 return false;
1698 }
1699 break;
1700 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1701 if (!context->getExtensions().textureCompressionDXT5)
1702 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001703 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001704 return false;
1705 }
1706 break;
1707 case GL_ETC1_RGB8_OES:
1708 if (!context->getExtensions().compressedETC1RGB8Texture)
1709 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001710 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001711 return false;
1712 }
1713 break;
1714 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001715 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1716 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1717 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1718 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001719 if (!context->getExtensions().lossyETCDecode)
1720 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001721 context->handleError(InvalidEnum()
1722 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001723 return false;
1724 }
1725 break;
1726 case GL_RGBA32F_EXT:
1727 case GL_RGB32F_EXT:
1728 case GL_ALPHA32F_EXT:
1729 case GL_LUMINANCE32F_EXT:
1730 case GL_LUMINANCE_ALPHA32F_EXT:
1731 if (!context->getExtensions().textureFloat)
1732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001733 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001734 return false;
1735 }
1736 break;
1737 case GL_RGBA16F_EXT:
1738 case GL_RGB16F_EXT:
1739 case GL_ALPHA16F_EXT:
1740 case GL_LUMINANCE16F_EXT:
1741 case GL_LUMINANCE_ALPHA16F_EXT:
1742 if (!context->getExtensions().textureHalfFloat)
1743 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001744 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001745 return false;
1746 }
1747 break;
1748 case GL_R8_EXT:
1749 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001750 if (!context->getExtensions().textureRG)
1751 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001752 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001753 return false;
1754 }
1755 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001756 case GL_R16F_EXT:
1757 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001758 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1759 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001760 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001761 return false;
1762 }
1763 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001764 case GL_R32F_EXT:
1765 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001766 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001767 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001768 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 return false;
1770 }
1771 break;
1772 case GL_DEPTH_COMPONENT16:
1773 case GL_DEPTH_COMPONENT32_OES:
1774 case GL_DEPTH24_STENCIL8_OES:
1775 if (!context->getExtensions().depthTextures)
1776 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001777 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001778 return false;
1779 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001780 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001781 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001782 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001783 return false;
1784 }
1785 // ANGLE_depth_texture only supports 1-level textures
1786 if (levels != 1)
1787 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001788 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001789 return false;
1790 }
1791 break;
1792 default:
1793 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001794 }
1795
Geoff Lang691e58c2014-12-19 17:03:25 -05001796 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001797 if (!texture || texture->id() == 0)
1798 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001799 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001800 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001801 }
1802
Geoff Lang69cce582015-09-17 13:20:36 -04001803 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001804 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001805 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001806 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001807 }
1808
1809 return true;
1810}
1811
He Yunchaoced53ae2016-11-29 15:00:51 +08001812bool ValidateDiscardFramebufferEXT(Context *context,
1813 GLenum target,
1814 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001815 const GLenum *attachments)
1816{
Jamie Madillc29968b2016-01-20 11:17:23 -05001817 if (!context->getExtensions().discardFramebuffer)
1818 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001819 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001820 return false;
1821 }
1822
Austin Kinross08332632015-05-05 13:35:47 -07001823 bool defaultFramebuffer = false;
1824
1825 switch (target)
1826 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001827 case GL_FRAMEBUFFER:
1828 defaultFramebuffer =
1829 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1830 break;
1831 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001832 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001833 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001834 }
1835
He Yunchaoced53ae2016-11-29 15:00:51 +08001836 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1837 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001838}
1839
Austin Kinrossbc781f32015-10-26 09:27:38 -07001840bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1841{
1842 if (!context->getExtensions().vertexArrayObject)
1843 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001844 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001845 return false;
1846 }
1847
1848 return ValidateBindVertexArrayBase(context, array);
1849}
1850
Jamie Madilld7576732017-08-26 18:49:50 -04001851bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001852{
1853 if (!context->getExtensions().vertexArrayObject)
1854 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001855 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001856 return false;
1857 }
1858
Olli Etuaho41997e72016-03-10 13:38:39 +02001859 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001860}
1861
Jamie Madilld7576732017-08-26 18:49:50 -04001862bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001863{
1864 if (!context->getExtensions().vertexArrayObject)
1865 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001866 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001867 return false;
1868 }
1869
Olli Etuaho41997e72016-03-10 13:38:39 +02001870 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001871}
1872
Jamie Madilld7576732017-08-26 18:49:50 -04001873bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001874{
1875 if (!context->getExtensions().vertexArrayObject)
1876 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001877 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001878 return false;
1879 }
1880
1881 return true;
1882}
Geoff Langc5629752015-12-07 16:29:04 -05001883
1884bool ValidateProgramBinaryOES(Context *context,
1885 GLuint program,
1886 GLenum binaryFormat,
1887 const void *binary,
1888 GLint length)
1889{
1890 if (!context->getExtensions().getProgramBinary)
1891 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001892 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001893 return false;
1894 }
1895
1896 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1897}
1898
1899bool ValidateGetProgramBinaryOES(Context *context,
1900 GLuint program,
1901 GLsizei bufSize,
1902 GLsizei *length,
1903 GLenum *binaryFormat,
1904 void *binary)
1905{
1906 if (!context->getExtensions().getProgramBinary)
1907 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001908 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001909 return false;
1910 }
1911
1912 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1913}
Geoff Lange102fee2015-12-10 11:23:30 -05001914
Geoff Lang70d0f492015-12-10 17:45:46 -05001915static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1916{
1917 switch (source)
1918 {
1919 case GL_DEBUG_SOURCE_API:
1920 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1921 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1922 case GL_DEBUG_SOURCE_OTHER:
1923 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1924 return !mustBeThirdPartyOrApplication;
1925
1926 case GL_DEBUG_SOURCE_THIRD_PARTY:
1927 case GL_DEBUG_SOURCE_APPLICATION:
1928 return true;
1929
1930 default:
1931 return false;
1932 }
1933}
1934
1935static bool ValidDebugType(GLenum type)
1936{
1937 switch (type)
1938 {
1939 case GL_DEBUG_TYPE_ERROR:
1940 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1941 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1942 case GL_DEBUG_TYPE_PERFORMANCE:
1943 case GL_DEBUG_TYPE_PORTABILITY:
1944 case GL_DEBUG_TYPE_OTHER:
1945 case GL_DEBUG_TYPE_MARKER:
1946 case GL_DEBUG_TYPE_PUSH_GROUP:
1947 case GL_DEBUG_TYPE_POP_GROUP:
1948 return true;
1949
1950 default:
1951 return false;
1952 }
1953}
1954
1955static bool ValidDebugSeverity(GLenum severity)
1956{
1957 switch (severity)
1958 {
1959 case GL_DEBUG_SEVERITY_HIGH:
1960 case GL_DEBUG_SEVERITY_MEDIUM:
1961 case GL_DEBUG_SEVERITY_LOW:
1962 case GL_DEBUG_SEVERITY_NOTIFICATION:
1963 return true;
1964
1965 default:
1966 return false;
1967 }
1968}
1969
Geoff Lange102fee2015-12-10 11:23:30 -05001970bool ValidateDebugMessageControlKHR(Context *context,
1971 GLenum source,
1972 GLenum type,
1973 GLenum severity,
1974 GLsizei count,
1975 const GLuint *ids,
1976 GLboolean enabled)
1977{
1978 if (!context->getExtensions().debug)
1979 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001980 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001981 return false;
1982 }
1983
Geoff Lang70d0f492015-12-10 17:45:46 -05001984 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1985 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001986 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001987 return false;
1988 }
1989
1990 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1991 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001992 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001993 return false;
1994 }
1995
1996 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1997 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001998 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001999 return false;
2000 }
2001
2002 if (count > 0)
2003 {
2004 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002006 context->handleError(
2007 InvalidOperation()
2008 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002009 return false;
2010 }
2011
2012 if (severity != GL_DONT_CARE)
2013 {
Jamie Madill437fa652016-05-03 15:13:24 -04002014 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002015 InvalidOperation()
2016 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002017 return false;
2018 }
2019 }
2020
Geoff Lange102fee2015-12-10 11:23:30 -05002021 return true;
2022}
2023
2024bool ValidateDebugMessageInsertKHR(Context *context,
2025 GLenum source,
2026 GLenum type,
2027 GLuint id,
2028 GLenum severity,
2029 GLsizei length,
2030 const GLchar *buf)
2031{
2032 if (!context->getExtensions().debug)
2033 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002034 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002035 return false;
2036 }
2037
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002038 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002039 {
2040 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2041 // not generate an error.
2042 return false;
2043 }
2044
2045 if (!ValidDebugSeverity(severity))
2046 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002047 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002048 return false;
2049 }
2050
2051 if (!ValidDebugType(type))
2052 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002053 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002054 return false;
2055 }
2056
2057 if (!ValidDebugSource(source, true))
2058 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002059 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002060 return false;
2061 }
2062
2063 size_t messageLength = (length < 0) ? strlen(buf) : length;
2064 if (messageLength > context->getExtensions().maxDebugMessageLength)
2065 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002066 context->handleError(InvalidValue()
2067 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002068 return false;
2069 }
2070
Geoff Lange102fee2015-12-10 11:23:30 -05002071 return true;
2072}
2073
2074bool ValidateDebugMessageCallbackKHR(Context *context,
2075 GLDEBUGPROCKHR callback,
2076 const void *userParam)
2077{
2078 if (!context->getExtensions().debug)
2079 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002081 return false;
2082 }
2083
Geoff Lange102fee2015-12-10 11:23:30 -05002084 return true;
2085}
2086
2087bool ValidateGetDebugMessageLogKHR(Context *context,
2088 GLuint count,
2089 GLsizei bufSize,
2090 GLenum *sources,
2091 GLenum *types,
2092 GLuint *ids,
2093 GLenum *severities,
2094 GLsizei *lengths,
2095 GLchar *messageLog)
2096{
2097 if (!context->getExtensions().debug)
2098 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002099 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002100 return false;
2101 }
2102
Geoff Lang70d0f492015-12-10 17:45:46 -05002103 if (bufSize < 0 && messageLog != nullptr)
2104 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002105 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002106 return false;
2107 }
2108
Geoff Lange102fee2015-12-10 11:23:30 -05002109 return true;
2110}
2111
2112bool ValidatePushDebugGroupKHR(Context *context,
2113 GLenum source,
2114 GLuint id,
2115 GLsizei length,
2116 const GLchar *message)
2117{
2118 if (!context->getExtensions().debug)
2119 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002120 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002121 return false;
2122 }
2123
Geoff Lang70d0f492015-12-10 17:45:46 -05002124 if (!ValidDebugSource(source, true))
2125 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002126 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002127 return false;
2128 }
2129
2130 size_t messageLength = (length < 0) ? strlen(message) : length;
2131 if (messageLength > context->getExtensions().maxDebugMessageLength)
2132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002133 context->handleError(InvalidValue()
2134 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002135 return false;
2136 }
2137
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002138 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002139 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2140 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002141 context
2142 ->handleError(StackOverflow()
2143 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002144 return false;
2145 }
2146
Geoff Lange102fee2015-12-10 11:23:30 -05002147 return true;
2148}
2149
2150bool ValidatePopDebugGroupKHR(Context *context)
2151{
2152 if (!context->getExtensions().debug)
2153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002155 return false;
2156 }
2157
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002158 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002159 if (currentStackSize <= 1)
2160 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002161 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002162 return false;
2163 }
2164
2165 return true;
2166}
2167
2168static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2169{
2170 switch (identifier)
2171 {
2172 case GL_BUFFER:
2173 if (context->getBuffer(name) == nullptr)
2174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002175 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002176 return false;
2177 }
2178 return true;
2179
2180 case GL_SHADER:
2181 if (context->getShader(name) == nullptr)
2182 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002183 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002184 return false;
2185 }
2186 return true;
2187
2188 case GL_PROGRAM:
2189 if (context->getProgram(name) == nullptr)
2190 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002191 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002192 return false;
2193 }
2194 return true;
2195
2196 case GL_VERTEX_ARRAY:
2197 if (context->getVertexArray(name) == nullptr)
2198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002199 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002200 return false;
2201 }
2202 return true;
2203
2204 case GL_QUERY:
2205 if (context->getQuery(name) == nullptr)
2206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002207 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002208 return false;
2209 }
2210 return true;
2211
2212 case GL_TRANSFORM_FEEDBACK:
2213 if (context->getTransformFeedback(name) == nullptr)
2214 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002215 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002216 return false;
2217 }
2218 return true;
2219
2220 case GL_SAMPLER:
2221 if (context->getSampler(name) == nullptr)
2222 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002223 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002224 return false;
2225 }
2226 return true;
2227
2228 case GL_TEXTURE:
2229 if (context->getTexture(name) == nullptr)
2230 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002231 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002232 return false;
2233 }
2234 return true;
2235
2236 case GL_RENDERBUFFER:
2237 if (context->getRenderbuffer(name) == nullptr)
2238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002239 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002240 return false;
2241 }
2242 return true;
2243
2244 case GL_FRAMEBUFFER:
2245 if (context->getFramebuffer(name) == nullptr)
2246 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002247 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002248 return false;
2249 }
2250 return true;
2251
2252 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002253 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002254 return false;
2255 }
Geoff Lange102fee2015-12-10 11:23:30 -05002256}
2257
Martin Radev9d901792016-07-15 15:58:58 +03002258static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2259{
2260 size_t labelLength = 0;
2261
2262 if (length < 0)
2263 {
2264 if (label != nullptr)
2265 {
2266 labelLength = strlen(label);
2267 }
2268 }
2269 else
2270 {
2271 labelLength = static_cast<size_t>(length);
2272 }
2273
2274 if (labelLength > context->getExtensions().maxLabelLength)
2275 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002276 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002277 return false;
2278 }
2279
2280 return true;
2281}
2282
Geoff Lange102fee2015-12-10 11:23:30 -05002283bool ValidateObjectLabelKHR(Context *context,
2284 GLenum identifier,
2285 GLuint name,
2286 GLsizei length,
2287 const GLchar *label)
2288{
2289 if (!context->getExtensions().debug)
2290 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002291 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002292 return false;
2293 }
2294
Geoff Lang70d0f492015-12-10 17:45:46 -05002295 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2296 {
2297 return false;
2298 }
2299
Martin Radev9d901792016-07-15 15:58:58 +03002300 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002301 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002302 return false;
2303 }
2304
Geoff Lange102fee2015-12-10 11:23:30 -05002305 return true;
2306}
2307
2308bool ValidateGetObjectLabelKHR(Context *context,
2309 GLenum identifier,
2310 GLuint name,
2311 GLsizei bufSize,
2312 GLsizei *length,
2313 GLchar *label)
2314{
2315 if (!context->getExtensions().debug)
2316 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002317 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002318 return false;
2319 }
2320
Geoff Lang70d0f492015-12-10 17:45:46 -05002321 if (bufSize < 0)
2322 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002323 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002324 return false;
2325 }
2326
2327 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2328 {
2329 return false;
2330 }
2331
Martin Radev9d901792016-07-15 15:58:58 +03002332 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002333}
2334
2335static bool ValidateObjectPtrName(Context *context, const void *ptr)
2336{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002337 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002338 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002339 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002340 return false;
2341 }
2342
Geoff Lange102fee2015-12-10 11:23:30 -05002343 return true;
2344}
2345
2346bool ValidateObjectPtrLabelKHR(Context *context,
2347 const void *ptr,
2348 GLsizei length,
2349 const GLchar *label)
2350{
2351 if (!context->getExtensions().debug)
2352 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002354 return false;
2355 }
2356
Geoff Lang70d0f492015-12-10 17:45:46 -05002357 if (!ValidateObjectPtrName(context, ptr))
2358 {
2359 return false;
2360 }
2361
Martin Radev9d901792016-07-15 15:58:58 +03002362 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002363 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002364 return false;
2365 }
2366
Geoff Lange102fee2015-12-10 11:23:30 -05002367 return true;
2368}
2369
2370bool ValidateGetObjectPtrLabelKHR(Context *context,
2371 const void *ptr,
2372 GLsizei bufSize,
2373 GLsizei *length,
2374 GLchar *label)
2375{
2376 if (!context->getExtensions().debug)
2377 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002378 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002379 return false;
2380 }
2381
Geoff Lang70d0f492015-12-10 17:45:46 -05002382 if (bufSize < 0)
2383 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002384 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002385 return false;
2386 }
2387
2388 if (!ValidateObjectPtrName(context, ptr))
2389 {
2390 return false;
2391 }
2392
Martin Radev9d901792016-07-15 15:58:58 +03002393 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002394}
2395
2396bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2397{
2398 if (!context->getExtensions().debug)
2399 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002401 return false;
2402 }
2403
Geoff Lang70d0f492015-12-10 17:45:46 -05002404 // TODO: represent this in Context::getQueryParameterInfo.
2405 switch (pname)
2406 {
2407 case GL_DEBUG_CALLBACK_FUNCTION:
2408 case GL_DEBUG_CALLBACK_USER_PARAM:
2409 break;
2410
2411 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002412 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002413 return false;
2414 }
2415
Geoff Lange102fee2015-12-10 11:23:30 -05002416 return true;
2417}
Jamie Madillc29968b2016-01-20 11:17:23 -05002418
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002419bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2420 GLenum pname,
2421 GLsizei bufSize,
2422 GLsizei *length,
2423 void **params)
2424{
2425 UNIMPLEMENTED();
2426 return false;
2427}
2428
Jamie Madillc29968b2016-01-20 11:17:23 -05002429bool ValidateBlitFramebufferANGLE(Context *context,
2430 GLint srcX0,
2431 GLint srcY0,
2432 GLint srcX1,
2433 GLint srcY1,
2434 GLint dstX0,
2435 GLint dstY0,
2436 GLint dstX1,
2437 GLint dstY1,
2438 GLbitfield mask,
2439 GLenum filter)
2440{
2441 if (!context->getExtensions().framebufferBlit)
2442 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002443 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002444 return false;
2445 }
2446
2447 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2448 {
2449 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002450 context->handleError(InvalidOperation() << "Scaling and flipping in "
2451 "BlitFramebufferANGLE not supported by this "
2452 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002453 return false;
2454 }
2455
2456 if (filter == GL_LINEAR)
2457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002458 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002459 return false;
2460 }
2461
Jamie Madill51f40ec2016-06-15 14:06:00 -04002462 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2463 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002464
2465 if (mask & GL_COLOR_BUFFER_BIT)
2466 {
2467 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2468 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2469
2470 if (readColorAttachment && drawColorAttachment)
2471 {
2472 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002473 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002474 readColorAttachment->type() != GL_RENDERBUFFER &&
2475 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2476 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002477 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002478 return false;
2479 }
2480
Geoff Langa15472a2015-08-11 11:48:03 -04002481 for (size_t drawbufferIdx = 0;
2482 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 {
Geoff Langa15472a2015-08-11 11:48:03 -04002484 const FramebufferAttachment *attachment =
2485 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2486 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002487 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002488 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002489 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002490 attachment->type() != GL_RENDERBUFFER &&
2491 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2492 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002493 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002494 return false;
2495 }
2496
2497 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002498 if (!Format::EquivalentForBlit(attachment->getFormat(),
2499 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002500 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002501 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002502 return false;
2503 }
2504 }
2505 }
2506
Jamie Madill427064d2018-04-13 16:20:34 -04002507 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002508 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002509 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2510 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2511 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002512 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002513 return false;
2514 }
2515 }
2516 }
2517
2518 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2519 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2520 for (size_t i = 0; i < 2; i++)
2521 {
2522 if (mask & masks[i])
2523 {
2524 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002525 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002526 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002527 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002528
2529 if (readBuffer && drawBuffer)
2530 {
2531 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2532 dstX0, dstY0, dstX1, dstY1))
2533 {
2534 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002535 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2536 "stencil blits are supported by "
2537 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 return false;
2539 }
2540
2541 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2542 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002543 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002544 return false;
2545 }
2546 }
2547 }
2548 }
2549
2550 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2551 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002552}
Jamie Madillc29968b2016-01-20 11:17:23 -05002553
Jamie Madill5b772312018-03-08 20:28:32 -05002554bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002555{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002556 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002557
Jamie Madill427064d2018-04-13 16:20:34 -04002558 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002559 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002560 return false;
2561 }
2562
2563 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2564 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002565 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002566 return false;
2567 }
2568
Geoff Lang76e65652017-03-27 14:58:02 -04002569 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2570 {
2571 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2572 GL_SIGNED_NORMALIZED};
2573
Corentin Wallez59c41592017-07-11 13:19:54 -04002574 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002575 drawBufferIdx++)
2576 {
2577 if (!ValidateWebGLFramebufferAttachmentClearType(
2578 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2579 {
2580 return false;
2581 }
2582 }
2583 }
2584
Jamie Madillc29968b2016-01-20 11:17:23 -05002585 return true;
2586}
2587
Jamie Madill5b772312018-03-08 20:28:32 -05002588bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002589{
2590 if (!context->getExtensions().drawBuffers)
2591 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002592 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002593 return false;
2594 }
2595
2596 return ValidateDrawBuffersBase(context, n, bufs);
2597}
2598
Jamie Madill73a84962016-02-12 09:27:23 -05002599bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002600 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002601 GLint level,
2602 GLint internalformat,
2603 GLsizei width,
2604 GLsizei height,
2605 GLint border,
2606 GLenum format,
2607 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002608 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002609{
Martin Radev1be913c2016-07-11 17:59:16 +03002610 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002611 {
2612 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002613 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002614 }
2615
Martin Radev1be913c2016-07-11 17:59:16 +03002616 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002617 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002618 0, 0, width, height, 1, border, format, type, -1,
2619 pixels);
2620}
2621
Brandon Jones416aaf92018-04-10 08:10:16 -07002622bool ValidateTexImage2DRobustANGLE(Context *context,
2623 TextureTarget target,
2624 GLint level,
2625 GLint internalformat,
2626 GLsizei width,
2627 GLsizei height,
2628 GLint border,
2629 GLenum format,
2630 GLenum type,
2631 GLsizei bufSize,
2632 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002633{
2634 if (!ValidateRobustEntryPoint(context, bufSize))
2635 {
2636 return false;
2637 }
2638
2639 if (context->getClientMajorVersion() < 3)
2640 {
2641 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2642 0, 0, width, height, border, format, type, bufSize,
2643 pixels);
2644 }
2645
2646 ASSERT(context->getClientMajorVersion() >= 3);
2647 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2648 0, 0, width, height, 1, border, format, type, bufSize,
2649 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002650}
2651
2652bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002653 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002654 GLint level,
2655 GLint xoffset,
2656 GLint yoffset,
2657 GLsizei width,
2658 GLsizei height,
2659 GLenum format,
2660 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002661 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002662{
2663
Martin Radev1be913c2016-07-11 17:59:16 +03002664 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002665 {
2666 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002667 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002668 }
2669
Martin Radev1be913c2016-07-11 17:59:16 +03002670 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002671 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002672 yoffset, 0, width, height, 1, 0, format, type, -1,
2673 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002674}
2675
Geoff Langc52f6f12016-10-14 10:18:00 -04002676bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002677 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002678 GLint level,
2679 GLint xoffset,
2680 GLint yoffset,
2681 GLsizei width,
2682 GLsizei height,
2683 GLenum format,
2684 GLenum type,
2685 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002686 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002687{
2688 if (!ValidateRobustEntryPoint(context, bufSize))
2689 {
2690 return false;
2691 }
2692
2693 if (context->getClientMajorVersion() < 3)
2694 {
2695 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2696 yoffset, width, height, 0, format, type, bufSize,
2697 pixels);
2698 }
2699
2700 ASSERT(context->getClientMajorVersion() >= 3);
2701 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2702 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2703 pixels);
2704}
2705
Jamie Madill73a84962016-02-12 09:27:23 -05002706bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002707 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002708 GLint level,
2709 GLenum internalformat,
2710 GLsizei width,
2711 GLsizei height,
2712 GLint border,
2713 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002714 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002715{
Martin Radev1be913c2016-07-11 17:59:16 +03002716 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002717 {
2718 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002719 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002720 {
2721 return false;
2722 }
2723 }
2724 else
2725 {
Martin Radev1be913c2016-07-11 17:59:16 +03002726 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002727 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002728 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002729 data))
2730 {
2731 return false;
2732 }
2733 }
2734
Geoff Langca271392017-04-05 12:30:00 -04002735 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002736 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002737 if (blockSizeOrErr.isError())
2738 {
2739 context->handleError(blockSizeOrErr.getError());
2740 return false;
2741 }
2742
2743 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002744 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002745 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002746 return false;
2747 }
2748
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002749 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002750 {
2751 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2752 return false;
2753 }
2754
Jamie Madill73a84962016-02-12 09:27:23 -05002755 return true;
2756}
2757
Corentin Wallezb2931602017-04-11 15:58:57 -04002758bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002759 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002760 GLint level,
2761 GLenum internalformat,
2762 GLsizei width,
2763 GLsizei height,
2764 GLint border,
2765 GLsizei imageSize,
2766 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002767 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002768{
2769 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2770 {
2771 return false;
2772 }
2773
2774 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2775 border, imageSize, data);
2776}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002777
Corentin Wallezb2931602017-04-11 15:58:57 -04002778bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002779 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002780 GLint level,
2781 GLint xoffset,
2782 GLint yoffset,
2783 GLsizei width,
2784 GLsizei height,
2785 GLenum format,
2786 GLsizei imageSize,
2787 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002788 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002789{
2790 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2791 {
2792 return false;
2793 }
2794
2795 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2796 format, imageSize, data);
2797}
2798
Jamie Madill73a84962016-02-12 09:27:23 -05002799bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002800 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002801 GLint level,
2802 GLint xoffset,
2803 GLint yoffset,
2804 GLsizei width,
2805 GLsizei height,
2806 GLenum format,
2807 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002808 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002809{
Martin Radev1be913c2016-07-11 17:59:16 +03002810 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002811 {
2812 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002813 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002814 {
2815 return false;
2816 }
2817 }
2818 else
2819 {
Martin Radev1be913c2016-07-11 17:59:16 +03002820 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002821 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002822 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002823 data))
2824 {
2825 return false;
2826 }
2827 }
2828
Geoff Langca271392017-04-05 12:30:00 -04002829 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002830 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002831 if (blockSizeOrErr.isError())
2832 {
2833 context->handleError(blockSizeOrErr.getError());
2834 return false;
2835 }
2836
2837 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002838 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002839 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002840 return false;
2841 }
2842
2843 return true;
2844}
2845
Corentin Wallez336129f2017-10-17 15:55:40 -04002846bool ValidateGetBufferPointervOES(Context *context,
2847 BufferBinding target,
2848 GLenum pname,
2849 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002850{
Geoff Lang496c02d2016-10-20 11:38:11 -07002851 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002852}
2853
Corentin Wallez336129f2017-10-17 15:55:40 -04002854bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002855{
2856 if (!context->getExtensions().mapBuffer)
2857 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002858 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002859 return false;
2860 }
2861
Corentin Walleze4477002017-12-01 14:39:58 -05002862 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002863 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002864 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002865 return false;
2866 }
2867
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002868 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002869
2870 if (buffer == nullptr)
2871 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002872 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002873 return false;
2874 }
2875
2876 if (access != GL_WRITE_ONLY_OES)
2877 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002878 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002879 return false;
2880 }
2881
2882 if (buffer->isMapped())
2883 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002884 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002885 return false;
2886 }
2887
Geoff Lang79f71042017-08-14 16:43:43 -04002888 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002889}
2890
Corentin Wallez336129f2017-10-17 15:55:40 -04002891bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002892{
2893 if (!context->getExtensions().mapBuffer)
2894 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002895 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002896 return false;
2897 }
2898
2899 return ValidateUnmapBufferBase(context, target);
2900}
2901
2902bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002903 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002904 GLintptr offset,
2905 GLsizeiptr length,
2906 GLbitfield access)
2907{
2908 if (!context->getExtensions().mapBufferRange)
2909 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002910 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002911 return false;
2912 }
2913
2914 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2915}
2916
Corentin Wallez336129f2017-10-17 15:55:40 -04002917bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002918{
2919 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2920 ASSERT(buffer != nullptr);
2921
2922 // Check if this buffer is currently being used as a transform feedback output buffer
2923 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2924 if (transformFeedback != nullptr && transformFeedback->isActive())
2925 {
2926 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2927 {
2928 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2929 if (transformFeedbackBuffer.get() == buffer)
2930 {
2931 context->handleError(InvalidOperation()
2932 << "Buffer is currently bound for transform feedback.");
2933 return false;
2934 }
2935 }
2936 }
2937
James Darpiniane8a93c62018-01-04 18:02:24 -08002938 if (context->getExtensions().webglCompatibility &&
2939 buffer->isBoundForTransformFeedbackAndOtherUse())
2940 {
2941 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2942 return false;
2943 }
2944
Geoff Lang79f71042017-08-14 16:43:43 -04002945 return true;
2946}
2947
Olli Etuaho4f667482016-03-30 15:56:35 +03002948bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002949 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002950 GLintptr offset,
2951 GLsizeiptr length)
2952{
2953 if (!context->getExtensions().mapBufferRange)
2954 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002955 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002956 return false;
2957 }
2958
2959 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2960}
2961
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002962bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002963{
2964 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002965 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002966 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002967 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002968 return false;
2969 }
2970
Geoff Langf41a7152016-09-19 15:11:17 -04002971 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2972 !context->isTextureGenerated(texture))
2973 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002974 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002975 return false;
2976 }
2977
Ian Ewell54f87462016-03-10 13:47:21 -05002978 switch (target)
2979 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002980 case TextureType::_2D:
2981 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002982 break;
2983
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002984 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002985 if (!context->getExtensions().textureRectangle)
2986 {
2987 context->handleError(InvalidEnum()
2988 << "Context does not support GL_ANGLE_texture_rectangle");
2989 return false;
2990 }
2991 break;
2992
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002993 case TextureType::_3D:
2994 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002995 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002996 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002997 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002998 return false;
2999 }
3000 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003001
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003002 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003003 if (context->getClientVersion() < Version(3, 1))
3004 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003005 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003006 return false;
3007 }
Geoff Lang3b573612016-10-31 14:08:10 -04003008 break;
3009
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003010 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003011 if (!context->getExtensions().eglImageExternal &&
3012 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003013 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003014 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003015 return false;
3016 }
3017 break;
3018 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003019 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003020 return false;
3021 }
3022
3023 return true;
3024}
3025
Geoff Langd8605522016-04-13 10:19:12 -04003026bool ValidateBindUniformLocationCHROMIUM(Context *context,
3027 GLuint program,
3028 GLint location,
3029 const GLchar *name)
3030{
3031 if (!context->getExtensions().bindUniformLocation)
3032 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003033 context->handleError(InvalidOperation()
3034 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003035 return false;
3036 }
3037
3038 Program *programObject = GetValidProgram(context, program);
3039 if (!programObject)
3040 {
3041 return false;
3042 }
3043
3044 if (location < 0)
3045 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003046 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003047 return false;
3048 }
3049
3050 const Caps &caps = context->getCaps();
3051 if (static_cast<size_t>(location) >=
3052 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3053 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003054 context->handleError(InvalidValue() << "Location must be less than "
3055 "(MAX_VERTEX_UNIFORM_VECTORS + "
3056 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003057 return false;
3058 }
3059
Geoff Langfc32e8b2017-05-31 14:16:59 -04003060 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3061 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003062 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003063 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003064 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003065 return false;
3066 }
3067
Geoff Langd8605522016-04-13 10:19:12 -04003068 if (strncmp(name, "gl_", 3) == 0)
3069 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003070 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003071 return false;
3072 }
3073
3074 return true;
3075}
3076
Jamie Madille2e406c2016-06-02 13:04:10 -04003077bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003078{
3079 if (!context->getExtensions().framebufferMixedSamples)
3080 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003081 context->handleError(InvalidOperation()
3082 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003083 return false;
3084 }
3085 switch (components)
3086 {
3087 case GL_RGB:
3088 case GL_RGBA:
3089 case GL_ALPHA:
3090 case GL_NONE:
3091 break;
3092 default:
3093 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003094 InvalidEnum()
3095 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003096 return false;
3097 }
3098
3099 return true;
3100}
3101
Sami Väisänene45e53b2016-05-25 10:36:04 +03003102// CHROMIUM_path_rendering
3103
Jamie Madill007530e2017-12-28 14:27:04 -05003104bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003105{
Jamie Madill007530e2017-12-28 14:27:04 -05003106 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003107 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003108 return false;
3109 }
Jamie Madill007530e2017-12-28 14:27:04 -05003110
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111 if (matrix == nullptr)
3112 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003113 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003114 return false;
3115 }
Jamie Madill007530e2017-12-28 14:27:04 -05003116
Sami Väisänene45e53b2016-05-25 10:36:04 +03003117 return true;
3118}
3119
Jamie Madill007530e2017-12-28 14:27:04 -05003120bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003121{
Jamie Madill007530e2017-12-28 14:27:04 -05003122 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003123}
3124
Jamie Madill007530e2017-12-28 14:27:04 -05003125bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003126{
3127 if (!context->getExtensions().pathRendering)
3128 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003129 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003130 return false;
3131 }
3132
3133 // range = 0 is undefined in NV_path_rendering.
3134 // we add stricter semantic check here and require a non zero positive range.
3135 if (range <= 0)
3136 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003137 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003138 return false;
3139 }
3140
3141 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3142 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003143 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003144 return false;
3145 }
3146
3147 return true;
3148}
3149
Jamie Madill007530e2017-12-28 14:27:04 -05003150bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003151{
3152 if (!context->getExtensions().pathRendering)
3153 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003154 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003155 return false;
3156 }
3157
3158 // range = 0 is undefined in NV_path_rendering.
3159 // we add stricter semantic check here and require a non zero positive range.
3160 if (range <= 0)
3161 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003162 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003163 return false;
3164 }
3165
3166 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3167 checkedRange += range;
3168
3169 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3170 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003171 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003172 return false;
3173 }
3174 return true;
3175}
3176
Jamie Madill007530e2017-12-28 14:27:04 -05003177bool ValidatePathCommandsCHROMIUM(Context *context,
3178 GLuint path,
3179 GLsizei numCommands,
3180 const GLubyte *commands,
3181 GLsizei numCoords,
3182 GLenum coordType,
3183 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003184{
3185 if (!context->getExtensions().pathRendering)
3186 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003187 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003188 return false;
3189 }
Brandon Jones59770802018-04-02 13:18:42 -07003190 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003191 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003192 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003193 return false;
3194 }
3195
3196 if (numCommands < 0)
3197 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003198 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003199 return false;
3200 }
3201 else if (numCommands > 0)
3202 {
3203 if (!commands)
3204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003205 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003206 return false;
3207 }
3208 }
3209
3210 if (numCoords < 0)
3211 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003212 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003213 return false;
3214 }
3215 else if (numCoords > 0)
3216 {
3217 if (!coords)
3218 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003219 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003220 return false;
3221 }
3222 }
3223
3224 std::uint32_t coordTypeSize = 0;
3225 switch (coordType)
3226 {
3227 case GL_BYTE:
3228 coordTypeSize = sizeof(GLbyte);
3229 break;
3230
3231 case GL_UNSIGNED_BYTE:
3232 coordTypeSize = sizeof(GLubyte);
3233 break;
3234
3235 case GL_SHORT:
3236 coordTypeSize = sizeof(GLshort);
3237 break;
3238
3239 case GL_UNSIGNED_SHORT:
3240 coordTypeSize = sizeof(GLushort);
3241 break;
3242
3243 case GL_FLOAT:
3244 coordTypeSize = sizeof(GLfloat);
3245 break;
3246
3247 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003248 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003249 return false;
3250 }
3251
3252 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3253 checkedSize += (coordTypeSize * numCoords);
3254 if (!checkedSize.IsValid())
3255 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003256 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003257 return false;
3258 }
3259
3260 // early return skips command data validation when it doesn't exist.
3261 if (!commands)
3262 return true;
3263
3264 GLsizei expectedNumCoords = 0;
3265 for (GLsizei i = 0; i < numCommands; ++i)
3266 {
3267 switch (commands[i])
3268 {
3269 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3270 break;
3271 case GL_MOVE_TO_CHROMIUM:
3272 case GL_LINE_TO_CHROMIUM:
3273 expectedNumCoords += 2;
3274 break;
3275 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3276 expectedNumCoords += 4;
3277 break;
3278 case GL_CUBIC_CURVE_TO_CHROMIUM:
3279 expectedNumCoords += 6;
3280 break;
3281 case GL_CONIC_CURVE_TO_CHROMIUM:
3282 expectedNumCoords += 5;
3283 break;
3284 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003285 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003286 return false;
3287 }
3288 }
3289 if (expectedNumCoords != numCoords)
3290 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003291 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003292 return false;
3293 }
3294
3295 return true;
3296}
3297
Jamie Madill007530e2017-12-28 14:27:04 -05003298bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003299{
3300 if (!context->getExtensions().pathRendering)
3301 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003302 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003303 return false;
3304 }
Brandon Jones59770802018-04-02 13:18:42 -07003305 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003306 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003307 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003308 return false;
3309 }
3310
3311 switch (pname)
3312 {
3313 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3314 if (value < 0.0f)
3315 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003316 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317 return false;
3318 }
3319 break;
3320 case GL_PATH_END_CAPS_CHROMIUM:
3321 switch (static_cast<GLenum>(value))
3322 {
3323 case GL_FLAT_CHROMIUM:
3324 case GL_SQUARE_CHROMIUM:
3325 case GL_ROUND_CHROMIUM:
3326 break;
3327 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003328 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003329 return false;
3330 }
3331 break;
3332 case GL_PATH_JOIN_STYLE_CHROMIUM:
3333 switch (static_cast<GLenum>(value))
3334 {
3335 case GL_MITER_REVERT_CHROMIUM:
3336 case GL_BEVEL_CHROMIUM:
3337 case GL_ROUND_CHROMIUM:
3338 break;
3339 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003340 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003341 return false;
3342 }
Nico Weber41b072b2018-02-09 10:01:32 -05003343 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003344 case GL_PATH_MITER_LIMIT_CHROMIUM:
3345 if (value < 0.0f)
3346 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003347 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003348 return false;
3349 }
3350 break;
3351
3352 case GL_PATH_STROKE_BOUND_CHROMIUM:
3353 // no errors, only clamping.
3354 break;
3355
3356 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003357 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003358 return false;
3359 }
3360 return true;
3361}
3362
Jamie Madill007530e2017-12-28 14:27:04 -05003363bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3364{
3365 // TODO(jmadill): Use proper clamping cast.
3366 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3367}
3368
3369bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003370{
3371 if (!context->getExtensions().pathRendering)
3372 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003373 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003374 return false;
3375 }
3376
Brandon Jones59770802018-04-02 13:18:42 -07003377 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003378 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003379 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003380 return false;
3381 }
3382 if (!value)
3383 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003384 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003385 return false;
3386 }
3387
3388 switch (pname)
3389 {
3390 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3391 case GL_PATH_END_CAPS_CHROMIUM:
3392 case GL_PATH_JOIN_STYLE_CHROMIUM:
3393 case GL_PATH_MITER_LIMIT_CHROMIUM:
3394 case GL_PATH_STROKE_BOUND_CHROMIUM:
3395 break;
3396
3397 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003398 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003399 return false;
3400 }
3401
3402 return true;
3403}
3404
Jamie Madill007530e2017-12-28 14:27:04 -05003405bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3406{
3407 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3408 reinterpret_cast<GLfloat *>(value));
3409}
3410
3411bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003412{
3413 if (!context->getExtensions().pathRendering)
3414 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003415 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003416 return false;
3417 }
3418
3419 switch (func)
3420 {
3421 case GL_NEVER:
3422 case GL_ALWAYS:
3423 case GL_LESS:
3424 case GL_LEQUAL:
3425 case GL_EQUAL:
3426 case GL_GEQUAL:
3427 case GL_GREATER:
3428 case GL_NOTEQUAL:
3429 break;
3430 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003431 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003432 return false;
3433 }
3434
3435 return true;
3436}
3437
3438// Note that the spec specifies that for the path drawing commands
3439// if the path object is not an existing path object the command
3440// does nothing and no error is generated.
3441// However if the path object exists but has not been specified any
3442// commands then an error is generated.
3443
Jamie Madill007530e2017-12-28 14:27:04 -05003444bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003445{
3446 if (!context->getExtensions().pathRendering)
3447 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003448 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003449 return false;
3450 }
Brandon Jones59770802018-04-02 13:18:42 -07003451 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003452 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003453 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003454 return false;
3455 }
3456
3457 switch (fillMode)
3458 {
3459 case GL_COUNT_UP_CHROMIUM:
3460 case GL_COUNT_DOWN_CHROMIUM:
3461 break;
3462 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003463 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003464 return false;
3465 }
3466
3467 if (!isPow2(mask + 1))
3468 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003469 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003470 return false;
3471 }
3472
3473 return true;
3474}
3475
Jamie Madill007530e2017-12-28 14:27:04 -05003476bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003477{
3478 if (!context->getExtensions().pathRendering)
3479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003480 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003481 return false;
3482 }
Brandon Jones59770802018-04-02 13:18:42 -07003483 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003484 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003485 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003486 return false;
3487 }
3488
3489 return true;
3490}
3491
Brandon Jonesd1049182018-03-28 10:02:20 -07003492bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3493{
3494 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3495}
3496
3497bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3498{
3499 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3500}
3501
Jamie Madill007530e2017-12-28 14:27:04 -05003502bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003503{
3504 if (!context->getExtensions().pathRendering)
3505 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003506 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003507 return false;
3508 }
Brandon Jones59770802018-04-02 13:18:42 -07003509 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003512 return false;
3513 }
3514
3515 switch (coverMode)
3516 {
3517 case GL_CONVEX_HULL_CHROMIUM:
3518 case GL_BOUNDING_BOX_CHROMIUM:
3519 break;
3520 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003521 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003522 return false;
3523 }
3524 return true;
3525}
3526
Jamie Madill007530e2017-12-28 14:27:04 -05003527bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3528 GLuint path,
3529 GLenum fillMode,
3530 GLuint mask,
3531 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003532{
Jamie Madill007530e2017-12-28 14:27:04 -05003533 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3534 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003535}
3536
Jamie Madill007530e2017-12-28 14:27:04 -05003537bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3538 GLuint path,
3539 GLint reference,
3540 GLuint mask,
3541 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542{
Jamie Madill007530e2017-12-28 14:27:04 -05003543 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3544 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003545}
3546
Brandon Jonesd1049182018-03-28 10:02:20 -07003547bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003548{
3549 if (!context->getExtensions().pathRendering)
3550 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003551 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003552 return false;
3553 }
3554 return true;
3555}
3556
Jamie Madill007530e2017-12-28 14:27:04 -05003557bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3558 GLsizei numPaths,
3559 GLenum pathNameType,
3560 const void *paths,
3561 GLuint pathBase,
3562 GLenum coverMode,
3563 GLenum transformType,
3564 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003565{
3566 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3567 transformType, transformValues))
3568 return false;
3569
3570 switch (coverMode)
3571 {
3572 case GL_CONVEX_HULL_CHROMIUM:
3573 case GL_BOUNDING_BOX_CHROMIUM:
3574 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3575 break;
3576 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003577 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003578 return false;
3579 }
3580
3581 return true;
3582}
3583
Jamie Madill007530e2017-12-28 14:27:04 -05003584bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3585 GLsizei numPaths,
3586 GLenum pathNameType,
3587 const void *paths,
3588 GLuint pathBase,
3589 GLenum coverMode,
3590 GLenum transformType,
3591 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003592{
3593 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3594 transformType, transformValues))
3595 return false;
3596
3597 switch (coverMode)
3598 {
3599 case GL_CONVEX_HULL_CHROMIUM:
3600 case GL_BOUNDING_BOX_CHROMIUM:
3601 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3602 break;
3603 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003604 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003605 return false;
3606 }
3607
3608 return true;
3609}
3610
Jamie Madill007530e2017-12-28 14:27:04 -05003611bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3612 GLsizei numPaths,
3613 GLenum pathNameType,
3614 const void *paths,
3615 GLuint pathBase,
3616 GLenum fillMode,
3617 GLuint mask,
3618 GLenum transformType,
3619 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003620{
3621
3622 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3623 transformType, transformValues))
3624 return false;
3625
3626 switch (fillMode)
3627 {
3628 case GL_COUNT_UP_CHROMIUM:
3629 case GL_COUNT_DOWN_CHROMIUM:
3630 break;
3631 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003632 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003633 return false;
3634 }
3635 if (!isPow2(mask + 1))
3636 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003637 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003638 return false;
3639 }
3640 return true;
3641}
3642
Jamie Madill007530e2017-12-28 14:27:04 -05003643bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3644 GLsizei numPaths,
3645 GLenum pathNameType,
3646 const void *paths,
3647 GLuint pathBase,
3648 GLint reference,
3649 GLuint mask,
3650 GLenum transformType,
3651 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003652{
3653 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3654 transformType, transformValues))
3655 return false;
3656
3657 // no more validation here.
3658
3659 return true;
3660}
3661
Jamie Madill007530e2017-12-28 14:27:04 -05003662bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3663 GLsizei numPaths,
3664 GLenum pathNameType,
3665 const void *paths,
3666 GLuint pathBase,
3667 GLenum fillMode,
3668 GLuint mask,
3669 GLenum coverMode,
3670 GLenum transformType,
3671 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003672{
3673 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3674 transformType, transformValues))
3675 return false;
3676
3677 switch (coverMode)
3678 {
3679 case GL_CONVEX_HULL_CHROMIUM:
3680 case GL_BOUNDING_BOX_CHROMIUM:
3681 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3682 break;
3683 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003684 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003685 return false;
3686 }
3687
3688 switch (fillMode)
3689 {
3690 case GL_COUNT_UP_CHROMIUM:
3691 case GL_COUNT_DOWN_CHROMIUM:
3692 break;
3693 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003694 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003695 return false;
3696 }
3697 if (!isPow2(mask + 1))
3698 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003699 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003700 return false;
3701 }
3702
3703 return true;
3704}
3705
Jamie Madill007530e2017-12-28 14:27:04 -05003706bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3707 GLsizei numPaths,
3708 GLenum pathNameType,
3709 const void *paths,
3710 GLuint pathBase,
3711 GLint reference,
3712 GLuint mask,
3713 GLenum coverMode,
3714 GLenum transformType,
3715 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003716{
3717 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3718 transformType, transformValues))
3719 return false;
3720
3721 switch (coverMode)
3722 {
3723 case GL_CONVEX_HULL_CHROMIUM:
3724 case GL_BOUNDING_BOX_CHROMIUM:
3725 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3726 break;
3727 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003728 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003729 return false;
3730 }
3731
3732 return true;
3733}
3734
Jamie Madill007530e2017-12-28 14:27:04 -05003735bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3736 GLuint program,
3737 GLint location,
3738 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003739{
3740 if (!context->getExtensions().pathRendering)
3741 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003742 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003743 return false;
3744 }
3745
3746 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3747 if (location >= MaxLocation)
3748 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003749 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003750 return false;
3751 }
3752
3753 const auto *programObject = context->getProgram(program);
3754 if (!programObject)
3755 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003756 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003757 return false;
3758 }
3759
3760 if (!name)
3761 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003762 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003763 return false;
3764 }
3765
3766 if (angle::BeginsWith(name, "gl_"))
3767 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003768 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003769 return false;
3770 }
3771
3772 return true;
3773}
3774
Jamie Madill007530e2017-12-28 14:27:04 -05003775bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3776 GLuint program,
3777 GLint location,
3778 GLenum genMode,
3779 GLint components,
3780 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003781{
3782 if (!context->getExtensions().pathRendering)
3783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003784 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003785 return false;
3786 }
3787
3788 const auto *programObject = context->getProgram(program);
3789 if (!programObject || programObject->isFlaggedForDeletion())
3790 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003791 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003792 return false;
3793 }
3794
3795 if (!programObject->isLinked())
3796 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003797 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003798 return false;
3799 }
3800
3801 switch (genMode)
3802 {
3803 case GL_NONE:
3804 if (components != 0)
3805 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003806 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003807 return false;
3808 }
3809 break;
3810
3811 case GL_OBJECT_LINEAR_CHROMIUM:
3812 case GL_EYE_LINEAR_CHROMIUM:
3813 case GL_CONSTANT_CHROMIUM:
3814 if (components < 1 || components > 4)
3815 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003816 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003817 return false;
3818 }
3819 if (!coeffs)
3820 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003821 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003822 return false;
3823 }
3824 break;
3825
3826 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003827 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003828 return false;
3829 }
3830
3831 // If the location is -1 then the command is silently ignored
3832 // and no further validation is needed.
3833 if (location == -1)
3834 return true;
3835
Jamie Madillbd044ed2017-06-05 12:59:21 -04003836 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003837
3838 if (!binding.valid)
3839 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003840 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003841 return false;
3842 }
3843
3844 if (binding.type != GL_NONE)
3845 {
3846 GLint expectedComponents = 0;
3847 switch (binding.type)
3848 {
3849 case GL_FLOAT:
3850 expectedComponents = 1;
3851 break;
3852 case GL_FLOAT_VEC2:
3853 expectedComponents = 2;
3854 break;
3855 case GL_FLOAT_VEC3:
3856 expectedComponents = 3;
3857 break;
3858 case GL_FLOAT_VEC4:
3859 expectedComponents = 4;
3860 break;
3861 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003862 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003863 InvalidOperation()
3864 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003865 return false;
3866 }
3867 if (expectedComponents != components && genMode != GL_NONE)
3868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003869 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003870 return false;
3871 }
3872 }
3873 return true;
3874}
3875
Geoff Lang97073d12016-04-20 10:42:34 -07003876bool ValidateCopyTextureCHROMIUM(Context *context,
3877 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003878 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003879 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003880 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003881 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003882 GLint internalFormat,
3883 GLenum destType,
3884 GLboolean unpackFlipY,
3885 GLboolean unpackPremultiplyAlpha,
3886 GLboolean unpackUnmultiplyAlpha)
3887{
3888 if (!context->getExtensions().copyTexture)
3889 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003890 context->handleError(InvalidOperation()
3891 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003892 return false;
3893 }
3894
Geoff Lang4f0e0032017-05-01 16:04:35 -04003895 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003896 if (source == nullptr)
3897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003898 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003899 return false;
3900 }
3901
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003902 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003903 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003904 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003905 return false;
3906 }
3907
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003908 TextureType sourceType = source->getType();
3909 ASSERT(sourceType != TextureType::CubeMap);
3910 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003911
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003912 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003913 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003914 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003915 return false;
3916 }
3917
Geoff Lang4f0e0032017-05-01 16:04:35 -04003918 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3919 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3920 if (sourceWidth == 0 || sourceHeight == 0)
3921 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003922 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003923 return false;
3924 }
3925
3926 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3927 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003928 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003929 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003930 return false;
3931 }
3932
Geoff Lang63458a32017-10-30 15:16:53 -04003933 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3934 {
3935 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3936 return false;
3937 }
3938
Geoff Lang4f0e0032017-05-01 16:04:35 -04003939 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003940 if (dest == nullptr)
3941 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003942 context->handleError(InvalidValue()
3943 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003944 return false;
3945 }
3946
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003947 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003948 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003949 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003950 return false;
3951 }
3952
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003953 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003954 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003955 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003956 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003957 return false;
3958 }
3959
Geoff Lang97073d12016-04-20 10:42:34 -07003960 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3961 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003962 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003963 return false;
3964 }
3965
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003966 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003967 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003968 context->handleError(
3969 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003970 return false;
3971 }
3972
Geoff Lang97073d12016-04-20 10:42:34 -07003973 if (dest->getImmutableFormat())
3974 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003975 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003976 return false;
3977 }
3978
3979 return true;
3980}
3981
3982bool ValidateCopySubTextureCHROMIUM(Context *context,
3983 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003984 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003985 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003986 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003987 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003988 GLint xoffset,
3989 GLint yoffset,
3990 GLint x,
3991 GLint y,
3992 GLsizei width,
3993 GLsizei height,
3994 GLboolean unpackFlipY,
3995 GLboolean unpackPremultiplyAlpha,
3996 GLboolean unpackUnmultiplyAlpha)
3997{
3998 if (!context->getExtensions().copyTexture)
3999 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004000 context->handleError(InvalidOperation()
4001 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004002 return false;
4003 }
4004
Geoff Lang4f0e0032017-05-01 16:04:35 -04004005 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004006 if (source == nullptr)
4007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004008 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004009 return false;
4010 }
4011
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004012 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004013 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004014 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004015 return false;
4016 }
4017
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004018 TextureType sourceType = source->getType();
4019 ASSERT(sourceType != TextureType::CubeMap);
4020 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004021
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004022 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004023 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004024 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004025 return false;
4026 }
4027
4028 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4029 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004030 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004031 context->handleError(InvalidValue()
4032 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004033 return false;
4034 }
4035
4036 if (x < 0 || y < 0)
4037 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004038 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004039 return false;
4040 }
4041
4042 if (width < 0 || height < 0)
4043 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004044 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004045 return false;
4046 }
4047
Geoff Lang4f0e0032017-05-01 16:04:35 -04004048 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4049 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004050 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004051 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004052 return false;
4053 }
4054
Geoff Lang4f0e0032017-05-01 16:04:35 -04004055 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4056 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004058 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004059 return false;
4060 }
4061
Geoff Lang63458a32017-10-30 15:16:53 -04004062 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4063 {
4064 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4065 return false;
4066 }
4067
Geoff Lang4f0e0032017-05-01 16:04:35 -04004068 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004069 if (dest == nullptr)
4070 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004071 context->handleError(InvalidValue()
4072 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004073 return false;
4074 }
4075
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004076 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004077 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004078 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004079 return false;
4080 }
4081
Brandon Jones28783792018-03-05 09:37:32 -08004082 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4083 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004084 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004085 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004086 return false;
4087 }
4088
Geoff Lang4f0e0032017-05-01 16:04:35 -04004089 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4090 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004091 context
4092 ->handleError(InvalidOperation()
4093 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004094 return false;
4095 }
4096
4097 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4098 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004099 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004100 context->handleError(InvalidOperation()
4101 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004102 return false;
4103 }
4104
4105 if (xoffset < 0 || yoffset < 0)
4106 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004107 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004108 return false;
4109 }
4110
Geoff Lang4f0e0032017-05-01 16:04:35 -04004111 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4112 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004113 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004114 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004115 return false;
4116 }
4117
4118 return true;
4119}
4120
Geoff Lang47110bf2016-04-20 11:13:22 -07004121bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4122{
4123 if (!context->getExtensions().copyCompressedTexture)
4124 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004125 context->handleError(InvalidOperation()
4126 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004127 return false;
4128 }
4129
4130 const gl::Texture *source = context->getTexture(sourceId);
4131 if (source == nullptr)
4132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004133 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004134 return false;
4135 }
4136
Corentin Wallez99d492c2018-02-27 15:17:10 -05004137 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004139 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004140 return false;
4141 }
4142
Corentin Wallez99d492c2018-02-27 15:17:10 -05004143 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4144 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004145 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004146 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004147 return false;
4148 }
4149
Corentin Wallez99d492c2018-02-27 15:17:10 -05004150 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004151 if (!sourceFormat.info->compressed)
4152 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004153 context->handleError(InvalidOperation()
4154 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004155 return false;
4156 }
4157
4158 const gl::Texture *dest = context->getTexture(destId);
4159 if (dest == nullptr)
4160 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004161 context->handleError(InvalidValue()
4162 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004163 return false;
4164 }
4165
Corentin Wallez99d492c2018-02-27 15:17:10 -05004166 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004168 context->handleError(InvalidValue()
4169 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004170 return false;
4171 }
4172
4173 if (dest->getImmutableFormat())
4174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004175 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004176 return false;
4177 }
4178
4179 return true;
4180}
4181
Jiawei Shao385b3e02018-03-21 09:43:28 +08004182bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004183{
4184 switch (type)
4185 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004186 case ShaderType::Vertex:
4187 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004188 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004189
Jiawei Shao385b3e02018-03-21 09:43:28 +08004190 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004191 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004192 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004193 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004194 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004195 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004196 break;
4197
Jiawei Shao385b3e02018-03-21 09:43:28 +08004198 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004199 if (!context->getExtensions().geometryShader)
4200 {
4201 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4202 return false;
4203 }
4204 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004205 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004206 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004207 return false;
4208 }
Jamie Madill29639852016-09-02 15:00:09 -04004209
4210 return true;
4211}
4212
Jamie Madill5b772312018-03-08 20:28:32 -05004213bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004214 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004215 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004216 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004217 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004218{
4219 if (size < 0)
4220 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004221 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004222 return false;
4223 }
4224
4225 switch (usage)
4226 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004227 case BufferUsage::StreamDraw:
4228 case BufferUsage::StaticDraw:
4229 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004230 break;
4231
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004232 case BufferUsage::StreamRead:
4233 case BufferUsage::StaticRead:
4234 case BufferUsage::DynamicRead:
4235 case BufferUsage::StreamCopy:
4236 case BufferUsage::StaticCopy:
4237 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004238 if (context->getClientMajorVersion() < 3)
4239 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004240 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004241 return false;
4242 }
4243 break;
4244
4245 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004246 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004247 return false;
4248 }
4249
Corentin Walleze4477002017-12-01 14:39:58 -05004250 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004251 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004252 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004253 return false;
4254 }
4255
4256 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4257
4258 if (!buffer)
4259 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004260 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004261 return false;
4262 }
4263
James Darpiniane8a93c62018-01-04 18:02:24 -08004264 if (context->getExtensions().webglCompatibility &&
4265 buffer->isBoundForTransformFeedbackAndOtherUse())
4266 {
4267 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4268 return false;
4269 }
4270
Jamie Madill29639852016-09-02 15:00:09 -04004271 return true;
4272}
4273
Jamie Madill5b772312018-03-08 20:28:32 -05004274bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004275 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004276 GLintptr offset,
4277 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004278 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004279{
Brandon Jones6cad5662017-06-14 13:25:13 -07004280 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004281 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004282 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4283 return false;
4284 }
4285
4286 if (offset < 0)
4287 {
4288 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004289 return false;
4290 }
4291
Corentin Walleze4477002017-12-01 14:39:58 -05004292 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004293 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004294 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004295 return false;
4296 }
4297
4298 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4299
4300 if (!buffer)
4301 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004302 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004303 return false;
4304 }
4305
4306 if (buffer->isMapped())
4307 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004308 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004309 return false;
4310 }
4311
James Darpiniane8a93c62018-01-04 18:02:24 -08004312 if (context->getExtensions().webglCompatibility &&
4313 buffer->isBoundForTransformFeedbackAndOtherUse())
4314 {
4315 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4316 return false;
4317 }
4318
Jamie Madill29639852016-09-02 15:00:09 -04004319 // Check for possible overflow of size + offset
4320 angle::CheckedNumeric<size_t> checkedSize(size);
4321 checkedSize += offset;
4322 if (!checkedSize.IsValid())
4323 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004324 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004325 return false;
4326 }
4327
4328 if (size + offset > buffer->getSize())
4329 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004330 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004331 return false;
4332 }
4333
Martin Radev4c4c8e72016-08-04 12:25:34 +03004334 return true;
4335}
4336
Geoff Lang111a99e2017-10-17 10:58:41 -04004337bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004338{
Geoff Langc339c4e2016-11-29 10:37:36 -05004339 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004340 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004341 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004342 return false;
4343 }
4344
Geoff Lang111a99e2017-10-17 10:58:41 -04004345 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004346 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004347 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004348 return false;
4349 }
4350
4351 return true;
4352}
4353
Jamie Madill5b772312018-03-08 20:28:32 -05004354bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004355{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004356 if (context->getClientMajorVersion() < 2)
4357 {
4358 return ValidateMultitextureUnit(context, texture);
4359 }
4360
Jamie Madillef300b12016-10-07 15:12:09 -04004361 if (texture < GL_TEXTURE0 ||
4362 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4363 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004364 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004365 return false;
4366 }
4367
4368 return true;
4369}
4370
Jamie Madill5b772312018-03-08 20:28:32 -05004371bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004372{
4373 Program *programObject = GetValidProgram(context, program);
4374 if (!programObject)
4375 {
4376 return false;
4377 }
4378
4379 Shader *shaderObject = GetValidShader(context, shader);
4380 if (!shaderObject)
4381 {
4382 return false;
4383 }
4384
Jiawei Shao385b3e02018-03-21 09:43:28 +08004385 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004386 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004387 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4388 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004389 }
4390
4391 return true;
4392}
4393
Jamie Madill5b772312018-03-08 20:28:32 -05004394bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004395{
4396 if (index >= MAX_VERTEX_ATTRIBS)
4397 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004398 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004399 return false;
4400 }
4401
4402 if (strncmp(name, "gl_", 3) == 0)
4403 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004404 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004405 return false;
4406 }
4407
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004408 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004409 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004410 const size_t length = strlen(name);
4411
4412 if (!IsValidESSLString(name, length))
4413 {
4414 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4415 // for shader-related entry points
4416 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4417 return false;
4418 }
4419
4420 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4421 {
4422 return false;
4423 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004424 }
4425
Jamie Madill01a80ee2016-11-07 12:06:18 -05004426 return GetValidProgram(context, program) != nullptr;
4427}
4428
Jamie Madill5b772312018-03-08 20:28:32 -05004429bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004430{
Corentin Walleze4477002017-12-01 14:39:58 -05004431 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004432 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004433 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004434 return false;
4435 }
4436
4437 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4438 !context->isBufferGenerated(buffer))
4439 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004440 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004441 return false;
4442 }
4443
4444 return true;
4445}
4446
Jamie Madill5b772312018-03-08 20:28:32 -05004447bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004448{
Geoff Lange8afa902017-09-27 15:00:43 -04004449 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004450 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004451 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004452 return false;
4453 }
4454
4455 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4456 !context->isFramebufferGenerated(framebuffer))
4457 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004458 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004459 return false;
4460 }
4461
4462 return true;
4463}
4464
Jamie Madill5b772312018-03-08 20:28:32 -05004465bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004466{
4467 if (target != GL_RENDERBUFFER)
4468 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004469 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004470 return false;
4471 }
4472
4473 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4474 !context->isRenderbufferGenerated(renderbuffer))
4475 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004477 return false;
4478 }
4479
4480 return true;
4481}
4482
Jamie Madill5b772312018-03-08 20:28:32 -05004483static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004484{
4485 switch (mode)
4486 {
4487 case GL_FUNC_ADD:
4488 case GL_FUNC_SUBTRACT:
4489 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004490 return true;
4491
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004492 case GL_MIN:
4493 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004494 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004495
4496 default:
4497 return false;
4498 }
4499}
4500
Jamie Madill5b772312018-03-08 20:28:32 -05004501bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004502{
4503 return true;
4504}
4505
Jamie Madill5b772312018-03-08 20:28:32 -05004506bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004507{
Geoff Lang50cac572017-09-26 17:37:43 -04004508 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004509 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004510 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004511 return false;
4512 }
4513
4514 return true;
4515}
4516
Jamie Madill5b772312018-03-08 20:28:32 -05004517bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004518{
Geoff Lang50cac572017-09-26 17:37:43 -04004519 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004520 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004521 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004522 return false;
4523 }
4524
Geoff Lang50cac572017-09-26 17:37:43 -04004525 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004526 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004527 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004528 return false;
4529 }
4530
4531 return true;
4532}
4533
Jamie Madill5b772312018-03-08 20:28:32 -05004534bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004535{
4536 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4537}
4538
4539static bool ValidSrcBlendFunc(GLenum srcBlend)
4540{
4541 switch (srcBlend)
4542 {
4543 case GL_ZERO:
4544 case GL_ONE:
4545 case GL_SRC_COLOR:
4546 case GL_ONE_MINUS_SRC_COLOR:
4547 case GL_DST_COLOR:
4548 case GL_ONE_MINUS_DST_COLOR:
4549 case GL_SRC_ALPHA:
4550 case GL_ONE_MINUS_SRC_ALPHA:
4551 case GL_DST_ALPHA:
4552 case GL_ONE_MINUS_DST_ALPHA:
4553 case GL_CONSTANT_COLOR:
4554 case GL_ONE_MINUS_CONSTANT_COLOR:
4555 case GL_CONSTANT_ALPHA:
4556 case GL_ONE_MINUS_CONSTANT_ALPHA:
4557 case GL_SRC_ALPHA_SATURATE:
4558 return true;
4559
4560 default:
4561 return false;
4562 }
4563}
4564
4565static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4566{
4567 switch (dstBlend)
4568 {
4569 case GL_ZERO:
4570 case GL_ONE:
4571 case GL_SRC_COLOR:
4572 case GL_ONE_MINUS_SRC_COLOR:
4573 case GL_DST_COLOR:
4574 case GL_ONE_MINUS_DST_COLOR:
4575 case GL_SRC_ALPHA:
4576 case GL_ONE_MINUS_SRC_ALPHA:
4577 case GL_DST_ALPHA:
4578 case GL_ONE_MINUS_DST_ALPHA:
4579 case GL_CONSTANT_COLOR:
4580 case GL_ONE_MINUS_CONSTANT_COLOR:
4581 case GL_CONSTANT_ALPHA:
4582 case GL_ONE_MINUS_CONSTANT_ALPHA:
4583 return true;
4584
4585 case GL_SRC_ALPHA_SATURATE:
4586 return (contextMajorVersion >= 3);
4587
4588 default:
4589 return false;
4590 }
4591}
4592
Jamie Madill5b772312018-03-08 20:28:32 -05004593bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004594 GLenum srcRGB,
4595 GLenum dstRGB,
4596 GLenum srcAlpha,
4597 GLenum dstAlpha)
4598{
4599 if (!ValidSrcBlendFunc(srcRGB))
4600 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004602 return false;
4603 }
4604
4605 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4606 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004607 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004608 return false;
4609 }
4610
4611 if (!ValidSrcBlendFunc(srcAlpha))
4612 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004613 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004614 return false;
4615 }
4616
4617 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4618 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004619 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004620 return false;
4621 }
4622
Frank Henigman146e8a12017-03-02 23:22:37 -05004623 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4624 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004625 {
4626 bool constantColorUsed =
4627 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4628 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4629
4630 bool constantAlphaUsed =
4631 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4632 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4633
4634 if (constantColorUsed && constantAlphaUsed)
4635 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004636 const char *msg;
4637 if (context->getExtensions().webglCompatibility)
4638 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004639 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004640 }
4641 else
4642 {
4643 msg =
4644 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4645 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4646 "implementation.";
4647 ERR() << msg;
4648 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004649 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004650 return false;
4651 }
4652 }
4653
4654 return true;
4655}
4656
Geoff Langc339c4e2016-11-29 10:37:36 -05004657bool ValidateGetString(Context *context, GLenum name)
4658{
4659 switch (name)
4660 {
4661 case GL_VENDOR:
4662 case GL_RENDERER:
4663 case GL_VERSION:
4664 case GL_SHADING_LANGUAGE_VERSION:
4665 case GL_EXTENSIONS:
4666 break;
4667
4668 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4669 if (!context->getExtensions().requestExtension)
4670 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004671 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004672 return false;
4673 }
4674 break;
4675
4676 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004677 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004678 return false;
4679 }
4680
4681 return true;
4682}
4683
Jamie Madill5b772312018-03-08 20:28:32 -05004684bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004685{
4686 if (width <= 0.0f || isNaN(width))
4687 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004688 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004689 return false;
4690 }
4691
4692 return true;
4693}
4694
Jamie Madill5b772312018-03-08 20:28:32 -05004695bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004696 GLuint index,
4697 GLint size,
4698 GLenum type,
4699 GLboolean normalized,
4700 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004701 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004702{
Shao80957d92017-02-20 21:25:59 +08004703 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004704 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004705 return false;
4706 }
4707
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004708 if (stride < 0)
4709 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004710 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004711 return false;
4712 }
4713
Shao80957d92017-02-20 21:25:59 +08004714 const Caps &caps = context->getCaps();
4715 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004716 {
Shao80957d92017-02-20 21:25:59 +08004717 if (stride > caps.maxVertexAttribStride)
4718 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004719 context->handleError(InvalidValue()
4720 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004721 return false;
4722 }
4723
4724 if (index >= caps.maxVertexAttribBindings)
4725 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004726 context->handleError(InvalidValue()
4727 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004728 return false;
4729 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004730 }
4731
4732 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4733 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4734 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4735 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004736 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4737 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004738 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4739 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004740 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004741 context
4742 ->handleError(InvalidOperation()
4743 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004744 return false;
4745 }
4746
4747 if (context->getExtensions().webglCompatibility)
4748 {
4749 // WebGL 1.0 [Section 6.14] Fixed point support
4750 // The WebGL API does not support the GL_FIXED data type.
4751 if (type == GL_FIXED)
4752 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004753 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004754 return false;
4755 }
4756
Geoff Lang2d62ab72017-03-23 16:54:40 -04004757 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004758 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004759 return false;
4760 }
4761 }
4762
4763 return true;
4764}
4765
Jamie Madill5b772312018-03-08 20:28:32 -05004766bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004767{
4768 if (context->getExtensions().webglCompatibility && zNear > zFar)
4769 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004770 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004771 return false;
4772 }
4773
4774 return true;
4775}
4776
Jamie Madill5b772312018-03-08 20:28:32 -05004777bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004778 GLenum target,
4779 GLenum internalformat,
4780 GLsizei width,
4781 GLsizei height)
4782{
4783 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4784 height);
4785}
4786
Jamie Madill5b772312018-03-08 20:28:32 -05004787bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004788 GLenum target,
4789 GLsizei samples,
4790 GLenum internalformat,
4791 GLsizei width,
4792 GLsizei height)
4793{
4794 if (!context->getExtensions().framebufferMultisample)
4795 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004796 context->handleError(InvalidOperation()
4797 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004798 return false;
4799 }
4800
4801 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4802 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4803 // generated.
4804 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4805 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004806 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004807 return false;
4808 }
4809
4810 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4811 // the specified storage. This is different than ES 3.0 in which a sample number higher
4812 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4813 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4814 if (context->getClientMajorVersion() >= 3)
4815 {
4816 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4817 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4818 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004819 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004820 return false;
4821 }
4822 }
4823
4824 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4825 width, height);
4826}
4827
Jamie Madill5b772312018-03-08 20:28:32 -05004828bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004829{
Geoff Lange8afa902017-09-27 15:00:43 -04004830 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004831 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004832 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004833 return false;
4834 }
4835
4836 return true;
4837}
4838
Jamie Madill5b772312018-03-08 20:28:32 -05004839bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004840{
4841 return true;
4842}
4843
Jamie Madill5b772312018-03-08 20:28:32 -05004844bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004845{
4846 return true;
4847}
4848
Jamie Madill5b772312018-03-08 20:28:32 -05004849bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004850{
4851 return true;
4852}
4853
Jamie Madill5b772312018-03-08 20:28:32 -05004854bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004855 GLboolean red,
4856 GLboolean green,
4857 GLboolean blue,
4858 GLboolean alpha)
4859{
4860 return true;
4861}
4862
Jamie Madill5b772312018-03-08 20:28:32 -05004863bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004864{
4865 return true;
4866}
4867
Jamie Madill5b772312018-03-08 20:28:32 -05004868bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004869{
4870 return true;
4871}
4872
Jamie Madill5b772312018-03-08 20:28:32 -05004873bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004874{
4875 switch (mode)
4876 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004877 case CullFaceMode::Front:
4878 case CullFaceMode::Back:
4879 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004880 break;
4881
4882 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004883 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004884 return false;
4885 }
4886
4887 return true;
4888}
4889
Jamie Madill5b772312018-03-08 20:28:32 -05004890bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004891{
4892 if (program == 0)
4893 {
4894 return false;
4895 }
4896
4897 if (!context->getProgram(program))
4898 {
4899 if (context->getShader(program))
4900 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004901 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004902 return false;
4903 }
4904 else
4905 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004906 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004907 return false;
4908 }
4909 }
4910
4911 return true;
4912}
4913
Jamie Madill5b772312018-03-08 20:28:32 -05004914bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004915{
4916 if (shader == 0)
4917 {
4918 return false;
4919 }
4920
4921 if (!context->getShader(shader))
4922 {
4923 if (context->getProgram(shader))
4924 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004925 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004926 return false;
4927 }
4928 else
4929 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004930 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004931 return false;
4932 }
4933 }
4934
4935 return true;
4936}
4937
Jamie Madill5b772312018-03-08 20:28:32 -05004938bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004939{
4940 switch (func)
4941 {
4942 case GL_NEVER:
4943 case GL_ALWAYS:
4944 case GL_LESS:
4945 case GL_LEQUAL:
4946 case GL_EQUAL:
4947 case GL_GREATER:
4948 case GL_GEQUAL:
4949 case GL_NOTEQUAL:
4950 break;
4951
4952 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004953 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004954 return false;
4955 }
4956
4957 return true;
4958}
4959
Jamie Madill5b772312018-03-08 20:28:32 -05004960bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004961{
4962 return true;
4963}
4964
Jamie Madill5b772312018-03-08 20:28:32 -05004965bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004966{
4967 Program *programObject = GetValidProgram(context, program);
4968 if (!programObject)
4969 {
4970 return false;
4971 }
4972
4973 Shader *shaderObject = GetValidShader(context, shader);
4974 if (!shaderObject)
4975 {
4976 return false;
4977 }
4978
Jiawei Shao385b3e02018-03-21 09:43:28 +08004979 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004980 if (attachedShader != shaderObject)
4981 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004982 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004983 return false;
4984 }
4985
4986 return true;
4987}
4988
Jamie Madill5b772312018-03-08 20:28:32 -05004989bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004990{
4991 if (index >= MAX_VERTEX_ATTRIBS)
4992 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004993 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004994 return false;
4995 }
4996
4997 return true;
4998}
4999
Jamie Madill5b772312018-03-08 20:28:32 -05005000bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005001{
5002 if (index >= MAX_VERTEX_ATTRIBS)
5003 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005004 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005005 return false;
5006 }
5007
5008 return true;
5009}
5010
Jamie Madill5b772312018-03-08 20:28:32 -05005011bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005012{
5013 return true;
5014}
5015
Jamie Madill5b772312018-03-08 20:28:32 -05005016bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005017{
5018 return true;
5019}
5020
Jamie Madill5b772312018-03-08 20:28:32 -05005021bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005022{
5023 switch (mode)
5024 {
5025 case GL_CW:
5026 case GL_CCW:
5027 break;
5028 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005029 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005030 return false;
5031 }
5032
5033 return true;
5034}
5035
Jamie Madill5b772312018-03-08 20:28:32 -05005036bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005037 GLuint program,
5038 GLuint index,
5039 GLsizei bufsize,
5040 GLsizei *length,
5041 GLint *size,
5042 GLenum *type,
5043 GLchar *name)
5044{
5045 if (bufsize < 0)
5046 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005047 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005048 return false;
5049 }
5050
5051 Program *programObject = GetValidProgram(context, program);
5052
5053 if (!programObject)
5054 {
5055 return false;
5056 }
5057
5058 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5059 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005060 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005061 return false;
5062 }
5063
5064 return true;
5065}
5066
Jamie Madill5b772312018-03-08 20:28:32 -05005067bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005068 GLuint program,
5069 GLuint index,
5070 GLsizei bufsize,
5071 GLsizei *length,
5072 GLint *size,
5073 GLenum *type,
5074 GLchar *name)
5075{
5076 if (bufsize < 0)
5077 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005078 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005079 return false;
5080 }
5081
5082 Program *programObject = GetValidProgram(context, program);
5083
5084 if (!programObject)
5085 {
5086 return false;
5087 }
5088
5089 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5090 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005091 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005092 return false;
5093 }
5094
5095 return true;
5096}
5097
Jamie Madill5b772312018-03-08 20:28:32 -05005098bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005099 GLuint program,
5100 GLsizei maxcount,
5101 GLsizei *count,
5102 GLuint *shaders)
5103{
5104 if (maxcount < 0)
5105 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005106 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005107 return false;
5108 }
5109
5110 Program *programObject = GetValidProgram(context, program);
5111
5112 if (!programObject)
5113 {
5114 return false;
5115 }
5116
5117 return true;
5118}
5119
Jamie Madill5b772312018-03-08 20:28:32 -05005120bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005121{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005122 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5123 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005124 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005125 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005126 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005127 return false;
5128 }
5129
Jamie Madillc1d770e2017-04-13 17:31:24 -04005130 Program *programObject = GetValidProgram(context, program);
5131
5132 if (!programObject)
5133 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005134 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005135 return false;
5136 }
5137
5138 if (!programObject->isLinked())
5139 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005140 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005141 return false;
5142 }
5143
5144 return true;
5145}
5146
Jamie Madill5b772312018-03-08 20:28:32 -05005147bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005148{
5149 GLenum nativeType;
5150 unsigned int numParams = 0;
5151 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5152}
5153
Jamie Madill5b772312018-03-08 20:28:32 -05005154bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005155{
5156 return true;
5157}
5158
Jamie Madill5b772312018-03-08 20:28:32 -05005159bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005160{
5161 GLenum nativeType;
5162 unsigned int numParams = 0;
5163 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5164}
5165
Jamie Madill5b772312018-03-08 20:28:32 -05005166bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005167{
5168 GLenum nativeType;
5169 unsigned int numParams = 0;
5170 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5171}
5172
Jamie Madill5b772312018-03-08 20:28:32 -05005173bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005174 GLuint program,
5175 GLsizei bufsize,
5176 GLsizei *length,
5177 GLchar *infolog)
5178{
5179 if (bufsize < 0)
5180 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005181 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005182 return false;
5183 }
5184
5185 Program *programObject = GetValidProgram(context, program);
5186 if (!programObject)
5187 {
5188 return false;
5189 }
5190
5191 return true;
5192}
5193
Jamie Madill5b772312018-03-08 20:28:32 -05005194bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005195 GLuint shader,
5196 GLsizei bufsize,
5197 GLsizei *length,
5198 GLchar *infolog)
5199{
5200 if (bufsize < 0)
5201 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005202 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005203 return false;
5204 }
5205
5206 Shader *shaderObject = GetValidShader(context, shader);
5207 if (!shaderObject)
5208 {
5209 return false;
5210 }
5211
5212 return true;
5213}
5214
Jamie Madill5b772312018-03-08 20:28:32 -05005215bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005216 GLenum shadertype,
5217 GLenum precisiontype,
5218 GLint *range,
5219 GLint *precision)
5220{
5221 switch (shadertype)
5222 {
5223 case GL_VERTEX_SHADER:
5224 case GL_FRAGMENT_SHADER:
5225 break;
5226 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005227 context->handleError(InvalidOperation()
5228 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005229 return false;
5230 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005231 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005232 return false;
5233 }
5234
5235 switch (precisiontype)
5236 {
5237 case GL_LOW_FLOAT:
5238 case GL_MEDIUM_FLOAT:
5239 case GL_HIGH_FLOAT:
5240 case GL_LOW_INT:
5241 case GL_MEDIUM_INT:
5242 case GL_HIGH_INT:
5243 break;
5244
5245 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005246 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005247 return false;
5248 }
5249
5250 return true;
5251}
5252
Jamie Madill5b772312018-03-08 20:28:32 -05005253bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005254 GLuint shader,
5255 GLsizei bufsize,
5256 GLsizei *length,
5257 GLchar *source)
5258{
5259 if (bufsize < 0)
5260 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005261 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005262 return false;
5263 }
5264
5265 Shader *shaderObject = GetValidShader(context, shader);
5266 if (!shaderObject)
5267 {
5268 return false;
5269 }
5270
5271 return true;
5272}
5273
Jamie Madill5b772312018-03-08 20:28:32 -05005274bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005275{
5276 if (strstr(name, "gl_") == name)
5277 {
5278 return false;
5279 }
5280
Geoff Langfc32e8b2017-05-31 14:16:59 -04005281 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5282 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005283 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005284 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005285 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005286 return false;
5287 }
5288
Jamie Madillc1d770e2017-04-13 17:31:24 -04005289 Program *programObject = GetValidProgram(context, program);
5290
5291 if (!programObject)
5292 {
5293 return false;
5294 }
5295
5296 if (!programObject->isLinked())
5297 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005298 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005299 return false;
5300 }
5301
5302 return true;
5303}
5304
Jamie Madill5b772312018-03-08 20:28:32 -05005305bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005306{
5307 switch (mode)
5308 {
5309 case GL_FASTEST:
5310 case GL_NICEST:
5311 case GL_DONT_CARE:
5312 break;
5313
5314 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005315 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005316 return false;
5317 }
5318
5319 switch (target)
5320 {
5321 case GL_GENERATE_MIPMAP_HINT:
5322 break;
5323
Geoff Lange7bd2182017-06-16 16:13:13 -04005324 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5325 if (context->getClientVersion() < ES_3_0 &&
5326 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005327 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005328 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005329 return false;
5330 }
5331 break;
5332
5333 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005334 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005335 return false;
5336 }
5337
5338 return true;
5339}
5340
Jamie Madill5b772312018-03-08 20:28:32 -05005341bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005342{
5343 return true;
5344}
5345
Jamie Madill5b772312018-03-08 20:28:32 -05005346bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347{
5348 return true;
5349}
5350
Jamie Madill5b772312018-03-08 20:28:32 -05005351bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005352{
5353 return true;
5354}
5355
Jamie Madill5b772312018-03-08 20:28:32 -05005356bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005357{
5358 return true;
5359}
5360
Jamie Madill5b772312018-03-08 20:28:32 -05005361bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005362{
5363 return true;
5364}
5365
Jamie Madill5b772312018-03-08 20:28:32 -05005366bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005367{
5368 return true;
5369}
5370
Jamie Madill5b772312018-03-08 20:28:32 -05005371bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005372{
5373 if (context->getClientMajorVersion() < 3)
5374 {
5375 switch (pname)
5376 {
5377 case GL_UNPACK_IMAGE_HEIGHT:
5378 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005379 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005380 return false;
5381
5382 case GL_UNPACK_ROW_LENGTH:
5383 case GL_UNPACK_SKIP_ROWS:
5384 case GL_UNPACK_SKIP_PIXELS:
5385 if (!context->getExtensions().unpackSubimage)
5386 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005387 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005388 return false;
5389 }
5390 break;
5391
5392 case GL_PACK_ROW_LENGTH:
5393 case GL_PACK_SKIP_ROWS:
5394 case GL_PACK_SKIP_PIXELS:
5395 if (!context->getExtensions().packSubimage)
5396 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005397 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005398 return false;
5399 }
5400 break;
5401 }
5402 }
5403
5404 if (param < 0)
5405 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005406 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005407 return false;
5408 }
5409
5410 switch (pname)
5411 {
5412 case GL_UNPACK_ALIGNMENT:
5413 if (param != 1 && param != 2 && param != 4 && param != 8)
5414 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005415 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005416 return false;
5417 }
5418 break;
5419
5420 case GL_PACK_ALIGNMENT:
5421 if (param != 1 && param != 2 && param != 4 && param != 8)
5422 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005423 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005424 return false;
5425 }
5426 break;
5427
5428 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005429 if (!context->getExtensions().packReverseRowOrder)
5430 {
5431 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5432 }
5433 break;
5434
Jamie Madillc1d770e2017-04-13 17:31:24 -04005435 case GL_UNPACK_ROW_LENGTH:
5436 case GL_UNPACK_IMAGE_HEIGHT:
5437 case GL_UNPACK_SKIP_IMAGES:
5438 case GL_UNPACK_SKIP_ROWS:
5439 case GL_UNPACK_SKIP_PIXELS:
5440 case GL_PACK_ROW_LENGTH:
5441 case GL_PACK_SKIP_ROWS:
5442 case GL_PACK_SKIP_PIXELS:
5443 break;
5444
5445 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005446 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005447 return false;
5448 }
5449
5450 return true;
5451}
5452
Jamie Madill5b772312018-03-08 20:28:32 -05005453bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005454{
5455 return true;
5456}
5457
Jamie Madill5b772312018-03-08 20:28:32 -05005458bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005459{
5460 return true;
5461}
5462
Jamie Madill5b772312018-03-08 20:28:32 -05005463bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005464{
5465 return true;
5466}
5467
Jamie Madill5b772312018-03-08 20:28:32 -05005468bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005469{
5470 if (width < 0 || height < 0)
5471 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005472 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005473 return false;
5474 }
5475
5476 return true;
5477}
5478
Jamie Madill5b772312018-03-08 20:28:32 -05005479bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005480 GLsizei n,
5481 const GLuint *shaders,
5482 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005483 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005484 GLsizei length)
5485{
5486 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5487 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5488 shaderBinaryFormats.end())
5489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005490 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005491 return false;
5492 }
5493
5494 return true;
5495}
5496
Jamie Madill5b772312018-03-08 20:28:32 -05005497bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005498 GLuint shader,
5499 GLsizei count,
5500 const GLchar *const *string,
5501 const GLint *length)
5502{
5503 if (count < 0)
5504 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005505 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005506 return false;
5507 }
5508
Geoff Langfc32e8b2017-05-31 14:16:59 -04005509 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5510 // shader-related entry points
5511 if (context->getExtensions().webglCompatibility)
5512 {
5513 for (GLsizei i = 0; i < count; i++)
5514 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005515 size_t len =
5516 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005517
5518 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005519 if (!IsValidESSLShaderSourceString(string[i], len,
5520 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005521 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005522 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005523 return false;
5524 }
5525 }
5526 }
5527
Jamie Madillc1d770e2017-04-13 17:31:24 -04005528 Shader *shaderObject = GetValidShader(context, shader);
5529 if (!shaderObject)
5530 {
5531 return false;
5532 }
5533
5534 return true;
5535}
5536
Jamie Madill5b772312018-03-08 20:28:32 -05005537bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005538{
5539 if (!IsValidStencilFunc(func))
5540 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005541 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005542 return false;
5543 }
5544
5545 return true;
5546}
5547
Jamie Madill5b772312018-03-08 20:28:32 -05005548bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005549{
5550 if (!IsValidStencilFace(face))
5551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005552 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005553 return false;
5554 }
5555
5556 if (!IsValidStencilFunc(func))
5557 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005558 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005559 return false;
5560 }
5561
5562 return true;
5563}
5564
Jamie Madill5b772312018-03-08 20:28:32 -05005565bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005566{
5567 return true;
5568}
5569
Jamie Madill5b772312018-03-08 20:28:32 -05005570bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005571{
5572 if (!IsValidStencilFace(face))
5573 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005574 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005575 return false;
5576 }
5577
5578 return true;
5579}
5580
Jamie Madill5b772312018-03-08 20:28:32 -05005581bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005582{
5583 if (!IsValidStencilOp(fail))
5584 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005585 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005586 return false;
5587 }
5588
5589 if (!IsValidStencilOp(zfail))
5590 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005591 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005592 return false;
5593 }
5594
5595 if (!IsValidStencilOp(zpass))
5596 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005597 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005598 return false;
5599 }
5600
5601 return true;
5602}
5603
Jamie Madill5b772312018-03-08 20:28:32 -05005604bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005605 GLenum face,
5606 GLenum fail,
5607 GLenum zfail,
5608 GLenum zpass)
5609{
5610 if (!IsValidStencilFace(face))
5611 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005612 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005613 return false;
5614 }
5615
5616 return ValidateStencilOp(context, fail, zfail, zpass);
5617}
5618
Jamie Madill5b772312018-03-08 20:28:32 -05005619bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005620{
5621 return ValidateUniform(context, GL_FLOAT, location, 1);
5622}
5623
Jamie Madill5b772312018-03-08 20:28:32 -05005624bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005625{
5626 return ValidateUniform(context, GL_FLOAT, location, count);
5627}
5628
Jamie Madill5b772312018-03-08 20:28:32 -05005629bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005630{
5631 return ValidateUniform1iv(context, location, 1, &x);
5632}
5633
Jamie Madill5b772312018-03-08 20:28:32 -05005634bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005635{
5636 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5637}
5638
Jamie Madill5b772312018-03-08 20:28:32 -05005639bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005640{
5641 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5642}
5643
Jamie Madill5b772312018-03-08 20:28:32 -05005644bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005645{
5646 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5647}
5648
Jamie Madill5b772312018-03-08 20:28:32 -05005649bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650{
5651 return ValidateUniform(context, GL_INT_VEC2, location, count);
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655{
5656 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5657}
5658
Jamie Madill5b772312018-03-08 20:28:32 -05005659bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005660{
5661 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5662}
5663
Jamie Madill5b772312018-03-08 20:28:32 -05005664bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005665{
5666 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670{
5671 return ValidateUniform(context, GL_INT_VEC3, location, count);
5672}
5673
Jamie Madill5b772312018-03-08 20:28:32 -05005674bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675{
5676 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005680{
5681 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5682}
5683
Jamie Madill5b772312018-03-08 20:28:32 -05005684bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005685{
5686 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5687}
5688
Jamie Madill5b772312018-03-08 20:28:32 -05005689bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005690{
5691 return ValidateUniform(context, GL_INT_VEC4, location, count);
5692}
5693
Jamie Madill5b772312018-03-08 20:28:32 -05005694bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005695 GLint location,
5696 GLsizei count,
5697 GLboolean transpose,
5698 const GLfloat *value)
5699{
5700 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5701}
5702
Jamie Madill5b772312018-03-08 20:28:32 -05005703bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005704 GLint location,
5705 GLsizei count,
5706 GLboolean transpose,
5707 const GLfloat *value)
5708{
5709 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5710}
5711
Jamie Madill5b772312018-03-08 20:28:32 -05005712bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005713 GLint location,
5714 GLsizei count,
5715 GLboolean transpose,
5716 const GLfloat *value)
5717{
5718 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5719}
5720
Jamie Madill5b772312018-03-08 20:28:32 -05005721bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005722{
5723 Program *programObject = GetValidProgram(context, program);
5724
5725 if (!programObject)
5726 {
5727 return false;
5728 }
5729
5730 return true;
5731}
5732
Jamie Madill5b772312018-03-08 20:28:32 -05005733bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005734{
5735 return ValidateVertexAttribIndex(context, index);
5736}
5737
Jamie Madill5b772312018-03-08 20:28:32 -05005738bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005739{
5740 return ValidateVertexAttribIndex(context, index);
5741}
5742
Jamie Madill5b772312018-03-08 20:28:32 -05005743bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005744{
5745 return ValidateVertexAttribIndex(context, index);
5746}
5747
Jamie Madill5b772312018-03-08 20:28:32 -05005748bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005749{
5750 return ValidateVertexAttribIndex(context, index);
5751}
5752
Jamie Madill5b772312018-03-08 20:28:32 -05005753bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005754{
5755 return ValidateVertexAttribIndex(context, index);
5756}
5757
Jamie Madill5b772312018-03-08 20:28:32 -05005758bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005759{
5760 return ValidateVertexAttribIndex(context, index);
5761}
5762
Jamie Madill5b772312018-03-08 20:28:32 -05005763bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005764 GLuint index,
5765 GLfloat x,
5766 GLfloat y,
5767 GLfloat z,
5768 GLfloat w)
5769{
5770 return ValidateVertexAttribIndex(context, index);
5771}
5772
Jamie Madill5b772312018-03-08 20:28:32 -05005773bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005774{
5775 return ValidateVertexAttribIndex(context, index);
5776}
5777
Jamie Madill5b772312018-03-08 20:28:32 -05005778bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005779{
5780 if (width < 0 || height < 0)
5781 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005782 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005783 return false;
5784 }
5785
5786 return true;
5787}
5788
Jamie Madill493f9572018-05-24 19:52:15 -04005789bool ValidateDrawArrays(Context *context, PrimitiveMode mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005790{
5791 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5792}
5793
Jamie Madill5b772312018-03-08 20:28:32 -05005794bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005795 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005796 GLsizei count,
5797 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005798 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005799{
5800 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5801}
5802
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005803bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005804 GLenum target,
5805 GLenum attachment,
5806 GLenum pname,
5807 GLint *params)
5808{
5809 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5810 nullptr);
5811}
5812
Jamie Madill5b772312018-03-08 20:28:32 -05005813bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005814{
5815 return ValidateGetProgramivBase(context, program, pname, nullptr);
5816}
5817
Jamie Madill5b772312018-03-08 20:28:32 -05005818bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005819 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005820 GLint level,
5821 GLenum internalformat,
5822 GLint x,
5823 GLint y,
5824 GLsizei width,
5825 GLsizei height,
5826 GLint border)
5827{
5828 if (context->getClientMajorVersion() < 3)
5829 {
5830 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5831 0, x, y, width, height, border);
5832 }
5833
5834 ASSERT(context->getClientMajorVersion() == 3);
5835 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5836 0, x, y, width, height, border);
5837}
5838
5839bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005840 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005841 GLint level,
5842 GLint xoffset,
5843 GLint yoffset,
5844 GLint x,
5845 GLint y,
5846 GLsizei width,
5847 GLsizei height)
5848{
5849 if (context->getClientMajorVersion() < 3)
5850 {
5851 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5852 yoffset, x, y, width, height, 0);
5853 }
5854
5855 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5856 yoffset, 0, x, y, width, height, 0);
5857}
5858
5859bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5860{
5861 return ValidateGenOrDelete(context, n);
5862}
5863
5864bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5865{
5866 return ValidateGenOrDelete(context, n);
5867}
5868
5869bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5870{
5871 return ValidateGenOrDelete(context, n);
5872}
5873
5874bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5875{
5876 return ValidateGenOrDelete(context, n);
5877}
5878
5879bool ValidateDisable(Context *context, GLenum cap)
5880{
5881 if (!ValidCap(context, cap, false))
5882 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005883 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005884 return false;
5885 }
5886
5887 return true;
5888}
5889
5890bool ValidateEnable(Context *context, GLenum cap)
5891{
5892 if (!ValidCap(context, cap, false))
5893 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005894 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005895 return false;
5896 }
5897
5898 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5899 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5900 {
5901 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005902 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005903
5904 // We also output an error message to the debugger window if tracing is active, so that
5905 // developers can see the error message.
5906 ERR() << errorMessage;
5907 return false;
5908 }
5909
5910 return true;
5911}
5912
5913bool ValidateFramebufferRenderbuffer(Context *context,
5914 GLenum target,
5915 GLenum attachment,
5916 GLenum renderbuffertarget,
5917 GLuint renderbuffer)
5918{
Geoff Lange8afa902017-09-27 15:00:43 -04005919 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005920 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005921 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5922 return false;
5923 }
5924
5925 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5926 {
5927 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005928 return false;
5929 }
5930
5931 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5932 renderbuffertarget, renderbuffer);
5933}
5934
5935bool ValidateFramebufferTexture2D(Context *context,
5936 GLenum target,
5937 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005938 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005939 GLuint texture,
5940 GLint level)
5941{
5942 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5943 // extension
5944 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5945 level != 0)
5946 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005947 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005948 return false;
5949 }
5950
5951 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5952 {
5953 return false;
5954 }
5955
5956 if (texture != 0)
5957 {
5958 gl::Texture *tex = context->getTexture(texture);
5959 ASSERT(tex);
5960
5961 const gl::Caps &caps = context->getCaps();
5962
5963 switch (textarget)
5964 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005965 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005966 {
5967 if (level > gl::log2(caps.max2DTextureSize))
5968 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005969 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005970 return false;
5971 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005972 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005973 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005974 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005975 return false;
5976 }
5977 }
5978 break;
5979
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005980 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005981 {
5982 if (level != 0)
5983 {
5984 context->handleError(InvalidValue());
5985 return false;
5986 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005987 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005988 {
5989 context->handleError(InvalidOperation()
5990 << "Textarget must match the texture target type.");
5991 return false;
5992 }
5993 }
5994 break;
5995
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005996 case TextureTarget::CubeMapNegativeX:
5997 case TextureTarget::CubeMapNegativeY:
5998 case TextureTarget::CubeMapNegativeZ:
5999 case TextureTarget::CubeMapPositiveX:
6000 case TextureTarget::CubeMapPositiveY:
6001 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006002 {
6003 if (level > gl::log2(caps.maxCubeMapTextureSize))
6004 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006005 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 return false;
6007 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006008 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006009 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006010 context->handleError(InvalidOperation()
6011 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 return false;
6013 }
6014 }
6015 break;
6016
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006017 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006018 {
6019 if (context->getClientVersion() < ES_3_1)
6020 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006021 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006022 return false;
6023 }
6024
6025 if (level != 0)
6026 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006027 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006028 return false;
6029 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006030 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006031 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006032 context->handleError(InvalidOperation()
6033 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006034 return false;
6035 }
6036 }
6037 break;
6038
6039 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006040 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006041 return false;
6042 }
6043
6044 const Format &format = tex->getFormat(textarget, level);
6045 if (format.info->compressed)
6046 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006047 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006048 return false;
6049 }
6050 }
6051
6052 return true;
6053}
6054
6055bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6056{
6057 return ValidateGenOrDelete(context, n);
6058}
6059
6060bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6061{
6062 return ValidateGenOrDelete(context, n);
6063}
6064
6065bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6066{
6067 return ValidateGenOrDelete(context, n);
6068}
6069
6070bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6071{
6072 return ValidateGenOrDelete(context, n);
6073}
6074
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006075bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006076{
6077 if (!ValidTextureTarget(context, target))
6078 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006079 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006080 return false;
6081 }
6082
6083 Texture *texture = context->getTargetTexture(target);
6084
6085 if (texture == nullptr)
6086 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006087 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006088 return false;
6089 }
6090
6091 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6092
6093 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6094 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6095 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6096 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006097 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006098 return false;
6099 }
6100
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006101 TextureTarget baseTarget = (target == TextureType::CubeMap)
6102 ? TextureTarget::CubeMapPositiveX
6103 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006104 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6105 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6106 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006107 {
6108 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6109 return false;
6110 }
6111
Geoff Lang536eca12017-09-13 11:23:35 -04006112 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6113 bool formatUnsized = !format.sized;
6114 bool formatColorRenderableAndFilterable =
6115 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006116 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006117 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006118 {
Geoff Lang536eca12017-09-13 11:23:35 -04006119 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006120 return false;
6121 }
6122
Geoff Lang536eca12017-09-13 11:23:35 -04006123 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6124 // generation
6125 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6126 {
6127 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6128 return false;
6129 }
6130
6131 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
Geoff Lange24032a2018-03-28 15:41:46 -04006132 // not. Differentiate the ES3 format from the extension format by checking if the format is
6133 // sized, GL_EXT_sRGB does not add any sized formats.
6134 bool supportsSRGBMipmapGeneration = context->getExtensions().webglCompatibility;
6135 if (!supportsSRGBMipmapGeneration && !format.sized && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006136 {
Geoff Lang536eca12017-09-13 11:23:35 -04006137 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006138 return false;
6139 }
6140
6141 // Non-power of 2 ES2 check
6142 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6143 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6144 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6145 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006146 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6147 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006148 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006149 return false;
6150 }
6151
6152 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006153 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006154 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006155 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006156 return false;
6157 }
6158
6159 return true;
6160}
6161
Jamie Madill5b772312018-03-08 20:28:32 -05006162bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006163 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006164 GLenum pname,
6165 GLint *params)
6166{
6167 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6168}
6169
6170bool ValidateGetRenderbufferParameteriv(Context *context,
6171 GLenum target,
6172 GLenum pname,
6173 GLint *params)
6174{
6175 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6176}
6177
6178bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6179{
6180 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6181}
6182
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006183bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006184{
6185 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6186}
6187
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006188bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006189{
6190 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6191}
6192
6193bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6194{
6195 return ValidateGetUniformBase(context, program, location);
6196}
6197
6198bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6199{
6200 return ValidateGetUniformBase(context, program, location);
6201}
6202
6203bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6204{
6205 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6206}
6207
6208bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6209{
6210 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6211}
6212
6213bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6214{
6215 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6216}
6217
6218bool ValidateIsEnabled(Context *context, GLenum cap)
6219{
6220 if (!ValidCap(context, cap, true))
6221 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006222 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006223 return false;
6224 }
6225
6226 return true;
6227}
6228
6229bool ValidateLinkProgram(Context *context, GLuint program)
6230{
6231 if (context->hasActiveTransformFeedback(program))
6232 {
6233 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006234 context->handleError(InvalidOperation() << "Cannot link program while program is "
6235 "associated with an active transform "
6236 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006237 return false;
6238 }
6239
6240 Program *programObject = GetValidProgram(context, program);
6241 if (!programObject)
6242 {
6243 return false;
6244 }
6245
6246 return true;
6247}
6248
Jamie Madill4928b7c2017-06-20 12:57:39 -04006249bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006250 GLint x,
6251 GLint y,
6252 GLsizei width,
6253 GLsizei height,
6254 GLenum format,
6255 GLenum type,
6256 void *pixels)
6257{
6258 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6259 nullptr, pixels);
6260}
6261
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006262bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006263{
6264 return ValidateTexParameterBase(context, target, pname, -1, &param);
6265}
6266
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006267bool ValidateTexParameterfv(Context *context,
6268 TextureType target,
6269 GLenum pname,
6270 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006271{
6272 return ValidateTexParameterBase(context, target, pname, -1, params);
6273}
6274
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006275bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006276{
6277 return ValidateTexParameterBase(context, target, pname, -1, &param);
6278}
6279
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006280bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006281{
6282 return ValidateTexParameterBase(context, target, pname, -1, params);
6283}
6284
6285bool ValidateUseProgram(Context *context, GLuint program)
6286{
6287 if (program != 0)
6288 {
6289 Program *programObject = context->getProgram(program);
6290 if (!programObject)
6291 {
6292 // ES 3.1.0 section 7.3 page 72
6293 if (context->getShader(program))
6294 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006296 return false;
6297 }
6298 else
6299 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006300 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006301 return false;
6302 }
6303 }
6304 if (!programObject->isLinked())
6305 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006306 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006307 return false;
6308 }
6309 }
6310 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6311 {
6312 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006313 context
6314 ->handleError(InvalidOperation()
6315 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006316 return false;
6317 }
6318
6319 return true;
6320}
6321
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006322bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6323{
6324 if (!context->getExtensions().fence)
6325 {
6326 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6327 return false;
6328 }
6329
6330 if (n < 0)
6331 {
6332 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6333 return false;
6334 }
6335
6336 return true;
6337}
6338
6339bool ValidateFinishFenceNV(Context *context, GLuint fence)
6340{
6341 if (!context->getExtensions().fence)
6342 {
6343 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6344 return false;
6345 }
6346
6347 FenceNV *fenceObject = context->getFenceNV(fence);
6348
6349 if (fenceObject == nullptr)
6350 {
6351 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6352 return false;
6353 }
6354
6355 if (!fenceObject->isSet())
6356 {
6357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6358 return false;
6359 }
6360
6361 return true;
6362}
6363
6364bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6365{
6366 if (!context->getExtensions().fence)
6367 {
6368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6369 return false;
6370 }
6371
6372 if (n < 0)
6373 {
6374 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6375 return false;
6376 }
6377
6378 return true;
6379}
6380
6381bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6382{
6383 if (!context->getExtensions().fence)
6384 {
6385 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6386 return false;
6387 }
6388
6389 FenceNV *fenceObject = context->getFenceNV(fence);
6390
6391 if (fenceObject == nullptr)
6392 {
6393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6394 return false;
6395 }
6396
6397 if (!fenceObject->isSet())
6398 {
6399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6400 return false;
6401 }
6402
6403 switch (pname)
6404 {
6405 case GL_FENCE_STATUS_NV:
6406 case GL_FENCE_CONDITION_NV:
6407 break;
6408
6409 default:
6410 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6411 return false;
6412 }
6413
6414 return true;
6415}
6416
6417bool ValidateGetGraphicsResetStatusEXT(Context *context)
6418{
6419 if (!context->getExtensions().robustness)
6420 {
6421 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6422 return false;
6423 }
6424
6425 return true;
6426}
6427
6428bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6429 GLuint shader,
6430 GLsizei bufsize,
6431 GLsizei *length,
6432 GLchar *source)
6433{
6434 if (!context->getExtensions().translatedShaderSource)
6435 {
6436 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6437 return false;
6438 }
6439
6440 if (bufsize < 0)
6441 {
6442 context->handleError(InvalidValue());
6443 return false;
6444 }
6445
6446 Shader *shaderObject = context->getShader(shader);
6447
6448 if (!shaderObject)
6449 {
6450 context->handleError(InvalidOperation());
6451 return false;
6452 }
6453
6454 return true;
6455}
6456
6457bool ValidateIsFenceNV(Context *context, GLuint fence)
6458{
6459 if (!context->getExtensions().fence)
6460 {
6461 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6462 return false;
6463 }
6464
6465 return true;
6466}
6467
Jamie Madill007530e2017-12-28 14:27:04 -05006468bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6469{
6470 if (!context->getExtensions().fence)
6471 {
6472 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6473 return false;
6474 }
6475
6476 if (condition != GL_ALL_COMPLETED_NV)
6477 {
6478 context->handleError(InvalidEnum());
6479 return false;
6480 }
6481
6482 FenceNV *fenceObject = context->getFenceNV(fence);
6483
6484 if (fenceObject == nullptr)
6485 {
6486 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6487 return false;
6488 }
6489
6490 return true;
6491}
6492
6493bool ValidateTestFenceNV(Context *context, GLuint fence)
6494{
6495 if (!context->getExtensions().fence)
6496 {
6497 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6498 return false;
6499 }
6500
6501 FenceNV *fenceObject = context->getFenceNV(fence);
6502
6503 if (fenceObject == nullptr)
6504 {
6505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6506 return false;
6507 }
6508
6509 if (fenceObject->isSet() != GL_TRUE)
6510 {
6511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6512 return false;
6513 }
6514
6515 return true;
6516}
6517
6518bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006519 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006520 GLsizei levels,
6521 GLenum internalformat,
6522 GLsizei width,
6523 GLsizei height)
6524{
6525 if (!context->getExtensions().textureStorage)
6526 {
6527 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6528 return false;
6529 }
6530
6531 if (context->getClientMajorVersion() < 3)
6532 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006533 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006534 height);
6535 }
6536
6537 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006538 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006539 1);
6540}
6541
6542bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6543{
6544 if (!context->getExtensions().instancedArrays)
6545 {
6546 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6547 return false;
6548 }
6549
6550 if (index >= MAX_VERTEX_ATTRIBS)
6551 {
6552 context->handleError(InvalidValue());
6553 return false;
6554 }
6555
6556 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6557 {
6558 if (index == 0 && divisor != 0)
6559 {
6560 const char *errorMessage =
6561 "The current context doesn't support setting a non-zero divisor on the "
6562 "attribute with index zero. "
6563 "Please reorder the attributes in your vertex shader so that attribute zero "
6564 "can have a zero divisor.";
6565 context->handleError(InvalidOperation() << errorMessage);
6566
6567 // We also output an error message to the debugger window if tracing is active, so
6568 // that developers can see the error message.
6569 ERR() << errorMessage;
6570 return false;
6571 }
6572 }
6573
6574 return true;
6575}
6576
6577bool ValidateTexImage3DOES(Context *context,
6578 GLenum target,
6579 GLint level,
6580 GLenum internalformat,
6581 GLsizei width,
6582 GLsizei height,
6583 GLsizei depth,
6584 GLint border,
6585 GLenum format,
6586 GLenum type,
6587 const void *pixels)
6588{
6589 UNIMPLEMENTED(); // FIXME
6590 return false;
6591}
6592
6593bool ValidatePopGroupMarkerEXT(Context *context)
6594{
6595 if (!context->getExtensions().debugMarker)
6596 {
6597 // The debug marker calls should not set error state
6598 // However, it seems reasonable to set an error state if the extension is not enabled
6599 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6600 return false;
6601 }
6602
6603 return true;
6604}
6605
Jamie Madillfa920eb2018-01-04 11:45:50 -05006606bool ValidateTexStorage1DEXT(Context *context,
6607 GLenum target,
6608 GLsizei levels,
6609 GLenum internalformat,
6610 GLsizei width)
6611{
6612 UNIMPLEMENTED();
6613 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6614 return false;
6615}
6616
6617bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006618 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006619 GLsizei levels,
6620 GLenum internalformat,
6621 GLsizei width,
6622 GLsizei height,
6623 GLsizei depth)
6624{
6625 if (!context->getExtensions().textureStorage)
6626 {
6627 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6628 return false;
6629 }
6630
6631 if (context->getClientMajorVersion() < 3)
6632 {
6633 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6634 return false;
6635 }
6636
6637 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6638 depth);
6639}
6640
jchen1082af6202018-06-22 10:59:52 +08006641bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6642{
6643 if (!context->getExtensions().parallelShaderCompile)
6644 {
6645 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6646 return false;
6647 }
6648 return true;
6649}
6650
Jamie Madillc29968b2016-01-20 11:17:23 -05006651} // namespace gl