blob: 10c6e5c59f0861d254f0a192d60d6ea33969e653 [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;
78 if (context->hasPath(pathName) && !context->hasPathData(pathName))
79 {
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
795 default:
796 return false;
797 }
798}
799
Geoff Langfc32e8b2017-05-31 14:16:59 -0400800// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
801// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400802bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400803{
804 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400805 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
806 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400807 {
808 return true;
809 }
810
811 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
812 if (c >= 9 && c <= 13)
813 {
814 return true;
815 }
816
817 return false;
818}
819
Geoff Langcab92ee2017-07-19 17:32:07 -0400820bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400821{
Geoff Langa71a98e2017-06-19 15:15:00 -0400822 for (size_t i = 0; i < len; i++)
823 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400824 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400825 {
826 return false;
827 }
828 }
829
830 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400831}
832
Geoff Langcab92ee2017-07-19 17:32:07 -0400833bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
834{
835 enum class ParseState
836 {
837 // Have not seen an ASCII non-whitespace character yet on
838 // this line. Possible that we might see a preprocessor
839 // directive.
840 BEGINING_OF_LINE,
841
842 // Have seen at least one ASCII non-whitespace character
843 // on this line.
844 MIDDLE_OF_LINE,
845
846 // Handling a preprocessor directive. Passes through all
847 // characters up to the end of the line. Disables comment
848 // processing.
849 IN_PREPROCESSOR_DIRECTIVE,
850
851 // Handling a single-line comment. The comment text is
852 // replaced with a single space.
853 IN_SINGLE_LINE_COMMENT,
854
855 // Handling a multi-line comment. Newlines are passed
856 // through to preserve line numbers.
857 IN_MULTI_LINE_COMMENT
858 };
859
860 ParseState state = ParseState::BEGINING_OF_LINE;
861 size_t pos = 0;
862
863 while (pos < len)
864 {
865 char c = str[pos];
866 char next = pos + 1 < len ? str[pos + 1] : 0;
867
868 // Check for newlines
869 if (c == '\n' || c == '\r')
870 {
871 if (state != ParseState::IN_MULTI_LINE_COMMENT)
872 {
873 state = ParseState::BEGINING_OF_LINE;
874 }
875
876 pos++;
877 continue;
878 }
879
880 switch (state)
881 {
882 case ParseState::BEGINING_OF_LINE:
883 if (c == ' ')
884 {
885 // Maintain the BEGINING_OF_LINE state until a non-space is seen
886 pos++;
887 }
888 else if (c == '#')
889 {
890 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
891 pos++;
892 }
893 else
894 {
895 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
896 state = ParseState::MIDDLE_OF_LINE;
897 }
898 break;
899
900 case ParseState::MIDDLE_OF_LINE:
901 if (c == '/' && next == '/')
902 {
903 state = ParseState::IN_SINGLE_LINE_COMMENT;
904 pos++;
905 }
906 else if (c == '/' && next == '*')
907 {
908 state = ParseState::IN_MULTI_LINE_COMMENT;
909 pos++;
910 }
911 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
912 {
913 // Skip line continuation characters
914 }
915 else if (!IsValidESSLCharacter(c))
916 {
917 return false;
918 }
919 pos++;
920 break;
921
922 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700923 // Line-continuation characters may not be permitted.
924 // Otherwise, just pass it through. Do not parse comments in this state.
925 if (!lineContinuationAllowed && c == '\\')
926 {
927 return false;
928 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400929 pos++;
930 break;
931
932 case ParseState::IN_SINGLE_LINE_COMMENT:
933 // Line-continuation characters are processed before comment processing.
934 // Advance string if a new line character is immediately behind
935 // line-continuation character.
936 if (c == '\\' && (next == '\n' || next == '\r'))
937 {
938 pos++;
939 }
940 pos++;
941 break;
942
943 case ParseState::IN_MULTI_LINE_COMMENT:
944 if (c == '*' && next == '/')
945 {
946 state = ParseState::MIDDLE_OF_LINE;
947 pos++;
948 }
949 pos++;
950 break;
951 }
952 }
953
954 return true;
955}
956
Jamie Madill5b772312018-03-08 20:28:32 -0500957bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700958{
959 ASSERT(context->isWebGL());
960
961 // WebGL 1.0 [Section 6.16] GLSL Constructs
962 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
963 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
964 {
965 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
966 return false;
967 }
968
969 return true;
970}
971
Jamie Madill5b772312018-03-08 20:28:32 -0500972bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700973{
974 ASSERT(context->isWebGL());
975
976 if (context->isWebGL1() && length > 256)
977 {
978 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
979 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
980 // locations.
981 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
982
983 return false;
984 }
985 else if (length > 1024)
986 {
987 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
988 // uniform and attribute locations.
989 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
990 return false;
991 }
992
993 return true;
994}
995
Jamie Madill007530e2017-12-28 14:27:04 -0500996bool ValidateMatrixMode(Context *context, GLenum matrixMode)
997{
998 if (!context->getExtensions().pathRendering)
999 {
1000 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1001 return false;
1002 }
1003
1004 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1005 {
1006 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1007 return false;
1008 }
1009 return true;
1010}
Jamie Madillc29968b2016-01-20 11:17:23 -05001011} // anonymous namespace
1012
Geoff Langff5b2d52016-09-07 11:32:23 -04001013bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001014 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001015 GLint level,
1016 GLenum internalformat,
1017 bool isCompressed,
1018 bool isSubImage,
1019 GLint xoffset,
1020 GLint yoffset,
1021 GLsizei width,
1022 GLsizei height,
1023 GLint border,
1024 GLenum format,
1025 GLenum type,
1026 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001027 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001028{
Jamie Madill6f38f822014-06-06 17:12:20 -04001029 if (!ValidTexture2DDestinationTarget(context, target))
1030 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001031 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001032 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001033 }
1034
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001035 TextureType texType = TextureTargetToType(target);
1036 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001037 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001038 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001039 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001040 }
1041
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001042 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001043 {
1044 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1045 return false;
1046 }
1047
1048 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001049 std::numeric_limits<GLsizei>::max() - yoffset < height)
1050 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001051 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001052 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001053 }
1054
Geoff Lang6e898aa2017-06-02 11:17:26 -04001055 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1056 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1057 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1058 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1059 // case.
1060 bool nonEqualFormatsAllowed =
1061 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1062 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1063
1064 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001065 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001066 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001067 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001068 }
1069
Geoff Langaae65a42014-05-26 12:43:44 -04001070 const gl::Caps &caps = context->getCaps();
1071
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001072 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001073 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001074 case TextureType::_2D:
1075 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1076 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1077 {
1078 context->handleError(InvalidValue());
1079 return false;
1080 }
1081 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001082
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001083 case TextureType::Rectangle:
1084 ASSERT(level == 0);
1085 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1086 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1087 {
1088 context->handleError(InvalidValue());
1089 return false;
1090 }
1091 if (isCompressed)
1092 {
1093 context->handleError(InvalidEnum()
1094 << "Rectangle texture cannot have a compressed format.");
1095 return false;
1096 }
1097 break;
1098
1099 case TextureType::CubeMap:
1100 if (!isSubImage && width != height)
1101 {
1102 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1103 return false;
1104 }
1105
1106 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1107 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1108 {
1109 context->handleError(InvalidValue());
1110 return false;
1111 }
1112 break;
1113
1114 default:
1115 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001116 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001117 }
1118
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001119 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001120 if (!texture)
1121 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001122 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001123 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001124 }
1125
Geoff Langa9be0dc2014-12-17 12:34:40 -05001126 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001127 {
Geoff Langca271392017-04-05 12:30:00 -04001128 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1129 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001131 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001132 return false;
1133 }
1134
Geoff Langa9be0dc2014-12-17 12:34:40 -05001135 if (format != GL_NONE)
1136 {
Geoff Langca271392017-04-05 12:30:00 -04001137 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1138 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001139 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001140 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001141 return false;
1142 }
1143 }
1144
1145 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1146 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001148 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001149 return false;
1150 }
Geoff Langfb052642017-10-24 13:42:09 -04001151
1152 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001153 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001154 {
1155 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1156 return false;
1157 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001158 }
1159 else
1160 {
Geoff Lang69cce582015-09-17 13:20:36 -04001161 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001163 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001164 return false;
1165 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001166 }
1167
1168 // Verify zero border
1169 if (border != 0)
1170 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001171 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001172 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001173 }
1174
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001175 if (isCompressed)
1176 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001177 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001178 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1179 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001180 switch (actualInternalFormat)
1181 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001182 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1183 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1184 if (!context->getExtensions().textureCompressionDXT1)
1185 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001186 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001187 return false;
1188 }
1189 break;
1190 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001191 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001192 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001193 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001194 return false;
1195 }
1196 break;
1197 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1198 if (!context->getExtensions().textureCompressionDXT5)
1199 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001201 return false;
1202 }
1203 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001204 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1205 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1206 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1207 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1208 if (!context->getExtensions().textureCompressionS3TCsRGB)
1209 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001210 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001211 return false;
1212 }
1213 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001214 case GL_ETC1_RGB8_OES:
1215 if (!context->getExtensions().compressedETC1RGB8Texture)
1216 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001217 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001218 return false;
1219 }
Geoff Lang86f81162017-10-30 15:10:45 -04001220 if (isSubImage)
1221 {
1222 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1223 return false;
1224 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001225 break;
1226 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001227 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1228 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1229 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1230 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001231 if (!context->getExtensions().lossyETCDecode)
1232 {
Geoff Lang86f81162017-10-30 15:10:45 -04001233 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001234 return false;
1235 }
1236 break;
1237 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001238 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001239 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001240 }
Geoff Lang966c9402017-04-18 12:38:27 -04001241
1242 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001243 {
Geoff Lang966c9402017-04-18 12:38:27 -04001244 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1245 height, texture->getWidth(target, level),
1246 texture->getHeight(target, level)))
1247 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001248 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001249 return false;
1250 }
1251
1252 if (format != actualInternalFormat)
1253 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001254 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001255 return false;
1256 }
1257 }
1258 else
1259 {
1260 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1261 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001262 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001263 return false;
1264 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001265 }
1266 }
1267 else
1268 {
1269 // validate <type> by itself (used as secondary key below)
1270 switch (type)
1271 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001272 case GL_UNSIGNED_BYTE:
1273 case GL_UNSIGNED_SHORT_5_6_5:
1274 case GL_UNSIGNED_SHORT_4_4_4_4:
1275 case GL_UNSIGNED_SHORT_5_5_5_1:
1276 case GL_UNSIGNED_SHORT:
1277 case GL_UNSIGNED_INT:
1278 case GL_UNSIGNED_INT_24_8_OES:
1279 case GL_HALF_FLOAT_OES:
1280 case GL_FLOAT:
1281 break;
1282 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001283 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001284 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001285 }
1286
1287 // validate <format> + <type> combinations
1288 // - invalid <format> -> sets INVALID_ENUM
1289 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1290 switch (format)
1291 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001292 case GL_ALPHA:
1293 case GL_LUMINANCE:
1294 case GL_LUMINANCE_ALPHA:
1295 switch (type)
1296 {
1297 case GL_UNSIGNED_BYTE:
1298 case GL_FLOAT:
1299 case GL_HALF_FLOAT_OES:
1300 break;
1301 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001302 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 return false;
1304 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001305 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001306 case GL_RED:
1307 case GL_RG:
1308 if (!context->getExtensions().textureRG)
1309 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001310 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001311 return false;
1312 }
1313 switch (type)
1314 {
1315 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001316 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001317 case GL_FLOAT:
1318 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001319 if (!context->getExtensions().textureFloat)
1320 {
1321 context->handleError(InvalidEnum());
1322 return false;
1323 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001324 break;
1325 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001326 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001327 return false;
1328 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001330 case GL_RGB:
1331 switch (type)
1332 {
1333 case GL_UNSIGNED_BYTE:
1334 case GL_UNSIGNED_SHORT_5_6_5:
1335 case GL_FLOAT:
1336 case GL_HALF_FLOAT_OES:
1337 break;
1338 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001339 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001340 return false;
1341 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001342 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001343 case GL_RGBA:
1344 switch (type)
1345 {
1346 case GL_UNSIGNED_BYTE:
1347 case GL_UNSIGNED_SHORT_4_4_4_4:
1348 case GL_UNSIGNED_SHORT_5_5_5_1:
1349 case GL_FLOAT:
1350 case GL_HALF_FLOAT_OES:
1351 break;
1352 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001354 return false;
1355 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001356 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001357 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001358 if (!context->getExtensions().textureFormatBGRA8888)
1359 {
1360 context->handleError(InvalidEnum());
1361 return false;
1362 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001363 switch (type)
1364 {
1365 case GL_UNSIGNED_BYTE:
1366 break;
1367 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 return false;
1370 }
1371 break;
1372 case GL_SRGB_EXT:
1373 case GL_SRGB_ALPHA_EXT:
1374 if (!context->getExtensions().sRGB)
1375 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001376 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001377 return false;
1378 }
1379 switch (type)
1380 {
1381 case GL_UNSIGNED_BYTE:
1382 break;
1383 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001384 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001385 return false;
1386 }
1387 break;
1388 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1389 // handled below
1390 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1391 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1392 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1393 break;
1394 case GL_DEPTH_COMPONENT:
1395 switch (type)
1396 {
1397 case GL_UNSIGNED_SHORT:
1398 case GL_UNSIGNED_INT:
1399 break;
1400 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001401 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001402 return false;
1403 }
1404 break;
1405 case GL_DEPTH_STENCIL_OES:
1406 switch (type)
1407 {
1408 case GL_UNSIGNED_INT_24_8_OES:
1409 break;
1410 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001411 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001412 return false;
1413 }
1414 break;
1415 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001416 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001417 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001418 }
1419
1420 switch (format)
1421 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001422 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1423 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1424 if (context->getExtensions().textureCompressionDXT1)
1425 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001426 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001427 return false;
1428 }
1429 else
1430 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001431 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001432 return false;
1433 }
1434 break;
1435 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1436 if (context->getExtensions().textureCompressionDXT3)
1437 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001438 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001439 return false;
1440 }
1441 else
1442 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001443 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001444 return false;
1445 }
1446 break;
1447 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1448 if (context->getExtensions().textureCompressionDXT5)
1449 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001450 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 return false;
1452 }
1453 else
1454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001455 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001456 return false;
1457 }
1458 break;
1459 case GL_ETC1_RGB8_OES:
1460 if (context->getExtensions().compressedETC1RGB8Texture)
1461 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001462 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001463 return false;
1464 }
1465 else
1466 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001467 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 return false;
1469 }
1470 break;
1471 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001472 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1473 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1474 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1475 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001476 if (context->getExtensions().lossyETCDecode)
1477 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001478 context->handleError(InvalidOperation()
1479 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001480 return false;
1481 }
1482 else
1483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001484 context->handleError(InvalidEnum()
1485 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001486 return false;
1487 }
1488 break;
1489 case GL_DEPTH_COMPONENT:
1490 case GL_DEPTH_STENCIL_OES:
1491 if (!context->getExtensions().depthTextures)
1492 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001493 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001494 return false;
1495 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001496 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001498 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001499 return false;
1500 }
1501 // OES_depth_texture supports loading depth data and multiple levels,
1502 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001503 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001504 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1506 return false;
1507 }
1508 if (level != 0)
1509 {
1510 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001511 return false;
1512 }
1513 break;
1514 default:
1515 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001516 }
1517
Geoff Lang6e898aa2017-06-02 11:17:26 -04001518 if (!isSubImage)
1519 {
1520 switch (internalformat)
1521 {
1522 case GL_RGBA32F:
1523 if (!context->getExtensions().colorBufferFloatRGBA)
1524 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001525 context->handleError(InvalidValue()
1526 << "Sized GL_RGBA32F internal format requires "
1527 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001528 return false;
1529 }
1530 if (type != GL_FLOAT)
1531 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001532 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001533 return false;
1534 }
1535 if (format != GL_RGBA)
1536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001537 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001538 return false;
1539 }
1540 break;
1541
1542 case GL_RGB32F:
1543 if (!context->getExtensions().colorBufferFloatRGB)
1544 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001545 context->handleError(InvalidValue()
1546 << "Sized GL_RGB32F internal format requires "
1547 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001548 return false;
1549 }
1550 if (type != GL_FLOAT)
1551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001552 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001553 return false;
1554 }
1555 if (format != GL_RGB)
1556 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001557 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001558 return false;
1559 }
1560 break;
1561
1562 default:
1563 break;
1564 }
1565 }
1566
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001567 if (type == GL_FLOAT)
1568 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001569 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001570 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001571 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001572 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001573 }
1574 }
1575 else if (type == GL_HALF_FLOAT_OES)
1576 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001577 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001578 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001579 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001580 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001581 }
1582 }
1583 }
1584
Geoff Langdbcced82017-06-06 15:55:54 -04001585 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001586 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001587 imageSize))
1588 {
1589 return false;
1590 }
1591
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001592 return true;
1593}
1594
He Yunchaoced53ae2016-11-29 15:00:51 +08001595bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001596 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001597 GLsizei levels,
1598 GLenum internalformat,
1599 GLsizei width,
1600 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001601{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001602 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1603 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001604 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001605 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001606 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001607 }
1608
1609 if (width < 1 || height < 1 || levels < 1)
1610 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001611 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001612 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001613 }
1614
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001615 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001616 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001617 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001618 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001619 }
1620
1621 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1622 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001623 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001624 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001625 }
1626
Geoff Langca271392017-04-05 12:30:00 -04001627 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001628 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001629 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001630 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001631 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001632 }
1633
Geoff Langaae65a42014-05-26 12:43:44 -04001634 const gl::Caps &caps = context->getCaps();
1635
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 switch (target)
1637 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001638 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001639 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1640 static_cast<GLuint>(height) > caps.max2DTextureSize)
1641 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001642 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001643 return false;
1644 }
1645 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001646 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001647 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1648 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1649 {
1650 context->handleError(InvalidValue());
1651 return false;
1652 }
1653 if (formatInfo.compressed)
1654 {
1655 context->handleError(InvalidEnum()
1656 << "Rectangle texture cannot have a compressed format.");
1657 return false;
1658 }
1659 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001660 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001661 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1662 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1663 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001664 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001665 return false;
1666 }
1667 break;
1668 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001669 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001670 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001671 }
1672
Geoff Langc0b9ef42014-07-02 10:02:37 -04001673 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001674 {
1675 if (!gl::isPow2(width) || !gl::isPow2(height))
1676 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001677 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001678 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001679 }
1680 }
1681
1682 switch (internalformat)
1683 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001684 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1685 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1686 if (!context->getExtensions().textureCompressionDXT1)
1687 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001688 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001689 return false;
1690 }
1691 break;
1692 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1693 if (!context->getExtensions().textureCompressionDXT3)
1694 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001695 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001696 return false;
1697 }
1698 break;
1699 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1700 if (!context->getExtensions().textureCompressionDXT5)
1701 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001702 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001703 return false;
1704 }
1705 break;
1706 case GL_ETC1_RGB8_OES:
1707 if (!context->getExtensions().compressedETC1RGB8Texture)
1708 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001709 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001710 return false;
1711 }
1712 break;
1713 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001714 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1715 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1716 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1717 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001718 if (!context->getExtensions().lossyETCDecode)
1719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001720 context->handleError(InvalidEnum()
1721 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001722 return false;
1723 }
1724 break;
1725 case GL_RGBA32F_EXT:
1726 case GL_RGB32F_EXT:
1727 case GL_ALPHA32F_EXT:
1728 case GL_LUMINANCE32F_EXT:
1729 case GL_LUMINANCE_ALPHA32F_EXT:
1730 if (!context->getExtensions().textureFloat)
1731 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001732 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001733 return false;
1734 }
1735 break;
1736 case GL_RGBA16F_EXT:
1737 case GL_RGB16F_EXT:
1738 case GL_ALPHA16F_EXT:
1739 case GL_LUMINANCE16F_EXT:
1740 case GL_LUMINANCE_ALPHA16F_EXT:
1741 if (!context->getExtensions().textureHalfFloat)
1742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001743 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001744 return false;
1745 }
1746 break;
1747 case GL_R8_EXT:
1748 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001749 if (!context->getExtensions().textureRG)
1750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001751 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001752 return false;
1753 }
1754 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001755 case GL_R16F_EXT:
1756 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001757 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001759 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001760 return false;
1761 }
1762 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001763 case GL_R32F_EXT:
1764 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001765 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001767 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001768 return false;
1769 }
1770 break;
1771 case GL_DEPTH_COMPONENT16:
1772 case GL_DEPTH_COMPONENT32_OES:
1773 case GL_DEPTH24_STENCIL8_OES:
1774 if (!context->getExtensions().depthTextures)
1775 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001776 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001777 return false;
1778 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001779 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001781 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001782 return false;
1783 }
1784 // ANGLE_depth_texture only supports 1-level textures
1785 if (levels != 1)
1786 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001787 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001788 return false;
1789 }
1790 break;
1791 default:
1792 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001793 }
1794
Geoff Lang691e58c2014-12-19 17:03:25 -05001795 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001796 if (!texture || texture->id() == 0)
1797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001798 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001799 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001800 }
1801
Geoff Lang69cce582015-09-17 13:20:36 -04001802 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001803 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001804 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001805 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001806 }
1807
1808 return true;
1809}
1810
He Yunchaoced53ae2016-11-29 15:00:51 +08001811bool ValidateDiscardFramebufferEXT(Context *context,
1812 GLenum target,
1813 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001814 const GLenum *attachments)
1815{
Jamie Madillc29968b2016-01-20 11:17:23 -05001816 if (!context->getExtensions().discardFramebuffer)
1817 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001818 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001819 return false;
1820 }
1821
Austin Kinross08332632015-05-05 13:35:47 -07001822 bool defaultFramebuffer = false;
1823
1824 switch (target)
1825 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001826 case GL_FRAMEBUFFER:
1827 defaultFramebuffer =
1828 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1829 break;
1830 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001831 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001832 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001833 }
1834
He Yunchaoced53ae2016-11-29 15:00:51 +08001835 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1836 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001837}
1838
Austin Kinrossbc781f32015-10-26 09:27:38 -07001839bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1840{
1841 if (!context->getExtensions().vertexArrayObject)
1842 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001843 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001844 return false;
1845 }
1846
1847 return ValidateBindVertexArrayBase(context, array);
1848}
1849
Jamie Madilld7576732017-08-26 18:49:50 -04001850bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001851{
1852 if (!context->getExtensions().vertexArrayObject)
1853 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001854 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001855 return false;
1856 }
1857
Olli Etuaho41997e72016-03-10 13:38:39 +02001858 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001859}
1860
Jamie Madilld7576732017-08-26 18:49:50 -04001861bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001862{
1863 if (!context->getExtensions().vertexArrayObject)
1864 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001865 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001866 return false;
1867 }
1868
Olli Etuaho41997e72016-03-10 13:38:39 +02001869 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870}
1871
Jamie Madilld7576732017-08-26 18:49:50 -04001872bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001873{
1874 if (!context->getExtensions().vertexArrayObject)
1875 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001876 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001877 return false;
1878 }
1879
1880 return true;
1881}
Geoff Langc5629752015-12-07 16:29:04 -05001882
1883bool ValidateProgramBinaryOES(Context *context,
1884 GLuint program,
1885 GLenum binaryFormat,
1886 const void *binary,
1887 GLint length)
1888{
1889 if (!context->getExtensions().getProgramBinary)
1890 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001891 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001892 return false;
1893 }
1894
1895 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1896}
1897
1898bool ValidateGetProgramBinaryOES(Context *context,
1899 GLuint program,
1900 GLsizei bufSize,
1901 GLsizei *length,
1902 GLenum *binaryFormat,
1903 void *binary)
1904{
1905 if (!context->getExtensions().getProgramBinary)
1906 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001907 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001908 return false;
1909 }
1910
1911 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1912}
Geoff Lange102fee2015-12-10 11:23:30 -05001913
Geoff Lang70d0f492015-12-10 17:45:46 -05001914static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1915{
1916 switch (source)
1917 {
1918 case GL_DEBUG_SOURCE_API:
1919 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1920 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1921 case GL_DEBUG_SOURCE_OTHER:
1922 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1923 return !mustBeThirdPartyOrApplication;
1924
1925 case GL_DEBUG_SOURCE_THIRD_PARTY:
1926 case GL_DEBUG_SOURCE_APPLICATION:
1927 return true;
1928
1929 default:
1930 return false;
1931 }
1932}
1933
1934static bool ValidDebugType(GLenum type)
1935{
1936 switch (type)
1937 {
1938 case GL_DEBUG_TYPE_ERROR:
1939 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1940 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1941 case GL_DEBUG_TYPE_PERFORMANCE:
1942 case GL_DEBUG_TYPE_PORTABILITY:
1943 case GL_DEBUG_TYPE_OTHER:
1944 case GL_DEBUG_TYPE_MARKER:
1945 case GL_DEBUG_TYPE_PUSH_GROUP:
1946 case GL_DEBUG_TYPE_POP_GROUP:
1947 return true;
1948
1949 default:
1950 return false;
1951 }
1952}
1953
1954static bool ValidDebugSeverity(GLenum severity)
1955{
1956 switch (severity)
1957 {
1958 case GL_DEBUG_SEVERITY_HIGH:
1959 case GL_DEBUG_SEVERITY_MEDIUM:
1960 case GL_DEBUG_SEVERITY_LOW:
1961 case GL_DEBUG_SEVERITY_NOTIFICATION:
1962 return true;
1963
1964 default:
1965 return false;
1966 }
1967}
1968
Geoff Lange102fee2015-12-10 11:23:30 -05001969bool ValidateDebugMessageControlKHR(Context *context,
1970 GLenum source,
1971 GLenum type,
1972 GLenum severity,
1973 GLsizei count,
1974 const GLuint *ids,
1975 GLboolean enabled)
1976{
1977 if (!context->getExtensions().debug)
1978 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001979 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001980 return false;
1981 }
1982
Geoff Lang70d0f492015-12-10 17:45:46 -05001983 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1984 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001986 return false;
1987 }
1988
1989 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1990 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001991 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001992 return false;
1993 }
1994
1995 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1996 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001997 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001998 return false;
1999 }
2000
2001 if (count > 0)
2002 {
2003 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2004 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002005 context->handleError(
2006 InvalidOperation()
2007 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002008 return false;
2009 }
2010
2011 if (severity != GL_DONT_CARE)
2012 {
Jamie Madill437fa652016-05-03 15:13:24 -04002013 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002014 InvalidOperation()
2015 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002016 return false;
2017 }
2018 }
2019
Geoff Lange102fee2015-12-10 11:23:30 -05002020 return true;
2021}
2022
2023bool ValidateDebugMessageInsertKHR(Context *context,
2024 GLenum source,
2025 GLenum type,
2026 GLuint id,
2027 GLenum severity,
2028 GLsizei length,
2029 const GLchar *buf)
2030{
2031 if (!context->getExtensions().debug)
2032 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002033 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002034 return false;
2035 }
2036
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002037 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002038 {
2039 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2040 // not generate an error.
2041 return false;
2042 }
2043
2044 if (!ValidDebugSeverity(severity))
2045 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002046 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002047 return false;
2048 }
2049
2050 if (!ValidDebugType(type))
2051 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002052 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002053 return false;
2054 }
2055
2056 if (!ValidDebugSource(source, true))
2057 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002058 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002059 return false;
2060 }
2061
2062 size_t messageLength = (length < 0) ? strlen(buf) : length;
2063 if (messageLength > context->getExtensions().maxDebugMessageLength)
2064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002065 context->handleError(InvalidValue()
2066 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002067 return false;
2068 }
2069
Geoff Lange102fee2015-12-10 11:23:30 -05002070 return true;
2071}
2072
2073bool ValidateDebugMessageCallbackKHR(Context *context,
2074 GLDEBUGPROCKHR callback,
2075 const void *userParam)
2076{
2077 if (!context->getExtensions().debug)
2078 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002079 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002080 return false;
2081 }
2082
Geoff Lange102fee2015-12-10 11:23:30 -05002083 return true;
2084}
2085
2086bool ValidateGetDebugMessageLogKHR(Context *context,
2087 GLuint count,
2088 GLsizei bufSize,
2089 GLenum *sources,
2090 GLenum *types,
2091 GLuint *ids,
2092 GLenum *severities,
2093 GLsizei *lengths,
2094 GLchar *messageLog)
2095{
2096 if (!context->getExtensions().debug)
2097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002098 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002099 return false;
2100 }
2101
Geoff Lang70d0f492015-12-10 17:45:46 -05002102 if (bufSize < 0 && messageLog != nullptr)
2103 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002104 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002105 return false;
2106 }
2107
Geoff Lange102fee2015-12-10 11:23:30 -05002108 return true;
2109}
2110
2111bool ValidatePushDebugGroupKHR(Context *context,
2112 GLenum source,
2113 GLuint id,
2114 GLsizei length,
2115 const GLchar *message)
2116{
2117 if (!context->getExtensions().debug)
2118 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002119 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002120 return false;
2121 }
2122
Geoff Lang70d0f492015-12-10 17:45:46 -05002123 if (!ValidDebugSource(source, true))
2124 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002125 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 return false;
2127 }
2128
2129 size_t messageLength = (length < 0) ? strlen(message) : length;
2130 if (messageLength > context->getExtensions().maxDebugMessageLength)
2131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002132 context->handleError(InvalidValue()
2133 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002134 return false;
2135 }
2136
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002137 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002138 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002140 context
2141 ->handleError(StackOverflow()
2142 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002143 return false;
2144 }
2145
Geoff Lange102fee2015-12-10 11:23:30 -05002146 return true;
2147}
2148
2149bool ValidatePopDebugGroupKHR(Context *context)
2150{
2151 if (!context->getExtensions().debug)
2152 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002153 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002154 return false;
2155 }
2156
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002157 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002158 if (currentStackSize <= 1)
2159 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002160 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002161 return false;
2162 }
2163
2164 return true;
2165}
2166
2167static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2168{
2169 switch (identifier)
2170 {
2171 case GL_BUFFER:
2172 if (context->getBuffer(name) == nullptr)
2173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002174 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002175 return false;
2176 }
2177 return true;
2178
2179 case GL_SHADER:
2180 if (context->getShader(name) == nullptr)
2181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002182 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002183 return false;
2184 }
2185 return true;
2186
2187 case GL_PROGRAM:
2188 if (context->getProgram(name) == nullptr)
2189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002190 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002191 return false;
2192 }
2193 return true;
2194
2195 case GL_VERTEX_ARRAY:
2196 if (context->getVertexArray(name) == nullptr)
2197 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002198 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 return false;
2200 }
2201 return true;
2202
2203 case GL_QUERY:
2204 if (context->getQuery(name) == nullptr)
2205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002206 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002207 return false;
2208 }
2209 return true;
2210
2211 case GL_TRANSFORM_FEEDBACK:
2212 if (context->getTransformFeedback(name) == nullptr)
2213 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002214 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002215 return false;
2216 }
2217 return true;
2218
2219 case GL_SAMPLER:
2220 if (context->getSampler(name) == nullptr)
2221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002222 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002223 return false;
2224 }
2225 return true;
2226
2227 case GL_TEXTURE:
2228 if (context->getTexture(name) == nullptr)
2229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002230 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 return false;
2232 }
2233 return true;
2234
2235 case GL_RENDERBUFFER:
2236 if (context->getRenderbuffer(name) == nullptr)
2237 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002238 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002239 return false;
2240 }
2241 return true;
2242
2243 case GL_FRAMEBUFFER:
2244 if (context->getFramebuffer(name) == nullptr)
2245 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002246 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002247 return false;
2248 }
2249 return true;
2250
2251 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002252 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002253 return false;
2254 }
Geoff Lange102fee2015-12-10 11:23:30 -05002255}
2256
Martin Radev9d901792016-07-15 15:58:58 +03002257static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2258{
2259 size_t labelLength = 0;
2260
2261 if (length < 0)
2262 {
2263 if (label != nullptr)
2264 {
2265 labelLength = strlen(label);
2266 }
2267 }
2268 else
2269 {
2270 labelLength = static_cast<size_t>(length);
2271 }
2272
2273 if (labelLength > context->getExtensions().maxLabelLength)
2274 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002275 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002276 return false;
2277 }
2278
2279 return true;
2280}
2281
Geoff Lange102fee2015-12-10 11:23:30 -05002282bool ValidateObjectLabelKHR(Context *context,
2283 GLenum identifier,
2284 GLuint name,
2285 GLsizei length,
2286 const GLchar *label)
2287{
2288 if (!context->getExtensions().debug)
2289 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002290 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002291 return false;
2292 }
2293
Geoff Lang70d0f492015-12-10 17:45:46 -05002294 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2295 {
2296 return false;
2297 }
2298
Martin Radev9d901792016-07-15 15:58:58 +03002299 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002300 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002301 return false;
2302 }
2303
Geoff Lange102fee2015-12-10 11:23:30 -05002304 return true;
2305}
2306
2307bool ValidateGetObjectLabelKHR(Context *context,
2308 GLenum identifier,
2309 GLuint name,
2310 GLsizei bufSize,
2311 GLsizei *length,
2312 GLchar *label)
2313{
2314 if (!context->getExtensions().debug)
2315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002317 return false;
2318 }
2319
Geoff Lang70d0f492015-12-10 17:45:46 -05002320 if (bufSize < 0)
2321 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002322 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002323 return false;
2324 }
2325
2326 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2327 {
2328 return false;
2329 }
2330
Martin Radev9d901792016-07-15 15:58:58 +03002331 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002332}
2333
2334static bool ValidateObjectPtrName(Context *context, const void *ptr)
2335{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002336 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002337 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002338 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002339 return false;
2340 }
2341
Geoff Lange102fee2015-12-10 11:23:30 -05002342 return true;
2343}
2344
2345bool ValidateObjectPtrLabelKHR(Context *context,
2346 const void *ptr,
2347 GLsizei length,
2348 const GLchar *label)
2349{
2350 if (!context->getExtensions().debug)
2351 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002352 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002353 return false;
2354 }
2355
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 if (!ValidateObjectPtrName(context, ptr))
2357 {
2358 return false;
2359 }
2360
Martin Radev9d901792016-07-15 15:58:58 +03002361 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002362 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002363 return false;
2364 }
2365
Geoff Lange102fee2015-12-10 11:23:30 -05002366 return true;
2367}
2368
2369bool ValidateGetObjectPtrLabelKHR(Context *context,
2370 const void *ptr,
2371 GLsizei bufSize,
2372 GLsizei *length,
2373 GLchar *label)
2374{
2375 if (!context->getExtensions().debug)
2376 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002377 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002378 return false;
2379 }
2380
Geoff Lang70d0f492015-12-10 17:45:46 -05002381 if (bufSize < 0)
2382 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002383 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002384 return false;
2385 }
2386
2387 if (!ValidateObjectPtrName(context, ptr))
2388 {
2389 return false;
2390 }
2391
Martin Radev9d901792016-07-15 15:58:58 +03002392 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002393}
2394
2395bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2396{
2397 if (!context->getExtensions().debug)
2398 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002400 return false;
2401 }
2402
Geoff Lang70d0f492015-12-10 17:45:46 -05002403 // TODO: represent this in Context::getQueryParameterInfo.
2404 switch (pname)
2405 {
2406 case GL_DEBUG_CALLBACK_FUNCTION:
2407 case GL_DEBUG_CALLBACK_USER_PARAM:
2408 break;
2409
2410 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002411 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002412 return false;
2413 }
2414
Geoff Lange102fee2015-12-10 11:23:30 -05002415 return true;
2416}
Jamie Madillc29968b2016-01-20 11:17:23 -05002417
2418bool ValidateBlitFramebufferANGLE(Context *context,
2419 GLint srcX0,
2420 GLint srcY0,
2421 GLint srcX1,
2422 GLint srcY1,
2423 GLint dstX0,
2424 GLint dstY0,
2425 GLint dstX1,
2426 GLint dstY1,
2427 GLbitfield mask,
2428 GLenum filter)
2429{
2430 if (!context->getExtensions().framebufferBlit)
2431 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002432 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002433 return false;
2434 }
2435
2436 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2437 {
2438 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002439 context->handleError(InvalidOperation() << "Scaling and flipping in "
2440 "BlitFramebufferANGLE not supported by this "
2441 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002442 return false;
2443 }
2444
2445 if (filter == GL_LINEAR)
2446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002447 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002448 return false;
2449 }
2450
Jamie Madill51f40ec2016-06-15 14:06:00 -04002451 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2452 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002453
2454 if (mask & GL_COLOR_BUFFER_BIT)
2455 {
2456 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2457 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2458
2459 if (readColorAttachment && drawColorAttachment)
2460 {
2461 if (!(readColorAttachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002462 readColorAttachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002463 readColorAttachment->type() != GL_RENDERBUFFER &&
2464 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002466 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002467 return false;
2468 }
2469
Geoff Langa15472a2015-08-11 11:48:03 -04002470 for (size_t drawbufferIdx = 0;
2471 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002472 {
Geoff Langa15472a2015-08-11 11:48:03 -04002473 const FramebufferAttachment *attachment =
2474 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2475 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002476 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002477 if (!(attachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002478 attachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002479 attachment->type() != GL_RENDERBUFFER &&
2480 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002482 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 return false;
2484 }
2485
2486 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002487 if (!Format::EquivalentForBlit(attachment->getFormat(),
2488 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002490 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 return false;
2492 }
2493 }
2494 }
2495
Jamie Madille98b1b52018-03-08 09:47:23 -05002496 GLint samples = 0;
2497 ANGLE_VALIDATION_TRY(readFramebuffer->getSamples(context, &samples));
2498 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002499 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2500 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2501 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002502 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002503 return false;
2504 }
2505 }
2506 }
2507
2508 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2509 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2510 for (size_t i = 0; i < 2; i++)
2511 {
2512 if (mask & masks[i])
2513 {
2514 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002515 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002516 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002517 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002518
2519 if (readBuffer && drawBuffer)
2520 {
2521 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2522 dstX0, dstY0, dstX1, dstY1))
2523 {
2524 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002525 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2526 "stencil blits are supported by "
2527 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002528 return false;
2529 }
2530
2531 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2532 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002533 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002534 return false;
2535 }
2536 }
2537 }
2538 }
2539
2540 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2541 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002542}
Jamie Madillc29968b2016-01-20 11:17:23 -05002543
Jamie Madill5b772312018-03-08 20:28:32 -05002544bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002545{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002546 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002547
2548 if (!ValidateFramebufferComplete(context, fbo, true))
Jamie Madillc29968b2016-01-20 11:17:23 -05002549 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002550 return false;
2551 }
2552
2553 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002555 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002556 return false;
2557 }
2558
Geoff Lang76e65652017-03-27 14:58:02 -04002559 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2560 {
2561 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2562 GL_SIGNED_NORMALIZED};
2563
Corentin Wallez59c41592017-07-11 13:19:54 -04002564 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002565 drawBufferIdx++)
2566 {
2567 if (!ValidateWebGLFramebufferAttachmentClearType(
2568 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2569 {
2570 return false;
2571 }
2572 }
2573 }
2574
Jamie Madillc29968b2016-01-20 11:17:23 -05002575 return true;
2576}
2577
Jamie Madill5b772312018-03-08 20:28:32 -05002578bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002579{
2580 if (!context->getExtensions().drawBuffers)
2581 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002582 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002583 return false;
2584 }
2585
2586 return ValidateDrawBuffersBase(context, n, bufs);
2587}
2588
Jamie Madill73a84962016-02-12 09:27:23 -05002589bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002590 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002591 GLint level,
2592 GLint internalformat,
2593 GLsizei width,
2594 GLsizei height,
2595 GLint border,
2596 GLenum format,
2597 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002598 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002599{
Martin Radev1be913c2016-07-11 17:59:16 +03002600 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002601 {
2602 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002603 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002604 }
2605
Martin Radev1be913c2016-07-11 17:59:16 +03002606 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002607 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002608 0, 0, width, height, 1, border, format, type, -1,
2609 pixels);
2610}
2611
2612bool ValidateTexImage2DRobust(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002613 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04002614 GLint level,
2615 GLint internalformat,
2616 GLsizei width,
2617 GLsizei height,
2618 GLint border,
2619 GLenum format,
2620 GLenum type,
2621 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002622 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002623{
2624 if (!ValidateRobustEntryPoint(context, bufSize))
2625 {
2626 return false;
2627 }
2628
2629 if (context->getClientMajorVersion() < 3)
2630 {
2631 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2632 0, 0, width, height, border, format, type, bufSize,
2633 pixels);
2634 }
2635
2636 ASSERT(context->getClientMajorVersion() >= 3);
2637 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2638 0, 0, width, height, 1, border, format, type, bufSize,
2639 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002640}
2641
2642bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002643 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002644 GLint level,
2645 GLint xoffset,
2646 GLint yoffset,
2647 GLsizei width,
2648 GLsizei height,
2649 GLenum format,
2650 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002651 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002652{
2653
Martin Radev1be913c2016-07-11 17:59:16 +03002654 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002655 {
2656 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002657 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002658 }
2659
Martin Radev1be913c2016-07-11 17:59:16 +03002660 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002661 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002662 yoffset, 0, width, height, 1, 0, format, type, -1,
2663 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002664}
2665
Geoff Langc52f6f12016-10-14 10:18:00 -04002666bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002667 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002668 GLint level,
2669 GLint xoffset,
2670 GLint yoffset,
2671 GLsizei width,
2672 GLsizei height,
2673 GLenum format,
2674 GLenum type,
2675 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002676 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002677{
2678 if (!ValidateRobustEntryPoint(context, bufSize))
2679 {
2680 return false;
2681 }
2682
2683 if (context->getClientMajorVersion() < 3)
2684 {
2685 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2686 yoffset, width, height, 0, format, type, bufSize,
2687 pixels);
2688 }
2689
2690 ASSERT(context->getClientMajorVersion() >= 3);
2691 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2692 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2693 pixels);
2694}
2695
Jamie Madill73a84962016-02-12 09:27:23 -05002696bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002697 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002698 GLint level,
2699 GLenum internalformat,
2700 GLsizei width,
2701 GLsizei height,
2702 GLint border,
2703 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002704 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002705{
Martin Radev1be913c2016-07-11 17:59:16 +03002706 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002707 {
2708 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002709 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002710 {
2711 return false;
2712 }
2713 }
2714 else
2715 {
Martin Radev1be913c2016-07-11 17:59:16 +03002716 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002717 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002718 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002719 data))
2720 {
2721 return false;
2722 }
2723 }
2724
Geoff Langca271392017-04-05 12:30:00 -04002725 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002726 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002727 if (blockSizeOrErr.isError())
2728 {
2729 context->handleError(blockSizeOrErr.getError());
2730 return false;
2731 }
2732
2733 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002734 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002735 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002736 return false;
2737 }
2738
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002739 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002740 {
2741 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2742 return false;
2743 }
2744
Jamie Madill73a84962016-02-12 09:27:23 -05002745 return true;
2746}
2747
Corentin Wallezb2931602017-04-11 15:58:57 -04002748bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002749 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002750 GLint level,
2751 GLenum internalformat,
2752 GLsizei width,
2753 GLsizei height,
2754 GLint border,
2755 GLsizei imageSize,
2756 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002757 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002758{
2759 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2760 {
2761 return false;
2762 }
2763
2764 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2765 border, imageSize, data);
2766}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002767
Corentin Wallezb2931602017-04-11 15:58:57 -04002768bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002769 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002770 GLint level,
2771 GLint xoffset,
2772 GLint yoffset,
2773 GLsizei width,
2774 GLsizei height,
2775 GLenum format,
2776 GLsizei imageSize,
2777 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002778 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002779{
2780 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2781 {
2782 return false;
2783 }
2784
2785 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2786 format, imageSize, data);
2787}
2788
Jamie Madill73a84962016-02-12 09:27:23 -05002789bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002790 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002791 GLint level,
2792 GLint xoffset,
2793 GLint yoffset,
2794 GLsizei width,
2795 GLsizei height,
2796 GLenum format,
2797 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002798 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002799{
Martin Radev1be913c2016-07-11 17:59:16 +03002800 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002801 {
2802 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002803 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002804 {
2805 return false;
2806 }
2807 }
2808 else
2809 {
Martin Radev1be913c2016-07-11 17:59:16 +03002810 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002811 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002812 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002813 data))
2814 {
2815 return false;
2816 }
2817 }
2818
Geoff Langca271392017-04-05 12:30:00 -04002819 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002820 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002821 if (blockSizeOrErr.isError())
2822 {
2823 context->handleError(blockSizeOrErr.getError());
2824 return false;
2825 }
2826
2827 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002828 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002829 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002830 return false;
2831 }
2832
2833 return true;
2834}
2835
Corentin Wallez336129f2017-10-17 15:55:40 -04002836bool ValidateGetBufferPointervOES(Context *context,
2837 BufferBinding target,
2838 GLenum pname,
2839 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002840{
Geoff Lang496c02d2016-10-20 11:38:11 -07002841 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002842}
2843
Corentin Wallez336129f2017-10-17 15:55:40 -04002844bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002845{
2846 if (!context->getExtensions().mapBuffer)
2847 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002848 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002849 return false;
2850 }
2851
Corentin Walleze4477002017-12-01 14:39:58 -05002852 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002853 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002854 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002855 return false;
2856 }
2857
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002858 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002859
2860 if (buffer == nullptr)
2861 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002862 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002863 return false;
2864 }
2865
2866 if (access != GL_WRITE_ONLY_OES)
2867 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002868 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002869 return false;
2870 }
2871
2872 if (buffer->isMapped())
2873 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002874 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002875 return false;
2876 }
2877
Geoff Lang79f71042017-08-14 16:43:43 -04002878 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002879}
2880
Corentin Wallez336129f2017-10-17 15:55:40 -04002881bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002882{
2883 if (!context->getExtensions().mapBuffer)
2884 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002885 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002886 return false;
2887 }
2888
2889 return ValidateUnmapBufferBase(context, target);
2890}
2891
2892bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002893 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002894 GLintptr offset,
2895 GLsizeiptr length,
2896 GLbitfield access)
2897{
2898 if (!context->getExtensions().mapBufferRange)
2899 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002900 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002901 return false;
2902 }
2903
2904 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2905}
2906
Corentin Wallez336129f2017-10-17 15:55:40 -04002907bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002908{
2909 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2910 ASSERT(buffer != nullptr);
2911
2912 // Check if this buffer is currently being used as a transform feedback output buffer
2913 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2914 if (transformFeedback != nullptr && transformFeedback->isActive())
2915 {
2916 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2917 {
2918 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2919 if (transformFeedbackBuffer.get() == buffer)
2920 {
2921 context->handleError(InvalidOperation()
2922 << "Buffer is currently bound for transform feedback.");
2923 return false;
2924 }
2925 }
2926 }
2927
James Darpiniane8a93c62018-01-04 18:02:24 -08002928 if (context->getExtensions().webglCompatibility &&
2929 buffer->isBoundForTransformFeedbackAndOtherUse())
2930 {
2931 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2932 return false;
2933 }
2934
Geoff Lang79f71042017-08-14 16:43:43 -04002935 return true;
2936}
2937
Olli Etuaho4f667482016-03-30 15:56:35 +03002938bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002939 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002940 GLintptr offset,
2941 GLsizeiptr length)
2942{
2943 if (!context->getExtensions().mapBufferRange)
2944 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002945 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002946 return false;
2947 }
2948
2949 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2950}
2951
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002952bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002953{
2954 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002955 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002956 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002957 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002958 return false;
2959 }
2960
Geoff Langf41a7152016-09-19 15:11:17 -04002961 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2962 !context->isTextureGenerated(texture))
2963 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002964 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002965 return false;
2966 }
2967
Ian Ewell54f87462016-03-10 13:47:21 -05002968 switch (target)
2969 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002970 case TextureType::_2D:
2971 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002972 break;
2973
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002974 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002975 if (!context->getExtensions().textureRectangle)
2976 {
2977 context->handleError(InvalidEnum()
2978 << "Context does not support GL_ANGLE_texture_rectangle");
2979 return false;
2980 }
2981 break;
2982
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002983 case TextureType::_3D:
2984 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002985 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002986 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002987 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002988 return false;
2989 }
2990 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002991
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002992 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04002993 if (context->getClientVersion() < Version(3, 1))
2994 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002995 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002996 return false;
2997 }
Geoff Lang3b573612016-10-31 14:08:10 -04002998 break;
2999
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003000 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003001 if (!context->getExtensions().eglImageExternal &&
3002 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003003 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003004 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003005 return false;
3006 }
3007 break;
3008 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003009 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003010 return false;
3011 }
3012
3013 return true;
3014}
3015
Geoff Langd8605522016-04-13 10:19:12 -04003016bool ValidateBindUniformLocationCHROMIUM(Context *context,
3017 GLuint program,
3018 GLint location,
3019 const GLchar *name)
3020{
3021 if (!context->getExtensions().bindUniformLocation)
3022 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003023 context->handleError(InvalidOperation()
3024 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003025 return false;
3026 }
3027
3028 Program *programObject = GetValidProgram(context, program);
3029 if (!programObject)
3030 {
3031 return false;
3032 }
3033
3034 if (location < 0)
3035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003036 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003037 return false;
3038 }
3039
3040 const Caps &caps = context->getCaps();
3041 if (static_cast<size_t>(location) >=
3042 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3043 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003044 context->handleError(InvalidValue() << "Location must be less than "
3045 "(MAX_VERTEX_UNIFORM_VECTORS + "
3046 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003047 return false;
3048 }
3049
Geoff Langfc32e8b2017-05-31 14:16:59 -04003050 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3051 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003052 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003053 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003054 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003055 return false;
3056 }
3057
Geoff Langd8605522016-04-13 10:19:12 -04003058 if (strncmp(name, "gl_", 3) == 0)
3059 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003060 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003061 return false;
3062 }
3063
3064 return true;
3065}
3066
Jamie Madille2e406c2016-06-02 13:04:10 -04003067bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003068{
3069 if (!context->getExtensions().framebufferMixedSamples)
3070 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003071 context->handleError(InvalidOperation()
3072 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003073 return false;
3074 }
3075 switch (components)
3076 {
3077 case GL_RGB:
3078 case GL_RGBA:
3079 case GL_ALPHA:
3080 case GL_NONE:
3081 break;
3082 default:
3083 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003084 InvalidEnum()
3085 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003086 return false;
3087 }
3088
3089 return true;
3090}
3091
Sami Väisänene45e53b2016-05-25 10:36:04 +03003092// CHROMIUM_path_rendering
3093
Jamie Madill007530e2017-12-28 14:27:04 -05003094bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003095{
Jamie Madill007530e2017-12-28 14:27:04 -05003096 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003097 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003098 return false;
3099 }
Jamie Madill007530e2017-12-28 14:27:04 -05003100
Sami Väisänene45e53b2016-05-25 10:36:04 +03003101 if (matrix == nullptr)
3102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003103 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003104 return false;
3105 }
Jamie Madill007530e2017-12-28 14:27:04 -05003106
Sami Väisänene45e53b2016-05-25 10:36:04 +03003107 return true;
3108}
3109
Jamie Madill007530e2017-12-28 14:27:04 -05003110bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111{
Jamie Madill007530e2017-12-28 14:27:04 -05003112 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003113}
3114
Jamie Madill007530e2017-12-28 14:27:04 -05003115bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003116{
3117 if (!context->getExtensions().pathRendering)
3118 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003119 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003120 return false;
3121 }
3122
3123 // range = 0 is undefined in NV_path_rendering.
3124 // we add stricter semantic check here and require a non zero positive range.
3125 if (range <= 0)
3126 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003127 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003128 return false;
3129 }
3130
3131 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3132 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003133 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003134 return false;
3135 }
3136
3137 return true;
3138}
3139
Jamie Madill007530e2017-12-28 14:27:04 -05003140bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003141{
3142 if (!context->getExtensions().pathRendering)
3143 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003144 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003145 return false;
3146 }
3147
3148 // range = 0 is undefined in NV_path_rendering.
3149 // we add stricter semantic check here and require a non zero positive range.
3150 if (range <= 0)
3151 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003152 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003153 return false;
3154 }
3155
3156 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3157 checkedRange += range;
3158
3159 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3160 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003161 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003162 return false;
3163 }
3164 return true;
3165}
3166
Jamie Madill007530e2017-12-28 14:27:04 -05003167bool ValidatePathCommandsCHROMIUM(Context *context,
3168 GLuint path,
3169 GLsizei numCommands,
3170 const GLubyte *commands,
3171 GLsizei numCoords,
3172 GLenum coordType,
3173 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003174{
3175 if (!context->getExtensions().pathRendering)
3176 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003177 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003178 return false;
3179 }
3180 if (!context->hasPath(path))
3181 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003182 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003183 return false;
3184 }
3185
3186 if (numCommands < 0)
3187 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003188 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003189 return false;
3190 }
3191 else if (numCommands > 0)
3192 {
3193 if (!commands)
3194 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003195 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003196 return false;
3197 }
3198 }
3199
3200 if (numCoords < 0)
3201 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003202 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003203 return false;
3204 }
3205 else if (numCoords > 0)
3206 {
3207 if (!coords)
3208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003209 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003210 return false;
3211 }
3212 }
3213
3214 std::uint32_t coordTypeSize = 0;
3215 switch (coordType)
3216 {
3217 case GL_BYTE:
3218 coordTypeSize = sizeof(GLbyte);
3219 break;
3220
3221 case GL_UNSIGNED_BYTE:
3222 coordTypeSize = sizeof(GLubyte);
3223 break;
3224
3225 case GL_SHORT:
3226 coordTypeSize = sizeof(GLshort);
3227 break;
3228
3229 case GL_UNSIGNED_SHORT:
3230 coordTypeSize = sizeof(GLushort);
3231 break;
3232
3233 case GL_FLOAT:
3234 coordTypeSize = sizeof(GLfloat);
3235 break;
3236
3237 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003238 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003239 return false;
3240 }
3241
3242 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3243 checkedSize += (coordTypeSize * numCoords);
3244 if (!checkedSize.IsValid())
3245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003246 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003247 return false;
3248 }
3249
3250 // early return skips command data validation when it doesn't exist.
3251 if (!commands)
3252 return true;
3253
3254 GLsizei expectedNumCoords = 0;
3255 for (GLsizei i = 0; i < numCommands; ++i)
3256 {
3257 switch (commands[i])
3258 {
3259 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3260 break;
3261 case GL_MOVE_TO_CHROMIUM:
3262 case GL_LINE_TO_CHROMIUM:
3263 expectedNumCoords += 2;
3264 break;
3265 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3266 expectedNumCoords += 4;
3267 break;
3268 case GL_CUBIC_CURVE_TO_CHROMIUM:
3269 expectedNumCoords += 6;
3270 break;
3271 case GL_CONIC_CURVE_TO_CHROMIUM:
3272 expectedNumCoords += 5;
3273 break;
3274 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003275 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003276 return false;
3277 }
3278 }
3279 if (expectedNumCoords != numCoords)
3280 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003281 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003282 return false;
3283 }
3284
3285 return true;
3286}
3287
Jamie Madill007530e2017-12-28 14:27:04 -05003288bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003289{
3290 if (!context->getExtensions().pathRendering)
3291 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003292 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003293 return false;
3294 }
3295 if (!context->hasPath(path))
3296 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003297 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003298 return false;
3299 }
3300
3301 switch (pname)
3302 {
3303 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3304 if (value < 0.0f)
3305 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003306 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003307 return false;
3308 }
3309 break;
3310 case GL_PATH_END_CAPS_CHROMIUM:
3311 switch (static_cast<GLenum>(value))
3312 {
3313 case GL_FLAT_CHROMIUM:
3314 case GL_SQUARE_CHROMIUM:
3315 case GL_ROUND_CHROMIUM:
3316 break;
3317 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003318 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003319 return false;
3320 }
3321 break;
3322 case GL_PATH_JOIN_STYLE_CHROMIUM:
3323 switch (static_cast<GLenum>(value))
3324 {
3325 case GL_MITER_REVERT_CHROMIUM:
3326 case GL_BEVEL_CHROMIUM:
3327 case GL_ROUND_CHROMIUM:
3328 break;
3329 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003330 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003331 return false;
3332 }
Nico Weber41b072b2018-02-09 10:01:32 -05003333 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003334 case GL_PATH_MITER_LIMIT_CHROMIUM:
3335 if (value < 0.0f)
3336 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003337 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003338 return false;
3339 }
3340 break;
3341
3342 case GL_PATH_STROKE_BOUND_CHROMIUM:
3343 // no errors, only clamping.
3344 break;
3345
3346 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003347 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003348 return false;
3349 }
3350 return true;
3351}
3352
Jamie Madill007530e2017-12-28 14:27:04 -05003353bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3354{
3355 // TODO(jmadill): Use proper clamping cast.
3356 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3357}
3358
3359bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003360{
3361 if (!context->getExtensions().pathRendering)
3362 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003363 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003364 return false;
3365 }
3366
3367 if (!context->hasPath(path))
3368 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003369 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003370 return false;
3371 }
3372 if (!value)
3373 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003374 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003375 return false;
3376 }
3377
3378 switch (pname)
3379 {
3380 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3381 case GL_PATH_END_CAPS_CHROMIUM:
3382 case GL_PATH_JOIN_STYLE_CHROMIUM:
3383 case GL_PATH_MITER_LIMIT_CHROMIUM:
3384 case GL_PATH_STROKE_BOUND_CHROMIUM:
3385 break;
3386
3387 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003388 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003389 return false;
3390 }
3391
3392 return true;
3393}
3394
Jamie Madill007530e2017-12-28 14:27:04 -05003395bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3396{
3397 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3398 reinterpret_cast<GLfloat *>(value));
3399}
3400
3401bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003402{
3403 if (!context->getExtensions().pathRendering)
3404 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003405 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003406 return false;
3407 }
3408
3409 switch (func)
3410 {
3411 case GL_NEVER:
3412 case GL_ALWAYS:
3413 case GL_LESS:
3414 case GL_LEQUAL:
3415 case GL_EQUAL:
3416 case GL_GEQUAL:
3417 case GL_GREATER:
3418 case GL_NOTEQUAL:
3419 break;
3420 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003421 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003422 return false;
3423 }
3424
3425 return true;
3426}
3427
3428// Note that the spec specifies that for the path drawing commands
3429// if the path object is not an existing path object the command
3430// does nothing and no error is generated.
3431// However if the path object exists but has not been specified any
3432// commands then an error is generated.
3433
Jamie Madill007530e2017-12-28 14:27:04 -05003434bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003435{
3436 if (!context->getExtensions().pathRendering)
3437 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003438 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003439 return false;
3440 }
3441 if (context->hasPath(path) && !context->hasPathData(path))
3442 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003444 return false;
3445 }
3446
3447 switch (fillMode)
3448 {
3449 case GL_COUNT_UP_CHROMIUM:
3450 case GL_COUNT_DOWN_CHROMIUM:
3451 break;
3452 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003453 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003454 return false;
3455 }
3456
3457 if (!isPow2(mask + 1))
3458 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003459 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003460 return false;
3461 }
3462
3463 return true;
3464}
3465
Jamie Madill007530e2017-12-28 14:27:04 -05003466bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003467{
3468 if (!context->getExtensions().pathRendering)
3469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003470 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471 return false;
3472 }
3473 if (context->hasPath(path) && !context->hasPathData(path))
3474 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003475 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003476 return false;
3477 }
3478
3479 return true;
3480}
3481
Jamie Madill007530e2017-12-28 14:27:04 -05003482bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003483{
3484 if (!context->getExtensions().pathRendering)
3485 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003486 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003487 return false;
3488 }
3489 if (context->hasPath(path) && !context->hasPathData(path))
3490 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003491 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003492 return false;
3493 }
3494
3495 switch (coverMode)
3496 {
3497 case GL_CONVEX_HULL_CHROMIUM:
3498 case GL_BOUNDING_BOX_CHROMIUM:
3499 break;
3500 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003501 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003502 return false;
3503 }
3504 return true;
3505}
3506
Jamie Madill007530e2017-12-28 14:27:04 -05003507bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3508 GLuint path,
3509 GLenum fillMode,
3510 GLuint mask,
3511 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003512{
Jamie Madill007530e2017-12-28 14:27:04 -05003513 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3514 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003515}
3516
Jamie Madill007530e2017-12-28 14:27:04 -05003517bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3518 GLuint path,
3519 GLint reference,
3520 GLuint mask,
3521 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003522{
Jamie Madill007530e2017-12-28 14:27:04 -05003523 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3524 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003525}
3526
Jamie Madill007530e2017-12-28 14:27:04 -05003527bool ValidateIsPathCHROMIUM(Context *context)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003528{
3529 if (!context->getExtensions().pathRendering)
3530 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003531 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003532 return false;
3533 }
3534 return true;
3535}
3536
Jamie Madill007530e2017-12-28 14:27:04 -05003537bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3538 GLsizei numPaths,
3539 GLenum pathNameType,
3540 const void *paths,
3541 GLuint pathBase,
3542 GLenum coverMode,
3543 GLenum transformType,
3544 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003545{
3546 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3547 transformType, transformValues))
3548 return false;
3549
3550 switch (coverMode)
3551 {
3552 case GL_CONVEX_HULL_CHROMIUM:
3553 case GL_BOUNDING_BOX_CHROMIUM:
3554 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3555 break;
3556 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003557 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003558 return false;
3559 }
3560
3561 return true;
3562}
3563
Jamie Madill007530e2017-12-28 14:27:04 -05003564bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3565 GLsizei numPaths,
3566 GLenum pathNameType,
3567 const void *paths,
3568 GLuint pathBase,
3569 GLenum coverMode,
3570 GLenum transformType,
3571 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003572{
3573 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3574 transformType, transformValues))
3575 return false;
3576
3577 switch (coverMode)
3578 {
3579 case GL_CONVEX_HULL_CHROMIUM:
3580 case GL_BOUNDING_BOX_CHROMIUM:
3581 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3582 break;
3583 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003584 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003585 return false;
3586 }
3587
3588 return true;
3589}
3590
Jamie Madill007530e2017-12-28 14:27:04 -05003591bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3592 GLsizei numPaths,
3593 GLenum pathNameType,
3594 const void *paths,
3595 GLuint pathBase,
3596 GLenum fillMode,
3597 GLuint mask,
3598 GLenum transformType,
3599 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003600{
3601
3602 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3603 transformType, transformValues))
3604 return false;
3605
3606 switch (fillMode)
3607 {
3608 case GL_COUNT_UP_CHROMIUM:
3609 case GL_COUNT_DOWN_CHROMIUM:
3610 break;
3611 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003612 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003613 return false;
3614 }
3615 if (!isPow2(mask + 1))
3616 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003617 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003618 return false;
3619 }
3620 return true;
3621}
3622
Jamie Madill007530e2017-12-28 14:27:04 -05003623bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3624 GLsizei numPaths,
3625 GLenum pathNameType,
3626 const void *paths,
3627 GLuint pathBase,
3628 GLint reference,
3629 GLuint mask,
3630 GLenum transformType,
3631 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003632{
3633 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3634 transformType, transformValues))
3635 return false;
3636
3637 // no more validation here.
3638
3639 return true;
3640}
3641
Jamie Madill007530e2017-12-28 14:27:04 -05003642bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3643 GLsizei numPaths,
3644 GLenum pathNameType,
3645 const void *paths,
3646 GLuint pathBase,
3647 GLenum fillMode,
3648 GLuint mask,
3649 GLenum coverMode,
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 switch (coverMode)
3658 {
3659 case GL_CONVEX_HULL_CHROMIUM:
3660 case GL_BOUNDING_BOX_CHROMIUM:
3661 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3662 break;
3663 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003664 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003665 return false;
3666 }
3667
3668 switch (fillMode)
3669 {
3670 case GL_COUNT_UP_CHROMIUM:
3671 case GL_COUNT_DOWN_CHROMIUM:
3672 break;
3673 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003674 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003675 return false;
3676 }
3677 if (!isPow2(mask + 1))
3678 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003679 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003680 return false;
3681 }
3682
3683 return true;
3684}
3685
Jamie Madill007530e2017-12-28 14:27:04 -05003686bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3687 GLsizei numPaths,
3688 GLenum pathNameType,
3689 const void *paths,
3690 GLuint pathBase,
3691 GLint reference,
3692 GLuint mask,
3693 GLenum coverMode,
3694 GLenum transformType,
3695 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003696{
3697 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3698 transformType, transformValues))
3699 return false;
3700
3701 switch (coverMode)
3702 {
3703 case GL_CONVEX_HULL_CHROMIUM:
3704 case GL_BOUNDING_BOX_CHROMIUM:
3705 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3706 break;
3707 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003708 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003709 return false;
3710 }
3711
3712 return true;
3713}
3714
Jamie Madill007530e2017-12-28 14:27:04 -05003715bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3716 GLuint program,
3717 GLint location,
3718 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003719{
3720 if (!context->getExtensions().pathRendering)
3721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003722 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003723 return false;
3724 }
3725
3726 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3727 if (location >= MaxLocation)
3728 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003729 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003730 return false;
3731 }
3732
3733 const auto *programObject = context->getProgram(program);
3734 if (!programObject)
3735 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003736 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003737 return false;
3738 }
3739
3740 if (!name)
3741 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003742 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003743 return false;
3744 }
3745
3746 if (angle::BeginsWith(name, "gl_"))
3747 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003748 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003749 return false;
3750 }
3751
3752 return true;
3753}
3754
Jamie Madill007530e2017-12-28 14:27:04 -05003755bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3756 GLuint program,
3757 GLint location,
3758 GLenum genMode,
3759 GLint components,
3760 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003761{
3762 if (!context->getExtensions().pathRendering)
3763 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003764 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003765 return false;
3766 }
3767
3768 const auto *programObject = context->getProgram(program);
3769 if (!programObject || programObject->isFlaggedForDeletion())
3770 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003771 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003772 return false;
3773 }
3774
3775 if (!programObject->isLinked())
3776 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003777 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003778 return false;
3779 }
3780
3781 switch (genMode)
3782 {
3783 case GL_NONE:
3784 if (components != 0)
3785 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003786 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003787 return false;
3788 }
3789 break;
3790
3791 case GL_OBJECT_LINEAR_CHROMIUM:
3792 case GL_EYE_LINEAR_CHROMIUM:
3793 case GL_CONSTANT_CHROMIUM:
3794 if (components < 1 || components > 4)
3795 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003796 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003797 return false;
3798 }
3799 if (!coeffs)
3800 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003801 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003802 return false;
3803 }
3804 break;
3805
3806 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003807 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003808 return false;
3809 }
3810
3811 // If the location is -1 then the command is silently ignored
3812 // and no further validation is needed.
3813 if (location == -1)
3814 return true;
3815
Jamie Madillbd044ed2017-06-05 12:59:21 -04003816 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003817
3818 if (!binding.valid)
3819 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003820 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003821 return false;
3822 }
3823
3824 if (binding.type != GL_NONE)
3825 {
3826 GLint expectedComponents = 0;
3827 switch (binding.type)
3828 {
3829 case GL_FLOAT:
3830 expectedComponents = 1;
3831 break;
3832 case GL_FLOAT_VEC2:
3833 expectedComponents = 2;
3834 break;
3835 case GL_FLOAT_VEC3:
3836 expectedComponents = 3;
3837 break;
3838 case GL_FLOAT_VEC4:
3839 expectedComponents = 4;
3840 break;
3841 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003842 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003843 InvalidOperation()
3844 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003845 return false;
3846 }
3847 if (expectedComponents != components && genMode != GL_NONE)
3848 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003849 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003850 return false;
3851 }
3852 }
3853 return true;
3854}
3855
Geoff Lang97073d12016-04-20 10:42:34 -07003856bool ValidateCopyTextureCHROMIUM(Context *context,
3857 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003858 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003859 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003860 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003861 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003862 GLint internalFormat,
3863 GLenum destType,
3864 GLboolean unpackFlipY,
3865 GLboolean unpackPremultiplyAlpha,
3866 GLboolean unpackUnmultiplyAlpha)
3867{
3868 if (!context->getExtensions().copyTexture)
3869 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003870 context->handleError(InvalidOperation()
3871 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003872 return false;
3873 }
3874
Geoff Lang4f0e0032017-05-01 16:04:35 -04003875 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003876 if (source == nullptr)
3877 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003878 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003879 return false;
3880 }
3881
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003882 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003883 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003884 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003885 return false;
3886 }
3887
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003888 TextureType sourceType = source->getType();
3889 ASSERT(sourceType != TextureType::CubeMap);
3890 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003891
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003892 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003893 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003894 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003895 return false;
3896 }
3897
Geoff Lang4f0e0032017-05-01 16:04:35 -04003898 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3899 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3900 if (sourceWidth == 0 || sourceHeight == 0)
3901 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003902 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003903 return false;
3904 }
3905
3906 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3907 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003908 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003909 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003910 return false;
3911 }
3912
Geoff Lang63458a32017-10-30 15:16:53 -04003913 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3914 {
3915 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3916 return false;
3917 }
3918
Geoff Lang4f0e0032017-05-01 16:04:35 -04003919 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003920 if (dest == nullptr)
3921 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003922 context->handleError(InvalidValue()
3923 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003924 return false;
3925 }
3926
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003927 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003928 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003929 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003930 return false;
3931 }
3932
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003933 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003934 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003935 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003936 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003937 return false;
3938 }
3939
Geoff Lang97073d12016-04-20 10:42:34 -07003940 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3941 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003942 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003943 return false;
3944 }
3945
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003946 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003947 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003948 context->handleError(
3949 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003950 return false;
3951 }
3952
Geoff Lang97073d12016-04-20 10:42:34 -07003953 if (dest->getImmutableFormat())
3954 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003955 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003956 return false;
3957 }
3958
3959 return true;
3960}
3961
3962bool ValidateCopySubTextureCHROMIUM(Context *context,
3963 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003964 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003965 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003966 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003967 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003968 GLint xoffset,
3969 GLint yoffset,
3970 GLint x,
3971 GLint y,
3972 GLsizei width,
3973 GLsizei height,
3974 GLboolean unpackFlipY,
3975 GLboolean unpackPremultiplyAlpha,
3976 GLboolean unpackUnmultiplyAlpha)
3977{
3978 if (!context->getExtensions().copyTexture)
3979 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003980 context->handleError(InvalidOperation()
3981 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003982 return false;
3983 }
3984
Geoff Lang4f0e0032017-05-01 16:04:35 -04003985 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003986 if (source == nullptr)
3987 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003988 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003989 return false;
3990 }
3991
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003992 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003993 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003994 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003995 return false;
3996 }
3997
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003998 TextureType sourceType = source->getType();
3999 ASSERT(sourceType != TextureType::CubeMap);
4000 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004001
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004002 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004003 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004004 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004005 return false;
4006 }
4007
4008 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4009 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004011 context->handleError(InvalidValue()
4012 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004013 return false;
4014 }
4015
4016 if (x < 0 || y < 0)
4017 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004018 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004019 return false;
4020 }
4021
4022 if (width < 0 || height < 0)
4023 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004024 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004025 return false;
4026 }
4027
Geoff Lang4f0e0032017-05-01 16:04:35 -04004028 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4029 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004030 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004031 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004032 return false;
4033 }
4034
Geoff Lang4f0e0032017-05-01 16:04:35 -04004035 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4036 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004037 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004038 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004039 return false;
4040 }
4041
Geoff Lang63458a32017-10-30 15:16:53 -04004042 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4043 {
4044 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4045 return false;
4046 }
4047
Geoff Lang4f0e0032017-05-01 16:04:35 -04004048 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004049 if (dest == nullptr)
4050 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004051 context->handleError(InvalidValue()
4052 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004053 return false;
4054 }
4055
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004056 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004058 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004059 return false;
4060 }
4061
Brandon Jones28783792018-03-05 09:37:32 -08004062 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4063 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004065 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004066 return false;
4067 }
4068
Geoff Lang4f0e0032017-05-01 16:04:35 -04004069 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4070 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004071 context
4072 ->handleError(InvalidOperation()
4073 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004074 return false;
4075 }
4076
4077 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4078 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004079 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004080 context->handleError(InvalidOperation()
4081 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004082 return false;
4083 }
4084
4085 if (xoffset < 0 || yoffset < 0)
4086 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004087 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004088 return false;
4089 }
4090
Geoff Lang4f0e0032017-05-01 16:04:35 -04004091 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4092 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004093 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004094 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004095 return false;
4096 }
4097
4098 return true;
4099}
4100
Geoff Lang47110bf2016-04-20 11:13:22 -07004101bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4102{
4103 if (!context->getExtensions().copyCompressedTexture)
4104 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004105 context->handleError(InvalidOperation()
4106 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004107 return false;
4108 }
4109
4110 const gl::Texture *source = context->getTexture(sourceId);
4111 if (source == nullptr)
4112 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004113 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004114 return false;
4115 }
4116
Corentin Wallez99d492c2018-02-27 15:17:10 -05004117 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004118 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004119 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004120 return false;
4121 }
4122
Corentin Wallez99d492c2018-02-27 15:17:10 -05004123 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4124 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004125 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004126 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004127 return false;
4128 }
4129
Corentin Wallez99d492c2018-02-27 15:17:10 -05004130 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004131 if (!sourceFormat.info->compressed)
4132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004133 context->handleError(InvalidOperation()
4134 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004135 return false;
4136 }
4137
4138 const gl::Texture *dest = context->getTexture(destId);
4139 if (dest == nullptr)
4140 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004141 context->handleError(InvalidValue()
4142 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004143 return false;
4144 }
4145
Corentin Wallez99d492c2018-02-27 15:17:10 -05004146 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004148 context->handleError(InvalidValue()
4149 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004150 return false;
4151 }
4152
4153 if (dest->getImmutableFormat())
4154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004155 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004156 return false;
4157 }
4158
4159 return true;
4160}
4161
Martin Radev4c4c8e72016-08-04 12:25:34 +03004162bool ValidateCreateShader(Context *context, GLenum type)
4163{
4164 switch (type)
4165 {
4166 case GL_VERTEX_SHADER:
4167 case GL_FRAGMENT_SHADER:
4168 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004169
Martin Radev4c4c8e72016-08-04 12:25:34 +03004170 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004171 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004172 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004173 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004174 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004175 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004176 break;
4177
Jiawei Shao89be29a2017-11-06 14:36:45 +08004178 case GL_GEOMETRY_SHADER_EXT:
4179 if (!context->getExtensions().geometryShader)
4180 {
4181 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4182 return false;
4183 }
4184 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004185 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004186 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004187 return false;
4188 }
Jamie Madill29639852016-09-02 15:00:09 -04004189
4190 return true;
4191}
4192
Jamie Madill5b772312018-03-08 20:28:32 -05004193bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004194 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004195 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004196 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004197 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004198{
4199 if (size < 0)
4200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004201 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004202 return false;
4203 }
4204
4205 switch (usage)
4206 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004207 case BufferUsage::StreamDraw:
4208 case BufferUsage::StaticDraw:
4209 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004210 break;
4211
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004212 case BufferUsage::StreamRead:
4213 case BufferUsage::StaticRead:
4214 case BufferUsage::DynamicRead:
4215 case BufferUsage::StreamCopy:
4216 case BufferUsage::StaticCopy:
4217 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004218 if (context->getClientMajorVersion() < 3)
4219 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004220 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004221 return false;
4222 }
4223 break;
4224
4225 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004226 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004227 return false;
4228 }
4229
Corentin Walleze4477002017-12-01 14:39:58 -05004230 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004231 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004232 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004233 return false;
4234 }
4235
4236 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4237
4238 if (!buffer)
4239 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004240 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004241 return false;
4242 }
4243
James Darpiniane8a93c62018-01-04 18:02:24 -08004244 if (context->getExtensions().webglCompatibility &&
4245 buffer->isBoundForTransformFeedbackAndOtherUse())
4246 {
4247 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4248 return false;
4249 }
4250
Jamie Madill29639852016-09-02 15:00:09 -04004251 return true;
4252}
4253
Jamie Madill5b772312018-03-08 20:28:32 -05004254bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004255 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004256 GLintptr offset,
4257 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004258 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004259{
Brandon Jones6cad5662017-06-14 13:25:13 -07004260 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004261 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004262 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4263 return false;
4264 }
4265
4266 if (offset < 0)
4267 {
4268 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004269 return false;
4270 }
4271
Corentin Walleze4477002017-12-01 14:39:58 -05004272 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004273 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004274 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004275 return false;
4276 }
4277
4278 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4279
4280 if (!buffer)
4281 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004282 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004283 return false;
4284 }
4285
4286 if (buffer->isMapped())
4287 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004288 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004289 return false;
4290 }
4291
James Darpiniane8a93c62018-01-04 18:02:24 -08004292 if (context->getExtensions().webglCompatibility &&
4293 buffer->isBoundForTransformFeedbackAndOtherUse())
4294 {
4295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4296 return false;
4297 }
4298
Jamie Madill29639852016-09-02 15:00:09 -04004299 // Check for possible overflow of size + offset
4300 angle::CheckedNumeric<size_t> checkedSize(size);
4301 checkedSize += offset;
4302 if (!checkedSize.IsValid())
4303 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004304 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004305 return false;
4306 }
4307
4308 if (size + offset > buffer->getSize())
4309 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004310 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004311 return false;
4312 }
4313
Martin Radev4c4c8e72016-08-04 12:25:34 +03004314 return true;
4315}
4316
Geoff Lang111a99e2017-10-17 10:58:41 -04004317bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004318{
Geoff Langc339c4e2016-11-29 10:37:36 -05004319 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004320 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004321 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004322 return false;
4323 }
4324
Geoff Lang111a99e2017-10-17 10:58:41 -04004325 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004326 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004327 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004328 return false;
4329 }
4330
4331 return true;
4332}
4333
Jamie Madill5b772312018-03-08 20:28:32 -05004334bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004335{
4336 if (texture < GL_TEXTURE0 ||
4337 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4338 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004339 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004340 return false;
4341 }
4342
4343 return true;
4344}
4345
Jamie Madill5b772312018-03-08 20:28:32 -05004346bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004347{
4348 Program *programObject = GetValidProgram(context, program);
4349 if (!programObject)
4350 {
4351 return false;
4352 }
4353
4354 Shader *shaderObject = GetValidShader(context, shader);
4355 if (!shaderObject)
4356 {
4357 return false;
4358 }
4359
4360 switch (shaderObject->getType())
4361 {
4362 case GL_VERTEX_SHADER:
4363 {
4364 if (programObject->getAttachedVertexShader())
4365 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004366 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004367 return false;
4368 }
4369 break;
4370 }
4371 case GL_FRAGMENT_SHADER:
4372 {
4373 if (programObject->getAttachedFragmentShader())
4374 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004375 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004376 return false;
4377 }
4378 break;
4379 }
4380 case GL_COMPUTE_SHADER:
4381 {
4382 if (programObject->getAttachedComputeShader())
4383 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004384 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004385 return false;
4386 }
4387 break;
4388 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004389 case GL_GEOMETRY_SHADER_EXT:
4390 {
4391 if (programObject->getAttachedGeometryShader())
4392 {
4393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4394 return false;
4395 }
4396 break;
4397 }
Jamie Madillef300b12016-10-07 15:12:09 -04004398 default:
4399 UNREACHABLE();
4400 break;
4401 }
4402
4403 return true;
4404}
4405
Jamie Madill5b772312018-03-08 20:28:32 -05004406bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004407{
4408 if (index >= MAX_VERTEX_ATTRIBS)
4409 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004410 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004411 return false;
4412 }
4413
4414 if (strncmp(name, "gl_", 3) == 0)
4415 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004416 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004417 return false;
4418 }
4419
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004420 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004421 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004422 const size_t length = strlen(name);
4423
4424 if (!IsValidESSLString(name, length))
4425 {
4426 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4427 // for shader-related entry points
4428 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4429 return false;
4430 }
4431
4432 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4433 {
4434 return false;
4435 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004436 }
4437
Jamie Madill01a80ee2016-11-07 12:06:18 -05004438 return GetValidProgram(context, program) != nullptr;
4439}
4440
Jamie Madill5b772312018-03-08 20:28:32 -05004441bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004442{
Corentin Walleze4477002017-12-01 14:39:58 -05004443 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004445 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004446 return false;
4447 }
4448
4449 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4450 !context->isBufferGenerated(buffer))
4451 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004452 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004453 return false;
4454 }
4455
4456 return true;
4457}
4458
Jamie Madill5b772312018-03-08 20:28:32 -05004459bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004460{
Geoff Lange8afa902017-09-27 15:00:43 -04004461 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004462 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004463 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004464 return false;
4465 }
4466
4467 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4468 !context->isFramebufferGenerated(framebuffer))
4469 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004470 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004471 return false;
4472 }
4473
4474 return true;
4475}
4476
Jamie Madill5b772312018-03-08 20:28:32 -05004477bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004478{
4479 if (target != GL_RENDERBUFFER)
4480 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004481 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004482 return false;
4483 }
4484
4485 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4486 !context->isRenderbufferGenerated(renderbuffer))
4487 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004488 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004489 return false;
4490 }
4491
4492 return true;
4493}
4494
Jamie Madill5b772312018-03-08 20:28:32 -05004495static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004496{
4497 switch (mode)
4498 {
4499 case GL_FUNC_ADD:
4500 case GL_FUNC_SUBTRACT:
4501 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004502 return true;
4503
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004504 case GL_MIN:
4505 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004506 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004507
4508 default:
4509 return false;
4510 }
4511}
4512
Jamie Madill5b772312018-03-08 20:28:32 -05004513bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004514{
4515 return true;
4516}
4517
Jamie Madill5b772312018-03-08 20:28:32 -05004518bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004519{
Geoff Lang50cac572017-09-26 17:37:43 -04004520 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004521 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004522 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004523 return false;
4524 }
4525
4526 return true;
4527}
4528
Jamie Madill5b772312018-03-08 20:28:32 -05004529bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004530{
Geoff Lang50cac572017-09-26 17:37:43 -04004531 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004532 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004533 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004534 return false;
4535 }
4536
Geoff Lang50cac572017-09-26 17:37:43 -04004537 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004538 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004539 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004540 return false;
4541 }
4542
4543 return true;
4544}
4545
Jamie Madill5b772312018-03-08 20:28:32 -05004546bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004547{
4548 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4549}
4550
4551static bool ValidSrcBlendFunc(GLenum srcBlend)
4552{
4553 switch (srcBlend)
4554 {
4555 case GL_ZERO:
4556 case GL_ONE:
4557 case GL_SRC_COLOR:
4558 case GL_ONE_MINUS_SRC_COLOR:
4559 case GL_DST_COLOR:
4560 case GL_ONE_MINUS_DST_COLOR:
4561 case GL_SRC_ALPHA:
4562 case GL_ONE_MINUS_SRC_ALPHA:
4563 case GL_DST_ALPHA:
4564 case GL_ONE_MINUS_DST_ALPHA:
4565 case GL_CONSTANT_COLOR:
4566 case GL_ONE_MINUS_CONSTANT_COLOR:
4567 case GL_CONSTANT_ALPHA:
4568 case GL_ONE_MINUS_CONSTANT_ALPHA:
4569 case GL_SRC_ALPHA_SATURATE:
4570 return true;
4571
4572 default:
4573 return false;
4574 }
4575}
4576
4577static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4578{
4579 switch (dstBlend)
4580 {
4581 case GL_ZERO:
4582 case GL_ONE:
4583 case GL_SRC_COLOR:
4584 case GL_ONE_MINUS_SRC_COLOR:
4585 case GL_DST_COLOR:
4586 case GL_ONE_MINUS_DST_COLOR:
4587 case GL_SRC_ALPHA:
4588 case GL_ONE_MINUS_SRC_ALPHA:
4589 case GL_DST_ALPHA:
4590 case GL_ONE_MINUS_DST_ALPHA:
4591 case GL_CONSTANT_COLOR:
4592 case GL_ONE_MINUS_CONSTANT_COLOR:
4593 case GL_CONSTANT_ALPHA:
4594 case GL_ONE_MINUS_CONSTANT_ALPHA:
4595 return true;
4596
4597 case GL_SRC_ALPHA_SATURATE:
4598 return (contextMajorVersion >= 3);
4599
4600 default:
4601 return false;
4602 }
4603}
4604
Jamie Madill5b772312018-03-08 20:28:32 -05004605bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004606 GLenum srcRGB,
4607 GLenum dstRGB,
4608 GLenum srcAlpha,
4609 GLenum dstAlpha)
4610{
4611 if (!ValidSrcBlendFunc(srcRGB))
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(dstRGB, 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
4623 if (!ValidSrcBlendFunc(srcAlpha))
4624 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004625 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004626 return false;
4627 }
4628
4629 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4630 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004631 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004632 return false;
4633 }
4634
Frank Henigman146e8a12017-03-02 23:22:37 -05004635 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4636 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004637 {
4638 bool constantColorUsed =
4639 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4640 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4641
4642 bool constantAlphaUsed =
4643 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4644 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4645
4646 if (constantColorUsed && constantAlphaUsed)
4647 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004648 const char *msg;
4649 if (context->getExtensions().webglCompatibility)
4650 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004651 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004652 }
4653 else
4654 {
4655 msg =
4656 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4657 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4658 "implementation.";
4659 ERR() << msg;
4660 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004661 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004662 return false;
4663 }
4664 }
4665
4666 return true;
4667}
4668
Geoff Langc339c4e2016-11-29 10:37:36 -05004669bool ValidateGetString(Context *context, GLenum name)
4670{
4671 switch (name)
4672 {
4673 case GL_VENDOR:
4674 case GL_RENDERER:
4675 case GL_VERSION:
4676 case GL_SHADING_LANGUAGE_VERSION:
4677 case GL_EXTENSIONS:
4678 break;
4679
4680 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4681 if (!context->getExtensions().requestExtension)
4682 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004683 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004684 return false;
4685 }
4686 break;
4687
4688 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004689 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004690 return false;
4691 }
4692
4693 return true;
4694}
4695
Jamie Madill5b772312018-03-08 20:28:32 -05004696bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004697{
4698 if (width <= 0.0f || isNaN(width))
4699 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004700 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004701 return false;
4702 }
4703
4704 return true;
4705}
4706
Jamie Madill5b772312018-03-08 20:28:32 -05004707bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004708 GLuint index,
4709 GLint size,
4710 GLenum type,
4711 GLboolean normalized,
4712 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004713 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004714{
Shao80957d92017-02-20 21:25:59 +08004715 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004716 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004717 return false;
4718 }
4719
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004720 if (stride < 0)
4721 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004722 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004723 return false;
4724 }
4725
Shao80957d92017-02-20 21:25:59 +08004726 const Caps &caps = context->getCaps();
4727 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004728 {
Shao80957d92017-02-20 21:25:59 +08004729 if (stride > caps.maxVertexAttribStride)
4730 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004731 context->handleError(InvalidValue()
4732 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004733 return false;
4734 }
4735
4736 if (index >= caps.maxVertexAttribBindings)
4737 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004738 context->handleError(InvalidValue()
4739 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004740 return false;
4741 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004742 }
4743
4744 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4745 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4746 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4747 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004748 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4749 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004750 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4751 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004752 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004753 context
4754 ->handleError(InvalidOperation()
4755 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004756 return false;
4757 }
4758
4759 if (context->getExtensions().webglCompatibility)
4760 {
4761 // WebGL 1.0 [Section 6.14] Fixed point support
4762 // The WebGL API does not support the GL_FIXED data type.
4763 if (type == GL_FIXED)
4764 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004765 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004766 return false;
4767 }
4768
Geoff Lang2d62ab72017-03-23 16:54:40 -04004769 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004770 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004771 return false;
4772 }
4773 }
4774
4775 return true;
4776}
4777
Jamie Madill5b772312018-03-08 20:28:32 -05004778bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004779{
4780 if (context->getExtensions().webglCompatibility && zNear > zFar)
4781 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004782 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004783 return false;
4784 }
4785
4786 return true;
4787}
4788
Jamie Madill5b772312018-03-08 20:28:32 -05004789bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004790 GLenum target,
4791 GLenum internalformat,
4792 GLsizei width,
4793 GLsizei height)
4794{
4795 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4796 height);
4797}
4798
Jamie Madill5b772312018-03-08 20:28:32 -05004799bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004800 GLenum target,
4801 GLsizei samples,
4802 GLenum internalformat,
4803 GLsizei width,
4804 GLsizei height)
4805{
4806 if (!context->getExtensions().framebufferMultisample)
4807 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004808 context->handleError(InvalidOperation()
4809 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004810 return false;
4811 }
4812
4813 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4814 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4815 // generated.
4816 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4817 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004818 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004819 return false;
4820 }
4821
4822 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4823 // the specified storage. This is different than ES 3.0 in which a sample number higher
4824 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4825 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4826 if (context->getClientMajorVersion() >= 3)
4827 {
4828 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4829 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4830 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004831 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004832 return false;
4833 }
4834 }
4835
4836 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4837 width, height);
4838}
4839
Jamie Madill5b772312018-03-08 20:28:32 -05004840bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004841{
Geoff Lange8afa902017-09-27 15:00:43 -04004842 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004843 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004844 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004845 return false;
4846 }
4847
4848 return true;
4849}
4850
Jamie Madill5b772312018-03-08 20:28:32 -05004851bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004852{
4853 return true;
4854}
4855
Jamie Madill5b772312018-03-08 20:28:32 -05004856bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004857{
4858 return true;
4859}
4860
Jamie Madill5b772312018-03-08 20:28:32 -05004861bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004862{
4863 return true;
4864}
4865
Jamie Madill5b772312018-03-08 20:28:32 -05004866bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004867 GLboolean red,
4868 GLboolean green,
4869 GLboolean blue,
4870 GLboolean alpha)
4871{
4872 return true;
4873}
4874
Jamie Madill5b772312018-03-08 20:28:32 -05004875bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004876{
4877 return true;
4878}
4879
Jamie Madill5b772312018-03-08 20:28:32 -05004880bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004881{
4882 return true;
4883}
4884
Jamie Madill5b772312018-03-08 20:28:32 -05004885bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004886{
4887 switch (mode)
4888 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004889 case CullFaceMode::Front:
4890 case CullFaceMode::Back:
4891 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004892 break;
4893
4894 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004895 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004896 return false;
4897 }
4898
4899 return true;
4900}
4901
Jamie Madill5b772312018-03-08 20:28:32 -05004902bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004903{
4904 if (program == 0)
4905 {
4906 return false;
4907 }
4908
4909 if (!context->getProgram(program))
4910 {
4911 if (context->getShader(program))
4912 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004913 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004914 return false;
4915 }
4916 else
4917 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004918 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004919 return false;
4920 }
4921 }
4922
4923 return true;
4924}
4925
Jamie Madill5b772312018-03-08 20:28:32 -05004926bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004927{
4928 if (shader == 0)
4929 {
4930 return false;
4931 }
4932
4933 if (!context->getShader(shader))
4934 {
4935 if (context->getProgram(shader))
4936 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004937 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004938 return false;
4939 }
4940 else
4941 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004942 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004943 return false;
4944 }
4945 }
4946
4947 return true;
4948}
4949
Jamie Madill5b772312018-03-08 20:28:32 -05004950bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004951{
4952 switch (func)
4953 {
4954 case GL_NEVER:
4955 case GL_ALWAYS:
4956 case GL_LESS:
4957 case GL_LEQUAL:
4958 case GL_EQUAL:
4959 case GL_GREATER:
4960 case GL_GEQUAL:
4961 case GL_NOTEQUAL:
4962 break;
4963
4964 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004965 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004966 return false;
4967 }
4968
4969 return true;
4970}
4971
Jamie Madill5b772312018-03-08 20:28:32 -05004972bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004973{
4974 return true;
4975}
4976
Jamie Madill5b772312018-03-08 20:28:32 -05004977bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004978{
4979 Program *programObject = GetValidProgram(context, program);
4980 if (!programObject)
4981 {
4982 return false;
4983 }
4984
4985 Shader *shaderObject = GetValidShader(context, shader);
4986 if (!shaderObject)
4987 {
4988 return false;
4989 }
4990
4991 const Shader *attachedShader = nullptr;
4992
4993 switch (shaderObject->getType())
4994 {
4995 case GL_VERTEX_SHADER:
4996 {
4997 attachedShader = programObject->getAttachedVertexShader();
4998 break;
4999 }
5000 case GL_FRAGMENT_SHADER:
5001 {
5002 attachedShader = programObject->getAttachedFragmentShader();
5003 break;
5004 }
5005 case GL_COMPUTE_SHADER:
5006 {
5007 attachedShader = programObject->getAttachedComputeShader();
5008 break;
5009 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08005010 case GL_GEOMETRY_SHADER_EXT:
5011 {
5012 attachedShader = programObject->getAttachedGeometryShader();
5013 break;
5014 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04005015 default:
5016 UNREACHABLE();
5017 return false;
5018 }
5019
5020 if (attachedShader != shaderObject)
5021 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005022 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005023 return false;
5024 }
5025
5026 return true;
5027}
5028
Jamie Madill5b772312018-03-08 20:28:32 -05005029bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005030{
5031 if (index >= MAX_VERTEX_ATTRIBS)
5032 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005033 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005034 return false;
5035 }
5036
5037 return true;
5038}
5039
Jamie Madill5b772312018-03-08 20:28:32 -05005040bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005041{
5042 if (index >= MAX_VERTEX_ATTRIBS)
5043 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005044 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005045 return false;
5046 }
5047
5048 return true;
5049}
5050
Jamie Madill5b772312018-03-08 20:28:32 -05005051bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005052{
5053 return true;
5054}
5055
Jamie Madill5b772312018-03-08 20:28:32 -05005056bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005057{
5058 return true;
5059}
5060
Jamie Madill5b772312018-03-08 20:28:32 -05005061bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005062{
5063 switch (mode)
5064 {
5065 case GL_CW:
5066 case GL_CCW:
5067 break;
5068 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005069 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005070 return false;
5071 }
5072
5073 return true;
5074}
5075
Jamie Madill5b772312018-03-08 20:28:32 -05005076bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005077 GLuint program,
5078 GLuint index,
5079 GLsizei bufsize,
5080 GLsizei *length,
5081 GLint *size,
5082 GLenum *type,
5083 GLchar *name)
5084{
5085 if (bufsize < 0)
5086 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005087 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005088 return false;
5089 }
5090
5091 Program *programObject = GetValidProgram(context, program);
5092
5093 if (!programObject)
5094 {
5095 return false;
5096 }
5097
5098 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5099 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005100 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005101 return false;
5102 }
5103
5104 return true;
5105}
5106
Jamie Madill5b772312018-03-08 20:28:32 -05005107bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005108 GLuint program,
5109 GLuint index,
5110 GLsizei bufsize,
5111 GLsizei *length,
5112 GLint *size,
5113 GLenum *type,
5114 GLchar *name)
5115{
5116 if (bufsize < 0)
5117 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005118 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005119 return false;
5120 }
5121
5122 Program *programObject = GetValidProgram(context, program);
5123
5124 if (!programObject)
5125 {
5126 return false;
5127 }
5128
5129 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5130 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005131 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005132 return false;
5133 }
5134
5135 return true;
5136}
5137
Jamie Madill5b772312018-03-08 20:28:32 -05005138bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005139 GLuint program,
5140 GLsizei maxcount,
5141 GLsizei *count,
5142 GLuint *shaders)
5143{
5144 if (maxcount < 0)
5145 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005146 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005147 return false;
5148 }
5149
5150 Program *programObject = GetValidProgram(context, program);
5151
5152 if (!programObject)
5153 {
5154 return false;
5155 }
5156
5157 return true;
5158}
5159
Jamie Madill5b772312018-03-08 20:28:32 -05005160bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005162 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5163 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005164 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005165 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005166 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005167 return false;
5168 }
5169
Jamie Madillc1d770e2017-04-13 17:31:24 -04005170 Program *programObject = GetValidProgram(context, program);
5171
5172 if (!programObject)
5173 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005174 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005175 return false;
5176 }
5177
5178 if (!programObject->isLinked())
5179 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005180 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005181 return false;
5182 }
5183
5184 return true;
5185}
5186
Jamie Madill5b772312018-03-08 20:28:32 -05005187bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005188{
5189 GLenum nativeType;
5190 unsigned int numParams = 0;
5191 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5192}
5193
Jamie Madill5b772312018-03-08 20:28:32 -05005194bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005195{
5196 return true;
5197}
5198
Jamie Madill5b772312018-03-08 20:28:32 -05005199bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005200{
5201 GLenum nativeType;
5202 unsigned int numParams = 0;
5203 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5204}
5205
Jamie Madill5b772312018-03-08 20:28:32 -05005206bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005207{
5208 GLenum nativeType;
5209 unsigned int numParams = 0;
5210 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5211}
5212
Jamie Madill5b772312018-03-08 20:28:32 -05005213bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005214 GLuint program,
5215 GLsizei bufsize,
5216 GLsizei *length,
5217 GLchar *infolog)
5218{
5219 if (bufsize < 0)
5220 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005221 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005222 return false;
5223 }
5224
5225 Program *programObject = GetValidProgram(context, program);
5226 if (!programObject)
5227 {
5228 return false;
5229 }
5230
5231 return true;
5232}
5233
Jamie Madill5b772312018-03-08 20:28:32 -05005234bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005235 GLuint shader,
5236 GLsizei bufsize,
5237 GLsizei *length,
5238 GLchar *infolog)
5239{
5240 if (bufsize < 0)
5241 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005242 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005243 return false;
5244 }
5245
5246 Shader *shaderObject = GetValidShader(context, shader);
5247 if (!shaderObject)
5248 {
5249 return false;
5250 }
5251
5252 return true;
5253}
5254
Jamie Madill5b772312018-03-08 20:28:32 -05005255bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005256 GLenum shadertype,
5257 GLenum precisiontype,
5258 GLint *range,
5259 GLint *precision)
5260{
5261 switch (shadertype)
5262 {
5263 case GL_VERTEX_SHADER:
5264 case GL_FRAGMENT_SHADER:
5265 break;
5266 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005267 context->handleError(InvalidOperation()
5268 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005269 return false;
5270 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005271 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005272 return false;
5273 }
5274
5275 switch (precisiontype)
5276 {
5277 case GL_LOW_FLOAT:
5278 case GL_MEDIUM_FLOAT:
5279 case GL_HIGH_FLOAT:
5280 case GL_LOW_INT:
5281 case GL_MEDIUM_INT:
5282 case GL_HIGH_INT:
5283 break;
5284
5285 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005286 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005287 return false;
5288 }
5289
5290 return true;
5291}
5292
Jamie Madill5b772312018-03-08 20:28:32 -05005293bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005294 GLuint shader,
5295 GLsizei bufsize,
5296 GLsizei *length,
5297 GLchar *source)
5298{
5299 if (bufsize < 0)
5300 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005301 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005302 return false;
5303 }
5304
5305 Shader *shaderObject = GetValidShader(context, shader);
5306 if (!shaderObject)
5307 {
5308 return false;
5309 }
5310
5311 return true;
5312}
5313
Jamie Madill5b772312018-03-08 20:28:32 -05005314bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005315{
5316 if (strstr(name, "gl_") == name)
5317 {
5318 return false;
5319 }
5320
Geoff Langfc32e8b2017-05-31 14:16:59 -04005321 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5322 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005323 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005324 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005325 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005326 return false;
5327 }
5328
Jamie Madillc1d770e2017-04-13 17:31:24 -04005329 Program *programObject = GetValidProgram(context, program);
5330
5331 if (!programObject)
5332 {
5333 return false;
5334 }
5335
5336 if (!programObject->isLinked())
5337 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005338 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005339 return false;
5340 }
5341
5342 return true;
5343}
5344
Jamie Madill5b772312018-03-08 20:28:32 -05005345bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005346{
5347 switch (mode)
5348 {
5349 case GL_FASTEST:
5350 case GL_NICEST:
5351 case GL_DONT_CARE:
5352 break;
5353
5354 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005355 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005356 return false;
5357 }
5358
5359 switch (target)
5360 {
5361 case GL_GENERATE_MIPMAP_HINT:
5362 break;
5363
Geoff Lange7bd2182017-06-16 16:13:13 -04005364 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5365 if (context->getClientVersion() < ES_3_0 &&
5366 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005367 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005368 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005369 return false;
5370 }
5371 break;
5372
5373 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005374 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005375 return false;
5376 }
5377
5378 return true;
5379}
5380
Jamie Madill5b772312018-03-08 20:28:32 -05005381bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005382{
5383 return true;
5384}
5385
Jamie Madill5b772312018-03-08 20:28:32 -05005386bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005387{
5388 return true;
5389}
5390
Jamie Madill5b772312018-03-08 20:28:32 -05005391bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005392{
5393 return true;
5394}
5395
Jamie Madill5b772312018-03-08 20:28:32 -05005396bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397{
5398 return true;
5399}
5400
Jamie Madill5b772312018-03-08 20:28:32 -05005401bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005402{
5403 return true;
5404}
5405
Jamie Madill5b772312018-03-08 20:28:32 -05005406bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005407{
5408 return true;
5409}
5410
Jamie Madill5b772312018-03-08 20:28:32 -05005411bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005412{
5413 if (context->getClientMajorVersion() < 3)
5414 {
5415 switch (pname)
5416 {
5417 case GL_UNPACK_IMAGE_HEIGHT:
5418 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005419 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005420 return false;
5421
5422 case GL_UNPACK_ROW_LENGTH:
5423 case GL_UNPACK_SKIP_ROWS:
5424 case GL_UNPACK_SKIP_PIXELS:
5425 if (!context->getExtensions().unpackSubimage)
5426 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005427 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005428 return false;
5429 }
5430 break;
5431
5432 case GL_PACK_ROW_LENGTH:
5433 case GL_PACK_SKIP_ROWS:
5434 case GL_PACK_SKIP_PIXELS:
5435 if (!context->getExtensions().packSubimage)
5436 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005437 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005438 return false;
5439 }
5440 break;
5441 }
5442 }
5443
5444 if (param < 0)
5445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005446 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005447 return false;
5448 }
5449
5450 switch (pname)
5451 {
5452 case GL_UNPACK_ALIGNMENT:
5453 if (param != 1 && param != 2 && param != 4 && param != 8)
5454 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005455 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005456 return false;
5457 }
5458 break;
5459
5460 case GL_PACK_ALIGNMENT:
5461 if (param != 1 && param != 2 && param != 4 && param != 8)
5462 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005463 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005464 return false;
5465 }
5466 break;
5467
5468 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005469 if (!context->getExtensions().packReverseRowOrder)
5470 {
5471 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5472 }
5473 break;
5474
Jamie Madillc1d770e2017-04-13 17:31:24 -04005475 case GL_UNPACK_ROW_LENGTH:
5476 case GL_UNPACK_IMAGE_HEIGHT:
5477 case GL_UNPACK_SKIP_IMAGES:
5478 case GL_UNPACK_SKIP_ROWS:
5479 case GL_UNPACK_SKIP_PIXELS:
5480 case GL_PACK_ROW_LENGTH:
5481 case GL_PACK_SKIP_ROWS:
5482 case GL_PACK_SKIP_PIXELS:
5483 break;
5484
5485 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005486 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005487 return false;
5488 }
5489
5490 return true;
5491}
5492
Jamie Madill5b772312018-03-08 20:28:32 -05005493bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494{
5495 return true;
5496}
5497
Jamie Madill5b772312018-03-08 20:28:32 -05005498bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005499{
5500 return true;
5501}
5502
Jamie Madill5b772312018-03-08 20:28:32 -05005503bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005504{
5505 return true;
5506}
5507
Jamie Madill5b772312018-03-08 20:28:32 -05005508bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005509{
5510 if (width < 0 || height < 0)
5511 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005512 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005513 return false;
5514 }
5515
5516 return true;
5517}
5518
Jamie Madill5b772312018-03-08 20:28:32 -05005519bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005520 GLsizei n,
5521 const GLuint *shaders,
5522 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005523 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005524 GLsizei length)
5525{
5526 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5527 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5528 shaderBinaryFormats.end())
5529 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005530 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005531 return false;
5532 }
5533
5534 return true;
5535}
5536
Jamie Madill5b772312018-03-08 20:28:32 -05005537bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005538 GLuint shader,
5539 GLsizei count,
5540 const GLchar *const *string,
5541 const GLint *length)
5542{
5543 if (count < 0)
5544 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005545 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005546 return false;
5547 }
5548
Geoff Langfc32e8b2017-05-31 14:16:59 -04005549 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5550 // shader-related entry points
5551 if (context->getExtensions().webglCompatibility)
5552 {
5553 for (GLsizei i = 0; i < count; i++)
5554 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005555 size_t len =
5556 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005557
5558 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005559 if (!IsValidESSLShaderSourceString(string[i], len,
5560 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005561 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005562 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005563 return false;
5564 }
5565 }
5566 }
5567
Jamie Madillc1d770e2017-04-13 17:31:24 -04005568 Shader *shaderObject = GetValidShader(context, shader);
5569 if (!shaderObject)
5570 {
5571 return false;
5572 }
5573
5574 return true;
5575}
5576
Jamie Madill5b772312018-03-08 20:28:32 -05005577bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005578{
5579 if (!IsValidStencilFunc(func))
5580 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005581 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005582 return false;
5583 }
5584
5585 return true;
5586}
5587
Jamie Madill5b772312018-03-08 20:28:32 -05005588bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005589{
5590 if (!IsValidStencilFace(face))
5591 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005592 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005593 return false;
5594 }
5595
5596 if (!IsValidStencilFunc(func))
5597 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005598 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005599 return false;
5600 }
5601
5602 return true;
5603}
5604
Jamie Madill5b772312018-03-08 20:28:32 -05005605bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005606{
5607 return true;
5608}
5609
Jamie Madill5b772312018-03-08 20:28:32 -05005610bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005611{
5612 if (!IsValidStencilFace(face))
5613 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005614 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005615 return false;
5616 }
5617
5618 return true;
5619}
5620
Jamie Madill5b772312018-03-08 20:28:32 -05005621bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005622{
5623 if (!IsValidStencilOp(fail))
5624 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005625 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005626 return false;
5627 }
5628
5629 if (!IsValidStencilOp(zfail))
5630 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005631 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005632 return false;
5633 }
5634
5635 if (!IsValidStencilOp(zpass))
5636 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005637 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005638 return false;
5639 }
5640
5641 return true;
5642}
5643
Jamie Madill5b772312018-03-08 20:28:32 -05005644bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005645 GLenum face,
5646 GLenum fail,
5647 GLenum zfail,
5648 GLenum zpass)
5649{
5650 if (!IsValidStencilFace(face))
5651 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005652 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005653 return false;
5654 }
5655
5656 return ValidateStencilOp(context, fail, zfail, zpass);
5657}
5658
Jamie Madill5b772312018-03-08 20:28:32 -05005659bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005660{
5661 return ValidateUniform(context, GL_FLOAT, location, 1);
5662}
5663
Jamie Madill5b772312018-03-08 20:28:32 -05005664bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005665{
5666 return ValidateUniform(context, GL_FLOAT, location, count);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005670{
5671 return ValidateUniform1iv(context, location, 1, &x);
5672}
5673
Jamie Madill5b772312018-03-08 20:28:32 -05005674bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675{
5676 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005680{
5681 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5682}
5683
Jamie Madill5b772312018-03-08 20:28:32 -05005684bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005685{
5686 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5687}
5688
Jamie Madill5b772312018-03-08 20:28:32 -05005689bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005690{
5691 return ValidateUniform(context, GL_INT_VEC2, location, count);
5692}
5693
Jamie Madill5b772312018-03-08 20:28:32 -05005694bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005695{
5696 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5697}
5698
Jamie Madill5b772312018-03-08 20:28:32 -05005699bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005700{
5701 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5702}
5703
Jamie Madill5b772312018-03-08 20:28:32 -05005704bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005705{
5706 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5707}
5708
Jamie Madill5b772312018-03-08 20:28:32 -05005709bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005710{
5711 return ValidateUniform(context, GL_INT_VEC3, location, count);
5712}
5713
Jamie Madill5b772312018-03-08 20:28:32 -05005714bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005715{
5716 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5717}
5718
Jamie Madill5b772312018-03-08 20:28:32 -05005719bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005720{
5721 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5722}
5723
Jamie Madill5b772312018-03-08 20:28:32 -05005724bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005725{
5726 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5727}
5728
Jamie Madill5b772312018-03-08 20:28:32 -05005729bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005730{
5731 return ValidateUniform(context, GL_INT_VEC4, location, count);
5732}
5733
Jamie Madill5b772312018-03-08 20:28:32 -05005734bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005735 GLint location,
5736 GLsizei count,
5737 GLboolean transpose,
5738 const GLfloat *value)
5739{
5740 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5741}
5742
Jamie Madill5b772312018-03-08 20:28:32 -05005743bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005744 GLint location,
5745 GLsizei count,
5746 GLboolean transpose,
5747 const GLfloat *value)
5748{
5749 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5750}
5751
Jamie Madill5b772312018-03-08 20:28:32 -05005752bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005753 GLint location,
5754 GLsizei count,
5755 GLboolean transpose,
5756 const GLfloat *value)
5757{
5758 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5759}
5760
Jamie Madill5b772312018-03-08 20:28:32 -05005761bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005762{
5763 Program *programObject = GetValidProgram(context, program);
5764
5765 if (!programObject)
5766 {
5767 return false;
5768 }
5769
5770 return true;
5771}
5772
Jamie Madill5b772312018-03-08 20:28:32 -05005773bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005774{
5775 return ValidateVertexAttribIndex(context, index);
5776}
5777
Jamie Madill5b772312018-03-08 20:28:32 -05005778bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005779{
5780 return ValidateVertexAttribIndex(context, index);
5781}
5782
Jamie Madill5b772312018-03-08 20:28:32 -05005783bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005784{
5785 return ValidateVertexAttribIndex(context, index);
5786}
5787
Jamie Madill5b772312018-03-08 20:28:32 -05005788bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005789{
5790 return ValidateVertexAttribIndex(context, index);
5791}
5792
Jamie Madill5b772312018-03-08 20:28:32 -05005793bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005794{
5795 return ValidateVertexAttribIndex(context, index);
5796}
5797
Jamie Madill5b772312018-03-08 20:28:32 -05005798bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005799{
5800 return ValidateVertexAttribIndex(context, index);
5801}
5802
Jamie Madill5b772312018-03-08 20:28:32 -05005803bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005804 GLuint index,
5805 GLfloat x,
5806 GLfloat y,
5807 GLfloat z,
5808 GLfloat w)
5809{
5810 return ValidateVertexAttribIndex(context, index);
5811}
5812
Jamie Madill5b772312018-03-08 20:28:32 -05005813bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005814{
5815 return ValidateVertexAttribIndex(context, index);
5816}
5817
Jamie Madill5b772312018-03-08 20:28:32 -05005818bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005819{
5820 if (width < 0 || height < 0)
5821 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005822 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005823 return false;
5824 }
5825
5826 return true;
5827}
5828
Jamie Madill5b772312018-03-08 20:28:32 -05005829bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005830{
5831 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5832}
5833
Jamie Madill5b772312018-03-08 20:28:32 -05005834bool ValidateDrawElements(Context *context,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005835 GLenum mode,
5836 GLsizei count,
5837 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005838 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005839{
5840 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5841}
5842
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005843bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005844 GLenum target,
5845 GLenum attachment,
5846 GLenum pname,
5847 GLint *params)
5848{
5849 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5850 nullptr);
5851}
5852
Jamie Madill5b772312018-03-08 20:28:32 -05005853bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005854{
5855 return ValidateGetProgramivBase(context, program, pname, nullptr);
5856}
5857
Jamie Madill5b772312018-03-08 20:28:32 -05005858bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005859 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005860 GLint level,
5861 GLenum internalformat,
5862 GLint x,
5863 GLint y,
5864 GLsizei width,
5865 GLsizei height,
5866 GLint border)
5867{
5868 if (context->getClientMajorVersion() < 3)
5869 {
5870 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5871 0, x, y, width, height, border);
5872 }
5873
5874 ASSERT(context->getClientMajorVersion() == 3);
5875 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5876 0, x, y, width, height, border);
5877}
5878
5879bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005880 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005881 GLint level,
5882 GLint xoffset,
5883 GLint yoffset,
5884 GLint x,
5885 GLint y,
5886 GLsizei width,
5887 GLsizei height)
5888{
5889 if (context->getClientMajorVersion() < 3)
5890 {
5891 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5892 yoffset, x, y, width, height, 0);
5893 }
5894
5895 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5896 yoffset, 0, x, y, width, height, 0);
5897}
5898
5899bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5900{
5901 return ValidateGenOrDelete(context, n);
5902}
5903
5904bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5905{
5906 return ValidateGenOrDelete(context, n);
5907}
5908
5909bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5910{
5911 return ValidateGenOrDelete(context, n);
5912}
5913
5914bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5915{
5916 return ValidateGenOrDelete(context, n);
5917}
5918
5919bool ValidateDisable(Context *context, GLenum cap)
5920{
5921 if (!ValidCap(context, cap, false))
5922 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005923 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005924 return false;
5925 }
5926
5927 return true;
5928}
5929
5930bool ValidateEnable(Context *context, GLenum cap)
5931{
5932 if (!ValidCap(context, cap, false))
5933 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005934 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005935 return false;
5936 }
5937
5938 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5939 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5940 {
5941 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005942 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005943
5944 // We also output an error message to the debugger window if tracing is active, so that
5945 // developers can see the error message.
5946 ERR() << errorMessage;
5947 return false;
5948 }
5949
5950 return true;
5951}
5952
5953bool ValidateFramebufferRenderbuffer(Context *context,
5954 GLenum target,
5955 GLenum attachment,
5956 GLenum renderbuffertarget,
5957 GLuint renderbuffer)
5958{
Geoff Lange8afa902017-09-27 15:00:43 -04005959 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005960 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005961 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5962 return false;
5963 }
5964
5965 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5966 {
5967 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005968 return false;
5969 }
5970
5971 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5972 renderbuffertarget, renderbuffer);
5973}
5974
5975bool ValidateFramebufferTexture2D(Context *context,
5976 GLenum target,
5977 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005978 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005979 GLuint texture,
5980 GLint level)
5981{
5982 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5983 // extension
5984 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5985 level != 0)
5986 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005987 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005988 return false;
5989 }
5990
5991 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5992 {
5993 return false;
5994 }
5995
5996 if (texture != 0)
5997 {
5998 gl::Texture *tex = context->getTexture(texture);
5999 ASSERT(tex);
6000
6001 const gl::Caps &caps = context->getCaps();
6002
6003 switch (textarget)
6004 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006005 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 {
6007 if (level > gl::log2(caps.max2DTextureSize))
6008 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006009 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006010 return false;
6011 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006012 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006014 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006015 return false;
6016 }
6017 }
6018 break;
6019
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006020 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006021 {
6022 if (level != 0)
6023 {
6024 context->handleError(InvalidValue());
6025 return false;
6026 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006027 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006028 {
6029 context->handleError(InvalidOperation()
6030 << "Textarget must match the texture target type.");
6031 return false;
6032 }
6033 }
6034 break;
6035
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006036 case TextureTarget::CubeMapNegativeX:
6037 case TextureTarget::CubeMapNegativeY:
6038 case TextureTarget::CubeMapNegativeZ:
6039 case TextureTarget::CubeMapPositiveX:
6040 case TextureTarget::CubeMapPositiveY:
6041 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 {
6043 if (level > gl::log2(caps.maxCubeMapTextureSize))
6044 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006045 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006046 return false;
6047 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006048 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006050 context->handleError(InvalidOperation()
6051 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006052 return false;
6053 }
6054 }
6055 break;
6056
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006057 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 {
6059 if (context->getClientVersion() < ES_3_1)
6060 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006061 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006062 return false;
6063 }
6064
6065 if (level != 0)
6066 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006067 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006068 return false;
6069 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006070 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006072 context->handleError(InvalidOperation()
6073 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006074 return false;
6075 }
6076 }
6077 break;
6078
6079 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006080 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006081 return false;
6082 }
6083
6084 const Format &format = tex->getFormat(textarget, level);
6085 if (format.info->compressed)
6086 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006087 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006088 return false;
6089 }
6090 }
6091
6092 return true;
6093}
6094
6095bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6096{
6097 return ValidateGenOrDelete(context, n);
6098}
6099
6100bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6101{
6102 return ValidateGenOrDelete(context, n);
6103}
6104
6105bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6106{
6107 return ValidateGenOrDelete(context, n);
6108}
6109
6110bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6111{
6112 return ValidateGenOrDelete(context, n);
6113}
6114
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006115bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006116{
6117 if (!ValidTextureTarget(context, target))
6118 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006119 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006120 return false;
6121 }
6122
6123 Texture *texture = context->getTargetTexture(target);
6124
6125 if (texture == nullptr)
6126 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006127 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006128 return false;
6129 }
6130
6131 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6132
6133 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6134 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6135 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6136 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006137 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006138 return false;
6139 }
6140
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006141 TextureTarget baseTarget = (target == TextureType::CubeMap)
6142 ? TextureTarget::CubeMapPositiveX
6143 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006144 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6145 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6146 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006147 {
6148 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6149 return false;
6150 }
6151
Geoff Lang536eca12017-09-13 11:23:35 -04006152 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6153 bool formatUnsized = !format.sized;
6154 bool formatColorRenderableAndFilterable =
6155 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6156 format.renderSupport(context->getClientVersion(), context->getExtensions());
6157 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006158 {
Geoff Lang536eca12017-09-13 11:23:35 -04006159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006160 return false;
6161 }
6162
Geoff Lang536eca12017-09-13 11:23:35 -04006163 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6164 // generation
6165 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6166 {
6167 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6168 return false;
6169 }
6170
6171 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6172 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006173 bool supportsSRGBMipmapGeneration =
6174 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006175 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006176 {
Geoff Lang536eca12017-09-13 11:23:35 -04006177 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006178 return false;
6179 }
6180
6181 // Non-power of 2 ES2 check
6182 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6183 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6184 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6185 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006186 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6187 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006188 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006189 return false;
6190 }
6191
6192 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006193 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006194 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006195 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006196 return false;
6197 }
6198
6199 return true;
6200}
6201
Jamie Madill5b772312018-03-08 20:28:32 -05006202bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006203 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006204 GLenum pname,
6205 GLint *params)
6206{
6207 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6208}
6209
6210bool ValidateGetRenderbufferParameteriv(Context *context,
6211 GLenum target,
6212 GLenum pname,
6213 GLint *params)
6214{
6215 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6216}
6217
6218bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6219{
6220 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6221}
6222
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006223bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006224{
6225 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6226}
6227
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006228bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006229{
6230 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6231}
6232
6233bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6234{
6235 return ValidateGetUniformBase(context, program, location);
6236}
6237
6238bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6239{
6240 return ValidateGetUniformBase(context, program, location);
6241}
6242
6243bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6244{
6245 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6246}
6247
6248bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6249{
6250 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6251}
6252
6253bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6254{
6255 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6256}
6257
6258bool ValidateIsEnabled(Context *context, GLenum cap)
6259{
6260 if (!ValidCap(context, cap, true))
6261 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006262 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006263 return false;
6264 }
6265
6266 return true;
6267}
6268
6269bool ValidateLinkProgram(Context *context, GLuint program)
6270{
6271 if (context->hasActiveTransformFeedback(program))
6272 {
6273 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006274 context->handleError(InvalidOperation() << "Cannot link program while program is "
6275 "associated with an active transform "
6276 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006277 return false;
6278 }
6279
6280 Program *programObject = GetValidProgram(context, program);
6281 if (!programObject)
6282 {
6283 return false;
6284 }
6285
6286 return true;
6287}
6288
Jamie Madill4928b7c2017-06-20 12:57:39 -04006289bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006290 GLint x,
6291 GLint y,
6292 GLsizei width,
6293 GLsizei height,
6294 GLenum format,
6295 GLenum type,
6296 void *pixels)
6297{
6298 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6299 nullptr, pixels);
6300}
6301
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006302bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006303{
6304 return ValidateTexParameterBase(context, target, pname, -1, &param);
6305}
6306
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006307bool ValidateTexParameterfv(Context *context,
6308 TextureType target,
6309 GLenum pname,
6310 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006311{
6312 return ValidateTexParameterBase(context, target, pname, -1, params);
6313}
6314
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006315bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006316{
6317 return ValidateTexParameterBase(context, target, pname, -1, &param);
6318}
6319
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006320bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006321{
6322 return ValidateTexParameterBase(context, target, pname, -1, params);
6323}
6324
6325bool ValidateUseProgram(Context *context, GLuint program)
6326{
6327 if (program != 0)
6328 {
6329 Program *programObject = context->getProgram(program);
6330 if (!programObject)
6331 {
6332 // ES 3.1.0 section 7.3 page 72
6333 if (context->getShader(program))
6334 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006335 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006336 return false;
6337 }
6338 else
6339 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006340 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006341 return false;
6342 }
6343 }
6344 if (!programObject->isLinked())
6345 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006346 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006347 return false;
6348 }
6349 }
6350 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6351 {
6352 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006353 context
6354 ->handleError(InvalidOperation()
6355 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006356 return false;
6357 }
6358
6359 return true;
6360}
6361
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006362bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6363{
6364 if (!context->getExtensions().fence)
6365 {
6366 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6367 return false;
6368 }
6369
6370 if (n < 0)
6371 {
6372 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6373 return false;
6374 }
6375
6376 return true;
6377}
6378
6379bool ValidateFinishFenceNV(Context *context, GLuint fence)
6380{
6381 if (!context->getExtensions().fence)
6382 {
6383 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6384 return false;
6385 }
6386
6387 FenceNV *fenceObject = context->getFenceNV(fence);
6388
6389 if (fenceObject == nullptr)
6390 {
6391 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6392 return false;
6393 }
6394
6395 if (!fenceObject->isSet())
6396 {
6397 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6398 return false;
6399 }
6400
6401 return true;
6402}
6403
6404bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6405{
6406 if (!context->getExtensions().fence)
6407 {
6408 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6409 return false;
6410 }
6411
6412 if (n < 0)
6413 {
6414 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6415 return false;
6416 }
6417
6418 return true;
6419}
6420
6421bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6422{
6423 if (!context->getExtensions().fence)
6424 {
6425 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6426 return false;
6427 }
6428
6429 FenceNV *fenceObject = context->getFenceNV(fence);
6430
6431 if (fenceObject == nullptr)
6432 {
6433 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6434 return false;
6435 }
6436
6437 if (!fenceObject->isSet())
6438 {
6439 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6440 return false;
6441 }
6442
6443 switch (pname)
6444 {
6445 case GL_FENCE_STATUS_NV:
6446 case GL_FENCE_CONDITION_NV:
6447 break;
6448
6449 default:
6450 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6451 return false;
6452 }
6453
6454 return true;
6455}
6456
6457bool ValidateGetGraphicsResetStatusEXT(Context *context)
6458{
6459 if (!context->getExtensions().robustness)
6460 {
6461 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6462 return false;
6463 }
6464
6465 return true;
6466}
6467
6468bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6469 GLuint shader,
6470 GLsizei bufsize,
6471 GLsizei *length,
6472 GLchar *source)
6473{
6474 if (!context->getExtensions().translatedShaderSource)
6475 {
6476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6477 return false;
6478 }
6479
6480 if (bufsize < 0)
6481 {
6482 context->handleError(InvalidValue());
6483 return false;
6484 }
6485
6486 Shader *shaderObject = context->getShader(shader);
6487
6488 if (!shaderObject)
6489 {
6490 context->handleError(InvalidOperation());
6491 return false;
6492 }
6493
6494 return true;
6495}
6496
6497bool ValidateIsFenceNV(Context *context, GLuint fence)
6498{
6499 if (!context->getExtensions().fence)
6500 {
6501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6502 return false;
6503 }
6504
6505 return true;
6506}
6507
Jamie Madill007530e2017-12-28 14:27:04 -05006508bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6509{
6510 if (!context->getExtensions().fence)
6511 {
6512 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6513 return false;
6514 }
6515
6516 if (condition != GL_ALL_COMPLETED_NV)
6517 {
6518 context->handleError(InvalidEnum());
6519 return false;
6520 }
6521
6522 FenceNV *fenceObject = context->getFenceNV(fence);
6523
6524 if (fenceObject == nullptr)
6525 {
6526 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6527 return false;
6528 }
6529
6530 return true;
6531}
6532
6533bool ValidateTestFenceNV(Context *context, GLuint fence)
6534{
6535 if (!context->getExtensions().fence)
6536 {
6537 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6538 return false;
6539 }
6540
6541 FenceNV *fenceObject = context->getFenceNV(fence);
6542
6543 if (fenceObject == nullptr)
6544 {
6545 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6546 return false;
6547 }
6548
6549 if (fenceObject->isSet() != GL_TRUE)
6550 {
6551 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6552 return false;
6553 }
6554
6555 return true;
6556}
6557
6558bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006559 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006560 GLsizei levels,
6561 GLenum internalformat,
6562 GLsizei width,
6563 GLsizei height)
6564{
6565 if (!context->getExtensions().textureStorage)
6566 {
6567 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6568 return false;
6569 }
6570
6571 if (context->getClientMajorVersion() < 3)
6572 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006573 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006574 height);
6575 }
6576
6577 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006578 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006579 1);
6580}
6581
6582bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6583{
6584 if (!context->getExtensions().instancedArrays)
6585 {
6586 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6587 return false;
6588 }
6589
6590 if (index >= MAX_VERTEX_ATTRIBS)
6591 {
6592 context->handleError(InvalidValue());
6593 return false;
6594 }
6595
6596 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6597 {
6598 if (index == 0 && divisor != 0)
6599 {
6600 const char *errorMessage =
6601 "The current context doesn't support setting a non-zero divisor on the "
6602 "attribute with index zero. "
6603 "Please reorder the attributes in your vertex shader so that attribute zero "
6604 "can have a zero divisor.";
6605 context->handleError(InvalidOperation() << errorMessage);
6606
6607 // We also output an error message to the debugger window if tracing is active, so
6608 // that developers can see the error message.
6609 ERR() << errorMessage;
6610 return false;
6611 }
6612 }
6613
6614 return true;
6615}
6616
6617bool ValidateTexImage3DOES(Context *context,
6618 GLenum target,
6619 GLint level,
6620 GLenum internalformat,
6621 GLsizei width,
6622 GLsizei height,
6623 GLsizei depth,
6624 GLint border,
6625 GLenum format,
6626 GLenum type,
6627 const void *pixels)
6628{
6629 UNIMPLEMENTED(); // FIXME
6630 return false;
6631}
6632
6633bool ValidatePopGroupMarkerEXT(Context *context)
6634{
6635 if (!context->getExtensions().debugMarker)
6636 {
6637 // The debug marker calls should not set error state
6638 // However, it seems reasonable to set an error state if the extension is not enabled
6639 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6640 return false;
6641 }
6642
6643 return true;
6644}
6645
Jamie Madillfa920eb2018-01-04 11:45:50 -05006646bool ValidateTexStorage1DEXT(Context *context,
6647 GLenum target,
6648 GLsizei levels,
6649 GLenum internalformat,
6650 GLsizei width)
6651{
6652 UNIMPLEMENTED();
6653 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6654 return false;
6655}
6656
6657bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006658 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006659 GLsizei levels,
6660 GLenum internalformat,
6661 GLsizei width,
6662 GLsizei height,
6663 GLsizei depth)
6664{
6665 if (!context->getExtensions().textureStorage)
6666 {
6667 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6668 return false;
6669 }
6670
6671 if (context->getClientMajorVersion() < 3)
6672 {
6673 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6674 return false;
6675 }
6676
6677 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6678 depth);
6679}
6680
Jamie Madillc29968b2016-01-20 11:17:23 -05006681} // namespace gl