blob: 5893f81732c4c706520e03e0ab994dcb5cb156f1 [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
Jiawei Shao385b3e02018-03-21 09:43:28 +08004162bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004163{
4164 switch (type)
4165 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004166 case ShaderType::Vertex:
4167 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004168 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004169
Jiawei Shao385b3e02018-03-21 09:43:28 +08004170 case ShaderType::Compute:
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 Shao385b3e02018-03-21 09:43:28 +08004178 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004179 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
Jiawei Shao385b3e02018-03-21 09:43:28 +08004360 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004361 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004362 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4363 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004364 }
4365
4366 return true;
4367}
4368
Jamie Madill5b772312018-03-08 20:28:32 -05004369bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004370{
4371 if (index >= MAX_VERTEX_ATTRIBS)
4372 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004373 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004374 return false;
4375 }
4376
4377 if (strncmp(name, "gl_", 3) == 0)
4378 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004379 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004380 return false;
4381 }
4382
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004383 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004384 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004385 const size_t length = strlen(name);
4386
4387 if (!IsValidESSLString(name, length))
4388 {
4389 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4390 // for shader-related entry points
4391 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4392 return false;
4393 }
4394
4395 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4396 {
4397 return false;
4398 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004399 }
4400
Jamie Madill01a80ee2016-11-07 12:06:18 -05004401 return GetValidProgram(context, program) != nullptr;
4402}
4403
Jamie Madill5b772312018-03-08 20:28:32 -05004404bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004405{
Corentin Walleze4477002017-12-01 14:39:58 -05004406 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004407 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004408 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004409 return false;
4410 }
4411
4412 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4413 !context->isBufferGenerated(buffer))
4414 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004415 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004416 return false;
4417 }
4418
4419 return true;
4420}
4421
Jamie Madill5b772312018-03-08 20:28:32 -05004422bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004423{
Geoff Lange8afa902017-09-27 15:00:43 -04004424 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004425 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004426 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004427 return false;
4428 }
4429
4430 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4431 !context->isFramebufferGenerated(framebuffer))
4432 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004433 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004434 return false;
4435 }
4436
4437 return true;
4438}
4439
Jamie Madill5b772312018-03-08 20:28:32 -05004440bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004441{
4442 if (target != GL_RENDERBUFFER)
4443 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004444 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004445 return false;
4446 }
4447
4448 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4449 !context->isRenderbufferGenerated(renderbuffer))
4450 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004451 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004452 return false;
4453 }
4454
4455 return true;
4456}
4457
Jamie Madill5b772312018-03-08 20:28:32 -05004458static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004459{
4460 switch (mode)
4461 {
4462 case GL_FUNC_ADD:
4463 case GL_FUNC_SUBTRACT:
4464 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004465 return true;
4466
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004467 case GL_MIN:
4468 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004469 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004470
4471 default:
4472 return false;
4473 }
4474}
4475
Jamie Madill5b772312018-03-08 20:28:32 -05004476bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004477{
4478 return true;
4479}
4480
Jamie Madill5b772312018-03-08 20:28:32 -05004481bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004482{
Geoff Lang50cac572017-09-26 17:37:43 -04004483 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004484 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004485 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004486 return false;
4487 }
4488
4489 return true;
4490}
4491
Jamie Madill5b772312018-03-08 20:28:32 -05004492bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004493{
Geoff Lang50cac572017-09-26 17:37:43 -04004494 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004495 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004496 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004497 return false;
4498 }
4499
Geoff Lang50cac572017-09-26 17:37:43 -04004500 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004501 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004502 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004503 return false;
4504 }
4505
4506 return true;
4507}
4508
Jamie Madill5b772312018-03-08 20:28:32 -05004509bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004510{
4511 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4512}
4513
4514static bool ValidSrcBlendFunc(GLenum srcBlend)
4515{
4516 switch (srcBlend)
4517 {
4518 case GL_ZERO:
4519 case GL_ONE:
4520 case GL_SRC_COLOR:
4521 case GL_ONE_MINUS_SRC_COLOR:
4522 case GL_DST_COLOR:
4523 case GL_ONE_MINUS_DST_COLOR:
4524 case GL_SRC_ALPHA:
4525 case GL_ONE_MINUS_SRC_ALPHA:
4526 case GL_DST_ALPHA:
4527 case GL_ONE_MINUS_DST_ALPHA:
4528 case GL_CONSTANT_COLOR:
4529 case GL_ONE_MINUS_CONSTANT_COLOR:
4530 case GL_CONSTANT_ALPHA:
4531 case GL_ONE_MINUS_CONSTANT_ALPHA:
4532 case GL_SRC_ALPHA_SATURATE:
4533 return true;
4534
4535 default:
4536 return false;
4537 }
4538}
4539
4540static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4541{
4542 switch (dstBlend)
4543 {
4544 case GL_ZERO:
4545 case GL_ONE:
4546 case GL_SRC_COLOR:
4547 case GL_ONE_MINUS_SRC_COLOR:
4548 case GL_DST_COLOR:
4549 case GL_ONE_MINUS_DST_COLOR:
4550 case GL_SRC_ALPHA:
4551 case GL_ONE_MINUS_SRC_ALPHA:
4552 case GL_DST_ALPHA:
4553 case GL_ONE_MINUS_DST_ALPHA:
4554 case GL_CONSTANT_COLOR:
4555 case GL_ONE_MINUS_CONSTANT_COLOR:
4556 case GL_CONSTANT_ALPHA:
4557 case GL_ONE_MINUS_CONSTANT_ALPHA:
4558 return true;
4559
4560 case GL_SRC_ALPHA_SATURATE:
4561 return (contextMajorVersion >= 3);
4562
4563 default:
4564 return false;
4565 }
4566}
4567
Jamie Madill5b772312018-03-08 20:28:32 -05004568bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004569 GLenum srcRGB,
4570 GLenum dstRGB,
4571 GLenum srcAlpha,
4572 GLenum dstAlpha)
4573{
4574 if (!ValidSrcBlendFunc(srcRGB))
4575 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004576 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004577 return false;
4578 }
4579
4580 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4581 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004582 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004583 return false;
4584 }
4585
4586 if (!ValidSrcBlendFunc(srcAlpha))
4587 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004588 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004589 return false;
4590 }
4591
4592 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4593 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004594 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004595 return false;
4596 }
4597
Frank Henigman146e8a12017-03-02 23:22:37 -05004598 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4599 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004600 {
4601 bool constantColorUsed =
4602 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4603 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4604
4605 bool constantAlphaUsed =
4606 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4607 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4608
4609 if (constantColorUsed && constantAlphaUsed)
4610 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004611 const char *msg;
4612 if (context->getExtensions().webglCompatibility)
4613 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004614 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004615 }
4616 else
4617 {
4618 msg =
4619 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4620 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4621 "implementation.";
4622 ERR() << msg;
4623 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004624 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004625 return false;
4626 }
4627 }
4628
4629 return true;
4630}
4631
Geoff Langc339c4e2016-11-29 10:37:36 -05004632bool ValidateGetString(Context *context, GLenum name)
4633{
4634 switch (name)
4635 {
4636 case GL_VENDOR:
4637 case GL_RENDERER:
4638 case GL_VERSION:
4639 case GL_SHADING_LANGUAGE_VERSION:
4640 case GL_EXTENSIONS:
4641 break;
4642
4643 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4644 if (!context->getExtensions().requestExtension)
4645 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004646 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004647 return false;
4648 }
4649 break;
4650
4651 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004652 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004653 return false;
4654 }
4655
4656 return true;
4657}
4658
Jamie Madill5b772312018-03-08 20:28:32 -05004659bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004660{
4661 if (width <= 0.0f || isNaN(width))
4662 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004663 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004664 return false;
4665 }
4666
4667 return true;
4668}
4669
Jamie Madill5b772312018-03-08 20:28:32 -05004670bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004671 GLuint index,
4672 GLint size,
4673 GLenum type,
4674 GLboolean normalized,
4675 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004676 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004677{
Shao80957d92017-02-20 21:25:59 +08004678 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004679 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004680 return false;
4681 }
4682
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004683 if (stride < 0)
4684 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004685 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004686 return false;
4687 }
4688
Shao80957d92017-02-20 21:25:59 +08004689 const Caps &caps = context->getCaps();
4690 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004691 {
Shao80957d92017-02-20 21:25:59 +08004692 if (stride > caps.maxVertexAttribStride)
4693 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004694 context->handleError(InvalidValue()
4695 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004696 return false;
4697 }
4698
4699 if (index >= caps.maxVertexAttribBindings)
4700 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004701 context->handleError(InvalidValue()
4702 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004703 return false;
4704 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004705 }
4706
4707 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4708 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4709 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4710 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004711 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4712 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004713 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4714 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004716 context
4717 ->handleError(InvalidOperation()
4718 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004719 return false;
4720 }
4721
4722 if (context->getExtensions().webglCompatibility)
4723 {
4724 // WebGL 1.0 [Section 6.14] Fixed point support
4725 // The WebGL API does not support the GL_FIXED data type.
4726 if (type == GL_FIXED)
4727 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004728 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004729 return false;
4730 }
4731
Geoff Lang2d62ab72017-03-23 16:54:40 -04004732 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004733 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004734 return false;
4735 }
4736 }
4737
4738 return true;
4739}
4740
Jamie Madill5b772312018-03-08 20:28:32 -05004741bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004742{
4743 if (context->getExtensions().webglCompatibility && zNear > zFar)
4744 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004745 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004746 return false;
4747 }
4748
4749 return true;
4750}
4751
Jamie Madill5b772312018-03-08 20:28:32 -05004752bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004753 GLenum target,
4754 GLenum internalformat,
4755 GLsizei width,
4756 GLsizei height)
4757{
4758 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4759 height);
4760}
4761
Jamie Madill5b772312018-03-08 20:28:32 -05004762bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004763 GLenum target,
4764 GLsizei samples,
4765 GLenum internalformat,
4766 GLsizei width,
4767 GLsizei height)
4768{
4769 if (!context->getExtensions().framebufferMultisample)
4770 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004771 context->handleError(InvalidOperation()
4772 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004773 return false;
4774 }
4775
4776 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4777 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4778 // generated.
4779 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004781 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004782 return false;
4783 }
4784
4785 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4786 // the specified storage. This is different than ES 3.0 in which a sample number higher
4787 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4788 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4789 if (context->getClientMajorVersion() >= 3)
4790 {
4791 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4792 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4793 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004794 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004795 return false;
4796 }
4797 }
4798
4799 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4800 width, height);
4801}
4802
Jamie Madill5b772312018-03-08 20:28:32 -05004803bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004804{
Geoff Lange8afa902017-09-27 15:00:43 -04004805 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004806 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004807 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004808 return false;
4809 }
4810
4811 return true;
4812}
4813
Jamie Madill5b772312018-03-08 20:28:32 -05004814bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004815{
4816 return true;
4817}
4818
Jamie Madill5b772312018-03-08 20:28:32 -05004819bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004820{
4821 return true;
4822}
4823
Jamie Madill5b772312018-03-08 20:28:32 -05004824bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004825{
4826 return true;
4827}
4828
Jamie Madill5b772312018-03-08 20:28:32 -05004829bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004830 GLboolean red,
4831 GLboolean green,
4832 GLboolean blue,
4833 GLboolean alpha)
4834{
4835 return true;
4836}
4837
Jamie Madill5b772312018-03-08 20:28:32 -05004838bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004839{
4840 return true;
4841}
4842
Jamie Madill5b772312018-03-08 20:28:32 -05004843bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004844{
4845 return true;
4846}
4847
Jamie Madill5b772312018-03-08 20:28:32 -05004848bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004849{
4850 switch (mode)
4851 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004852 case CullFaceMode::Front:
4853 case CullFaceMode::Back:
4854 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004855 break;
4856
4857 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004858 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004859 return false;
4860 }
4861
4862 return true;
4863}
4864
Jamie Madill5b772312018-03-08 20:28:32 -05004865bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004866{
4867 if (program == 0)
4868 {
4869 return false;
4870 }
4871
4872 if (!context->getProgram(program))
4873 {
4874 if (context->getShader(program))
4875 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004876 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004877 return false;
4878 }
4879 else
4880 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004881 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004882 return false;
4883 }
4884 }
4885
4886 return true;
4887}
4888
Jamie Madill5b772312018-03-08 20:28:32 -05004889bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004890{
4891 if (shader == 0)
4892 {
4893 return false;
4894 }
4895
4896 if (!context->getShader(shader))
4897 {
4898 if (context->getProgram(shader))
4899 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004900 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004901 return false;
4902 }
4903 else
4904 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004905 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004906 return false;
4907 }
4908 }
4909
4910 return true;
4911}
4912
Jamie Madill5b772312018-03-08 20:28:32 -05004913bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004914{
4915 switch (func)
4916 {
4917 case GL_NEVER:
4918 case GL_ALWAYS:
4919 case GL_LESS:
4920 case GL_LEQUAL:
4921 case GL_EQUAL:
4922 case GL_GREATER:
4923 case GL_GEQUAL:
4924 case GL_NOTEQUAL:
4925 break;
4926
4927 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004928 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004929 return false;
4930 }
4931
4932 return true;
4933}
4934
Jamie Madill5b772312018-03-08 20:28:32 -05004935bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004936{
4937 return true;
4938}
4939
Jamie Madill5b772312018-03-08 20:28:32 -05004940bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004941{
4942 Program *programObject = GetValidProgram(context, program);
4943 if (!programObject)
4944 {
4945 return false;
4946 }
4947
4948 Shader *shaderObject = GetValidShader(context, shader);
4949 if (!shaderObject)
4950 {
4951 return false;
4952 }
4953
Jiawei Shao385b3e02018-03-21 09:43:28 +08004954 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004955 if (attachedShader != shaderObject)
4956 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004957 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004958 return false;
4959 }
4960
4961 return true;
4962}
4963
Jamie Madill5b772312018-03-08 20:28:32 -05004964bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004965{
4966 if (index >= MAX_VERTEX_ATTRIBS)
4967 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004968 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004969 return false;
4970 }
4971
4972 return true;
4973}
4974
Jamie Madill5b772312018-03-08 20:28:32 -05004975bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004976{
4977 if (index >= MAX_VERTEX_ATTRIBS)
4978 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004979 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004980 return false;
4981 }
4982
4983 return true;
4984}
4985
Jamie Madill5b772312018-03-08 20:28:32 -05004986bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004987{
4988 return true;
4989}
4990
Jamie Madill5b772312018-03-08 20:28:32 -05004991bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004992{
4993 return true;
4994}
4995
Jamie Madill5b772312018-03-08 20:28:32 -05004996bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004997{
4998 switch (mode)
4999 {
5000 case GL_CW:
5001 case GL_CCW:
5002 break;
5003 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005004 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005005 return false;
5006 }
5007
5008 return true;
5009}
5010
Jamie Madill5b772312018-03-08 20:28:32 -05005011bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005012 GLuint program,
5013 GLuint index,
5014 GLsizei bufsize,
5015 GLsizei *length,
5016 GLint *size,
5017 GLenum *type,
5018 GLchar *name)
5019{
5020 if (bufsize < 0)
5021 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005022 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005023 return false;
5024 }
5025
5026 Program *programObject = GetValidProgram(context, program);
5027
5028 if (!programObject)
5029 {
5030 return false;
5031 }
5032
5033 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5034 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005035 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005036 return false;
5037 }
5038
5039 return true;
5040}
5041
Jamie Madill5b772312018-03-08 20:28:32 -05005042bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005043 GLuint program,
5044 GLuint index,
5045 GLsizei bufsize,
5046 GLsizei *length,
5047 GLint *size,
5048 GLenum *type,
5049 GLchar *name)
5050{
5051 if (bufsize < 0)
5052 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005053 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005054 return false;
5055 }
5056
5057 Program *programObject = GetValidProgram(context, program);
5058
5059 if (!programObject)
5060 {
5061 return false;
5062 }
5063
5064 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5065 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005066 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005067 return false;
5068 }
5069
5070 return true;
5071}
5072
Jamie Madill5b772312018-03-08 20:28:32 -05005073bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005074 GLuint program,
5075 GLsizei maxcount,
5076 GLsizei *count,
5077 GLuint *shaders)
5078{
5079 if (maxcount < 0)
5080 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005081 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005082 return false;
5083 }
5084
5085 Program *programObject = GetValidProgram(context, program);
5086
5087 if (!programObject)
5088 {
5089 return false;
5090 }
5091
5092 return true;
5093}
5094
Jamie Madill5b772312018-03-08 20:28:32 -05005095bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005096{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005097 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5098 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005099 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005100 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005101 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005102 return false;
5103 }
5104
Jamie Madillc1d770e2017-04-13 17:31:24 -04005105 Program *programObject = GetValidProgram(context, program);
5106
5107 if (!programObject)
5108 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005109 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110 return false;
5111 }
5112
5113 if (!programObject->isLinked())
5114 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005116 return false;
5117 }
5118
5119 return true;
5120}
5121
Jamie Madill5b772312018-03-08 20:28:32 -05005122bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005123{
5124 GLenum nativeType;
5125 unsigned int numParams = 0;
5126 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5127}
5128
Jamie Madill5b772312018-03-08 20:28:32 -05005129bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005130{
5131 return true;
5132}
5133
Jamie Madill5b772312018-03-08 20:28:32 -05005134bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005135{
5136 GLenum nativeType;
5137 unsigned int numParams = 0;
5138 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5139}
5140
Jamie Madill5b772312018-03-08 20:28:32 -05005141bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005142{
5143 GLenum nativeType;
5144 unsigned int numParams = 0;
5145 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5146}
5147
Jamie Madill5b772312018-03-08 20:28:32 -05005148bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149 GLuint program,
5150 GLsizei bufsize,
5151 GLsizei *length,
5152 GLchar *infolog)
5153{
5154 if (bufsize < 0)
5155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005156 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005157 return false;
5158 }
5159
5160 Program *programObject = GetValidProgram(context, program);
5161 if (!programObject)
5162 {
5163 return false;
5164 }
5165
5166 return true;
5167}
5168
Jamie Madill5b772312018-03-08 20:28:32 -05005169bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005170 GLuint shader,
5171 GLsizei bufsize,
5172 GLsizei *length,
5173 GLchar *infolog)
5174{
5175 if (bufsize < 0)
5176 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005177 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005178 return false;
5179 }
5180
5181 Shader *shaderObject = GetValidShader(context, shader);
5182 if (!shaderObject)
5183 {
5184 return false;
5185 }
5186
5187 return true;
5188}
5189
Jamie Madill5b772312018-03-08 20:28:32 -05005190bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005191 GLenum shadertype,
5192 GLenum precisiontype,
5193 GLint *range,
5194 GLint *precision)
5195{
5196 switch (shadertype)
5197 {
5198 case GL_VERTEX_SHADER:
5199 case GL_FRAGMENT_SHADER:
5200 break;
5201 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005202 context->handleError(InvalidOperation()
5203 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005204 return false;
5205 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005206 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005207 return false;
5208 }
5209
5210 switch (precisiontype)
5211 {
5212 case GL_LOW_FLOAT:
5213 case GL_MEDIUM_FLOAT:
5214 case GL_HIGH_FLOAT:
5215 case GL_LOW_INT:
5216 case GL_MEDIUM_INT:
5217 case GL_HIGH_INT:
5218 break;
5219
5220 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005221 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005222 return false;
5223 }
5224
5225 return true;
5226}
5227
Jamie Madill5b772312018-03-08 20:28:32 -05005228bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005229 GLuint shader,
5230 GLsizei bufsize,
5231 GLsizei *length,
5232 GLchar *source)
5233{
5234 if (bufsize < 0)
5235 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005236 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005237 return false;
5238 }
5239
5240 Shader *shaderObject = GetValidShader(context, shader);
5241 if (!shaderObject)
5242 {
5243 return false;
5244 }
5245
5246 return true;
5247}
5248
Jamie Madill5b772312018-03-08 20:28:32 -05005249bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005250{
5251 if (strstr(name, "gl_") == name)
5252 {
5253 return false;
5254 }
5255
Geoff Langfc32e8b2017-05-31 14:16:59 -04005256 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5257 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005258 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005259 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005260 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005261 return false;
5262 }
5263
Jamie Madillc1d770e2017-04-13 17:31:24 -04005264 Program *programObject = GetValidProgram(context, program);
5265
5266 if (!programObject)
5267 {
5268 return false;
5269 }
5270
5271 if (!programObject->isLinked())
5272 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005273 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005274 return false;
5275 }
5276
5277 return true;
5278}
5279
Jamie Madill5b772312018-03-08 20:28:32 -05005280bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005281{
5282 switch (mode)
5283 {
5284 case GL_FASTEST:
5285 case GL_NICEST:
5286 case GL_DONT_CARE:
5287 break;
5288
5289 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005290 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005291 return false;
5292 }
5293
5294 switch (target)
5295 {
5296 case GL_GENERATE_MIPMAP_HINT:
5297 break;
5298
Geoff Lange7bd2182017-06-16 16:13:13 -04005299 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5300 if (context->getClientVersion() < ES_3_0 &&
5301 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005302 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005303 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005304 return false;
5305 }
5306 break;
5307
5308 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005309 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005310 return false;
5311 }
5312
5313 return true;
5314}
5315
Jamie Madill5b772312018-03-08 20:28:32 -05005316bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005317{
5318 return true;
5319}
5320
Jamie Madill5b772312018-03-08 20:28:32 -05005321bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005322{
5323 return true;
5324}
5325
Jamie Madill5b772312018-03-08 20:28:32 -05005326bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005327{
5328 return true;
5329}
5330
Jamie Madill5b772312018-03-08 20:28:32 -05005331bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005332{
5333 return true;
5334}
5335
Jamie Madill5b772312018-03-08 20:28:32 -05005336bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005337{
5338 return true;
5339}
5340
Jamie Madill5b772312018-03-08 20:28:32 -05005341bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005342{
5343 return true;
5344}
5345
Jamie Madill5b772312018-03-08 20:28:32 -05005346bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347{
5348 if (context->getClientMajorVersion() < 3)
5349 {
5350 switch (pname)
5351 {
5352 case GL_UNPACK_IMAGE_HEIGHT:
5353 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005354 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005355 return false;
5356
5357 case GL_UNPACK_ROW_LENGTH:
5358 case GL_UNPACK_SKIP_ROWS:
5359 case GL_UNPACK_SKIP_PIXELS:
5360 if (!context->getExtensions().unpackSubimage)
5361 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005362 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005363 return false;
5364 }
5365 break;
5366
5367 case GL_PACK_ROW_LENGTH:
5368 case GL_PACK_SKIP_ROWS:
5369 case GL_PACK_SKIP_PIXELS:
5370 if (!context->getExtensions().packSubimage)
5371 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005372 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005373 return false;
5374 }
5375 break;
5376 }
5377 }
5378
5379 if (param < 0)
5380 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005381 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005382 return false;
5383 }
5384
5385 switch (pname)
5386 {
5387 case GL_UNPACK_ALIGNMENT:
5388 if (param != 1 && param != 2 && param != 4 && param != 8)
5389 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005390 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005391 return false;
5392 }
5393 break;
5394
5395 case GL_PACK_ALIGNMENT:
5396 if (param != 1 && param != 2 && param != 4 && param != 8)
5397 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005398 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005399 return false;
5400 }
5401 break;
5402
5403 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005404 if (!context->getExtensions().packReverseRowOrder)
5405 {
5406 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5407 }
5408 break;
5409
Jamie Madillc1d770e2017-04-13 17:31:24 -04005410 case GL_UNPACK_ROW_LENGTH:
5411 case GL_UNPACK_IMAGE_HEIGHT:
5412 case GL_UNPACK_SKIP_IMAGES:
5413 case GL_UNPACK_SKIP_ROWS:
5414 case GL_UNPACK_SKIP_PIXELS:
5415 case GL_PACK_ROW_LENGTH:
5416 case GL_PACK_SKIP_ROWS:
5417 case GL_PACK_SKIP_PIXELS:
5418 break;
5419
5420 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005421 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005422 return false;
5423 }
5424
5425 return true;
5426}
5427
Jamie Madill5b772312018-03-08 20:28:32 -05005428bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005429{
5430 return true;
5431}
5432
Jamie Madill5b772312018-03-08 20:28:32 -05005433bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005434{
5435 return true;
5436}
5437
Jamie Madill5b772312018-03-08 20:28:32 -05005438bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005439{
5440 return true;
5441}
5442
Jamie Madill5b772312018-03-08 20:28:32 -05005443bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444{
5445 if (width < 0 || height < 0)
5446 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005447 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005448 return false;
5449 }
5450
5451 return true;
5452}
5453
Jamie Madill5b772312018-03-08 20:28:32 -05005454bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005455 GLsizei n,
5456 const GLuint *shaders,
5457 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005458 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005459 GLsizei length)
5460{
5461 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5462 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5463 shaderBinaryFormats.end())
5464 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005465 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005466 return false;
5467 }
5468
5469 return true;
5470}
5471
Jamie Madill5b772312018-03-08 20:28:32 -05005472bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005473 GLuint shader,
5474 GLsizei count,
5475 const GLchar *const *string,
5476 const GLint *length)
5477{
5478 if (count < 0)
5479 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005480 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005481 return false;
5482 }
5483
Geoff Langfc32e8b2017-05-31 14:16:59 -04005484 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5485 // shader-related entry points
5486 if (context->getExtensions().webglCompatibility)
5487 {
5488 for (GLsizei i = 0; i < count; i++)
5489 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005490 size_t len =
5491 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005492
5493 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005494 if (!IsValidESSLShaderSourceString(string[i], len,
5495 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005496 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005497 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005498 return false;
5499 }
5500 }
5501 }
5502
Jamie Madillc1d770e2017-04-13 17:31:24 -04005503 Shader *shaderObject = GetValidShader(context, shader);
5504 if (!shaderObject)
5505 {
5506 return false;
5507 }
5508
5509 return true;
5510}
5511
Jamie Madill5b772312018-03-08 20:28:32 -05005512bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005513{
5514 if (!IsValidStencilFunc(func))
5515 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005516 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005517 return false;
5518 }
5519
5520 return true;
5521}
5522
Jamie Madill5b772312018-03-08 20:28:32 -05005523bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005524{
5525 if (!IsValidStencilFace(face))
5526 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005527 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005528 return false;
5529 }
5530
5531 if (!IsValidStencilFunc(func))
5532 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005533 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005534 return false;
5535 }
5536
5537 return true;
5538}
5539
Jamie Madill5b772312018-03-08 20:28:32 -05005540bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005541{
5542 return true;
5543}
5544
Jamie Madill5b772312018-03-08 20:28:32 -05005545bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005546{
5547 if (!IsValidStencilFace(face))
5548 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005549 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005550 return false;
5551 }
5552
5553 return true;
5554}
5555
Jamie Madill5b772312018-03-08 20:28:32 -05005556bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005557{
5558 if (!IsValidStencilOp(fail))
5559 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005560 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005561 return false;
5562 }
5563
5564 if (!IsValidStencilOp(zfail))
5565 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005566 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005567 return false;
5568 }
5569
5570 if (!IsValidStencilOp(zpass))
5571 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005572 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005573 return false;
5574 }
5575
5576 return true;
5577}
5578
Jamie Madill5b772312018-03-08 20:28:32 -05005579bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580 GLenum face,
5581 GLenum fail,
5582 GLenum zfail,
5583 GLenum zpass)
5584{
5585 if (!IsValidStencilFace(face))
5586 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005587 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005588 return false;
5589 }
5590
5591 return ValidateStencilOp(context, fail, zfail, zpass);
5592}
5593
Jamie Madill5b772312018-03-08 20:28:32 -05005594bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005595{
5596 return ValidateUniform(context, GL_FLOAT, location, 1);
5597}
5598
Jamie Madill5b772312018-03-08 20:28:32 -05005599bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005600{
5601 return ValidateUniform(context, GL_FLOAT, location, count);
5602}
5603
Jamie Madill5b772312018-03-08 20:28:32 -05005604bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005605{
5606 return ValidateUniform1iv(context, location, 1, &x);
5607}
5608
Jamie Madill5b772312018-03-08 20:28:32 -05005609bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005610{
5611 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5612}
5613
Jamie Madill5b772312018-03-08 20:28:32 -05005614bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005615{
5616 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5617}
5618
Jamie Madill5b772312018-03-08 20:28:32 -05005619bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005620{
5621 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5622}
5623
Jamie Madill5b772312018-03-08 20:28:32 -05005624bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005625{
5626 return ValidateUniform(context, GL_INT_VEC2, location, count);
5627}
5628
Jamie Madill5b772312018-03-08 20:28:32 -05005629bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005630{
5631 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5632}
5633
Jamie Madill5b772312018-03-08 20:28:32 -05005634bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005635{
5636 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5637}
5638
Jamie Madill5b772312018-03-08 20:28:32 -05005639bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005640{
5641 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5642}
5643
Jamie Madill5b772312018-03-08 20:28:32 -05005644bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005645{
5646 return ValidateUniform(context, GL_INT_VEC3, location, count);
5647}
5648
Jamie Madill5b772312018-03-08 20:28:32 -05005649bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650{
5651 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655{
5656 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5657}
5658
Jamie Madill5b772312018-03-08 20:28:32 -05005659bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005660{
5661 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5662}
5663
Jamie Madill5b772312018-03-08 20:28:32 -05005664bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005665{
5666 return ValidateUniform(context, GL_INT_VEC4, location, count);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670 GLint location,
5671 GLsizei count,
5672 GLboolean transpose,
5673 const GLfloat *value)
5674{
5675 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5676}
5677
Jamie Madill5b772312018-03-08 20:28:32 -05005678bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005679 GLint location,
5680 GLsizei count,
5681 GLboolean transpose,
5682 const GLfloat *value)
5683{
5684 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5685}
5686
Jamie Madill5b772312018-03-08 20:28:32 -05005687bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005688 GLint location,
5689 GLsizei count,
5690 GLboolean transpose,
5691 const GLfloat *value)
5692{
5693 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5694}
5695
Jamie Madill5b772312018-03-08 20:28:32 -05005696bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005697{
5698 Program *programObject = GetValidProgram(context, program);
5699
5700 if (!programObject)
5701 {
5702 return false;
5703 }
5704
5705 return true;
5706}
5707
Jamie Madill5b772312018-03-08 20:28:32 -05005708bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005709{
5710 return ValidateVertexAttribIndex(context, index);
5711}
5712
Jamie Madill5b772312018-03-08 20:28:32 -05005713bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005714{
5715 return ValidateVertexAttribIndex(context, index);
5716}
5717
Jamie Madill5b772312018-03-08 20:28:32 -05005718bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005719{
5720 return ValidateVertexAttribIndex(context, index);
5721}
5722
Jamie Madill5b772312018-03-08 20:28:32 -05005723bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005724{
5725 return ValidateVertexAttribIndex(context, index);
5726}
5727
Jamie Madill5b772312018-03-08 20:28:32 -05005728bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005729{
5730 return ValidateVertexAttribIndex(context, index);
5731}
5732
Jamie Madill5b772312018-03-08 20:28:32 -05005733bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005734{
5735 return ValidateVertexAttribIndex(context, index);
5736}
5737
Jamie Madill5b772312018-03-08 20:28:32 -05005738bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005739 GLuint index,
5740 GLfloat x,
5741 GLfloat y,
5742 GLfloat z,
5743 GLfloat w)
5744{
5745 return ValidateVertexAttribIndex(context, index);
5746}
5747
Jamie Madill5b772312018-03-08 20:28:32 -05005748bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005749{
5750 return ValidateVertexAttribIndex(context, index);
5751}
5752
Jamie Madill5b772312018-03-08 20:28:32 -05005753bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005754{
5755 if (width < 0 || height < 0)
5756 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005757 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005758 return false;
5759 }
5760
5761 return true;
5762}
5763
Jamie Madill5b772312018-03-08 20:28:32 -05005764bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005765{
5766 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5767}
5768
Jamie Madill5b772312018-03-08 20:28:32 -05005769bool ValidateDrawElements(Context *context,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005770 GLenum mode,
5771 GLsizei count,
5772 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005773 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005774{
5775 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5776}
5777
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005778bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005779 GLenum target,
5780 GLenum attachment,
5781 GLenum pname,
5782 GLint *params)
5783{
5784 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5785 nullptr);
5786}
5787
Jamie Madill5b772312018-03-08 20:28:32 -05005788bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005789{
5790 return ValidateGetProgramivBase(context, program, pname, nullptr);
5791}
5792
Jamie Madill5b772312018-03-08 20:28:32 -05005793bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005794 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005795 GLint level,
5796 GLenum internalformat,
5797 GLint x,
5798 GLint y,
5799 GLsizei width,
5800 GLsizei height,
5801 GLint border)
5802{
5803 if (context->getClientMajorVersion() < 3)
5804 {
5805 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5806 0, x, y, width, height, border);
5807 }
5808
5809 ASSERT(context->getClientMajorVersion() == 3);
5810 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5811 0, x, y, width, height, border);
5812}
5813
5814bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005815 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005816 GLint level,
5817 GLint xoffset,
5818 GLint yoffset,
5819 GLint x,
5820 GLint y,
5821 GLsizei width,
5822 GLsizei height)
5823{
5824 if (context->getClientMajorVersion() < 3)
5825 {
5826 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5827 yoffset, x, y, width, height, 0);
5828 }
5829
5830 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5831 yoffset, 0, x, y, width, height, 0);
5832}
5833
5834bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5835{
5836 return ValidateGenOrDelete(context, n);
5837}
5838
5839bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5840{
5841 return ValidateGenOrDelete(context, n);
5842}
5843
5844bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5845{
5846 return ValidateGenOrDelete(context, n);
5847}
5848
5849bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5850{
5851 return ValidateGenOrDelete(context, n);
5852}
5853
5854bool ValidateDisable(Context *context, GLenum cap)
5855{
5856 if (!ValidCap(context, cap, false))
5857 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005858 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005859 return false;
5860 }
5861
5862 return true;
5863}
5864
5865bool ValidateEnable(Context *context, GLenum cap)
5866{
5867 if (!ValidCap(context, cap, false))
5868 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005869 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005870 return false;
5871 }
5872
5873 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5874 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5875 {
5876 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005877 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005878
5879 // We also output an error message to the debugger window if tracing is active, so that
5880 // developers can see the error message.
5881 ERR() << errorMessage;
5882 return false;
5883 }
5884
5885 return true;
5886}
5887
5888bool ValidateFramebufferRenderbuffer(Context *context,
5889 GLenum target,
5890 GLenum attachment,
5891 GLenum renderbuffertarget,
5892 GLuint renderbuffer)
5893{
Geoff Lange8afa902017-09-27 15:00:43 -04005894 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005895 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005896 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5897 return false;
5898 }
5899
5900 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5901 {
5902 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005903 return false;
5904 }
5905
5906 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5907 renderbuffertarget, renderbuffer);
5908}
5909
5910bool ValidateFramebufferTexture2D(Context *context,
5911 GLenum target,
5912 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005913 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005914 GLuint texture,
5915 GLint level)
5916{
5917 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5918 // extension
5919 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5920 level != 0)
5921 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005922 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005923 return false;
5924 }
5925
5926 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5927 {
5928 return false;
5929 }
5930
5931 if (texture != 0)
5932 {
5933 gl::Texture *tex = context->getTexture(texture);
5934 ASSERT(tex);
5935
5936 const gl::Caps &caps = context->getCaps();
5937
5938 switch (textarget)
5939 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005940 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005941 {
5942 if (level > gl::log2(caps.max2DTextureSize))
5943 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005944 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005945 return false;
5946 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005947 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005948 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005949 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005950 return false;
5951 }
5952 }
5953 break;
5954
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005955 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005956 {
5957 if (level != 0)
5958 {
5959 context->handleError(InvalidValue());
5960 return false;
5961 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005962 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005963 {
5964 context->handleError(InvalidOperation()
5965 << "Textarget must match the texture target type.");
5966 return false;
5967 }
5968 }
5969 break;
5970
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005971 case TextureTarget::CubeMapNegativeX:
5972 case TextureTarget::CubeMapNegativeY:
5973 case TextureTarget::CubeMapNegativeZ:
5974 case TextureTarget::CubeMapPositiveX:
5975 case TextureTarget::CubeMapPositiveY:
5976 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005977 {
5978 if (level > gl::log2(caps.maxCubeMapTextureSize))
5979 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005980 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005981 return false;
5982 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005983 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04005984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005985 context->handleError(InvalidOperation()
5986 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005987 return false;
5988 }
5989 }
5990 break;
5991
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005992 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04005993 {
5994 if (context->getClientVersion() < ES_3_1)
5995 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005996 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005997 return false;
5998 }
5999
6000 if (level != 0)
6001 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006002 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006003 return false;
6004 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006005 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006007 context->handleError(InvalidOperation()
6008 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006009 return false;
6010 }
6011 }
6012 break;
6013
6014 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006015 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006016 return false;
6017 }
6018
6019 const Format &format = tex->getFormat(textarget, level);
6020 if (format.info->compressed)
6021 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006022 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006023 return false;
6024 }
6025 }
6026
6027 return true;
6028}
6029
6030bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6031{
6032 return ValidateGenOrDelete(context, n);
6033}
6034
6035bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6036{
6037 return ValidateGenOrDelete(context, n);
6038}
6039
6040bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6041{
6042 return ValidateGenOrDelete(context, n);
6043}
6044
6045bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6046{
6047 return ValidateGenOrDelete(context, n);
6048}
6049
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006050bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006051{
6052 if (!ValidTextureTarget(context, target))
6053 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006054 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006055 return false;
6056 }
6057
6058 Texture *texture = context->getTargetTexture(target);
6059
6060 if (texture == nullptr)
6061 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006062 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006063 return false;
6064 }
6065
6066 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6067
6068 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6069 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6070 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006072 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006073 return false;
6074 }
6075
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006076 TextureTarget baseTarget = (target == TextureType::CubeMap)
6077 ? TextureTarget::CubeMapPositiveX
6078 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006079 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6080 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6081 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006082 {
6083 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6084 return false;
6085 }
6086
Geoff Lang536eca12017-09-13 11:23:35 -04006087 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6088 bool formatUnsized = !format.sized;
6089 bool formatColorRenderableAndFilterable =
6090 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6091 format.renderSupport(context->getClientVersion(), context->getExtensions());
6092 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006093 {
Geoff Lang536eca12017-09-13 11:23:35 -04006094 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006095 return false;
6096 }
6097
Geoff Lang536eca12017-09-13 11:23:35 -04006098 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6099 // generation
6100 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6101 {
6102 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6103 return false;
6104 }
6105
6106 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6107 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006108 bool supportsSRGBMipmapGeneration =
6109 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006110 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006111 {
Geoff Lang536eca12017-09-13 11:23:35 -04006112 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006113 return false;
6114 }
6115
6116 // Non-power of 2 ES2 check
6117 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6118 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6119 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6120 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006121 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6122 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006123 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006124 return false;
6125 }
6126
6127 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006128 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006129 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006130 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006131 return false;
6132 }
6133
6134 return true;
6135}
6136
Jamie Madill5b772312018-03-08 20:28:32 -05006137bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006138 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006139 GLenum pname,
6140 GLint *params)
6141{
6142 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6143}
6144
6145bool ValidateGetRenderbufferParameteriv(Context *context,
6146 GLenum target,
6147 GLenum pname,
6148 GLint *params)
6149{
6150 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6151}
6152
6153bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6154{
6155 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6156}
6157
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006158bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006159{
6160 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6161}
6162
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006163bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006164{
6165 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6166}
6167
6168bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6169{
6170 return ValidateGetUniformBase(context, program, location);
6171}
6172
6173bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6174{
6175 return ValidateGetUniformBase(context, program, location);
6176}
6177
6178bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6179{
6180 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6181}
6182
6183bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6184{
6185 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6186}
6187
6188bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6189{
6190 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6191}
6192
6193bool ValidateIsEnabled(Context *context, GLenum cap)
6194{
6195 if (!ValidCap(context, cap, true))
6196 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006197 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006198 return false;
6199 }
6200
6201 return true;
6202}
6203
6204bool ValidateLinkProgram(Context *context, GLuint program)
6205{
6206 if (context->hasActiveTransformFeedback(program))
6207 {
6208 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006209 context->handleError(InvalidOperation() << "Cannot link program while program is "
6210 "associated with an active transform "
6211 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006212 return false;
6213 }
6214
6215 Program *programObject = GetValidProgram(context, program);
6216 if (!programObject)
6217 {
6218 return false;
6219 }
6220
6221 return true;
6222}
6223
Jamie Madill4928b7c2017-06-20 12:57:39 -04006224bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006225 GLint x,
6226 GLint y,
6227 GLsizei width,
6228 GLsizei height,
6229 GLenum format,
6230 GLenum type,
6231 void *pixels)
6232{
6233 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6234 nullptr, pixels);
6235}
6236
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006237bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006238{
6239 return ValidateTexParameterBase(context, target, pname, -1, &param);
6240}
6241
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006242bool ValidateTexParameterfv(Context *context,
6243 TextureType target,
6244 GLenum pname,
6245 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006246{
6247 return ValidateTexParameterBase(context, target, pname, -1, params);
6248}
6249
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006250bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006251{
6252 return ValidateTexParameterBase(context, target, pname, -1, &param);
6253}
6254
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006255bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006256{
6257 return ValidateTexParameterBase(context, target, pname, -1, params);
6258}
6259
6260bool ValidateUseProgram(Context *context, GLuint program)
6261{
6262 if (program != 0)
6263 {
6264 Program *programObject = context->getProgram(program);
6265 if (!programObject)
6266 {
6267 // ES 3.1.0 section 7.3 page 72
6268 if (context->getShader(program))
6269 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006270 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006271 return false;
6272 }
6273 else
6274 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006275 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006276 return false;
6277 }
6278 }
6279 if (!programObject->isLinked())
6280 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006281 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006282 return false;
6283 }
6284 }
6285 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6286 {
6287 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006288 context
6289 ->handleError(InvalidOperation()
6290 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006291 return false;
6292 }
6293
6294 return true;
6295}
6296
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006297bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6298{
6299 if (!context->getExtensions().fence)
6300 {
6301 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6302 return false;
6303 }
6304
6305 if (n < 0)
6306 {
6307 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6308 return false;
6309 }
6310
6311 return true;
6312}
6313
6314bool ValidateFinishFenceNV(Context *context, GLuint fence)
6315{
6316 if (!context->getExtensions().fence)
6317 {
6318 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6319 return false;
6320 }
6321
6322 FenceNV *fenceObject = context->getFenceNV(fence);
6323
6324 if (fenceObject == nullptr)
6325 {
6326 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6327 return false;
6328 }
6329
6330 if (!fenceObject->isSet())
6331 {
6332 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6333 return false;
6334 }
6335
6336 return true;
6337}
6338
6339bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6340{
6341 if (!context->getExtensions().fence)
6342 {
6343 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6344 return false;
6345 }
6346
6347 if (n < 0)
6348 {
6349 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6350 return false;
6351 }
6352
6353 return true;
6354}
6355
6356bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6357{
6358 if (!context->getExtensions().fence)
6359 {
6360 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6361 return false;
6362 }
6363
6364 FenceNV *fenceObject = context->getFenceNV(fence);
6365
6366 if (fenceObject == nullptr)
6367 {
6368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6369 return false;
6370 }
6371
6372 if (!fenceObject->isSet())
6373 {
6374 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6375 return false;
6376 }
6377
6378 switch (pname)
6379 {
6380 case GL_FENCE_STATUS_NV:
6381 case GL_FENCE_CONDITION_NV:
6382 break;
6383
6384 default:
6385 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6386 return false;
6387 }
6388
6389 return true;
6390}
6391
6392bool ValidateGetGraphicsResetStatusEXT(Context *context)
6393{
6394 if (!context->getExtensions().robustness)
6395 {
6396 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6397 return false;
6398 }
6399
6400 return true;
6401}
6402
6403bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6404 GLuint shader,
6405 GLsizei bufsize,
6406 GLsizei *length,
6407 GLchar *source)
6408{
6409 if (!context->getExtensions().translatedShaderSource)
6410 {
6411 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6412 return false;
6413 }
6414
6415 if (bufsize < 0)
6416 {
6417 context->handleError(InvalidValue());
6418 return false;
6419 }
6420
6421 Shader *shaderObject = context->getShader(shader);
6422
6423 if (!shaderObject)
6424 {
6425 context->handleError(InvalidOperation());
6426 return false;
6427 }
6428
6429 return true;
6430}
6431
6432bool ValidateIsFenceNV(Context *context, GLuint fence)
6433{
6434 if (!context->getExtensions().fence)
6435 {
6436 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6437 return false;
6438 }
6439
6440 return true;
6441}
6442
Jamie Madill007530e2017-12-28 14:27:04 -05006443bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6444{
6445 if (!context->getExtensions().fence)
6446 {
6447 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6448 return false;
6449 }
6450
6451 if (condition != GL_ALL_COMPLETED_NV)
6452 {
6453 context->handleError(InvalidEnum());
6454 return false;
6455 }
6456
6457 FenceNV *fenceObject = context->getFenceNV(fence);
6458
6459 if (fenceObject == nullptr)
6460 {
6461 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6462 return false;
6463 }
6464
6465 return true;
6466}
6467
6468bool ValidateTestFenceNV(Context *context, GLuint fence)
6469{
6470 if (!context->getExtensions().fence)
6471 {
6472 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6473 return false;
6474 }
6475
6476 FenceNV *fenceObject = context->getFenceNV(fence);
6477
6478 if (fenceObject == nullptr)
6479 {
6480 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6481 return false;
6482 }
6483
6484 if (fenceObject->isSet() != GL_TRUE)
6485 {
6486 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6487 return false;
6488 }
6489
6490 return true;
6491}
6492
6493bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006494 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006495 GLsizei levels,
6496 GLenum internalformat,
6497 GLsizei width,
6498 GLsizei height)
6499{
6500 if (!context->getExtensions().textureStorage)
6501 {
6502 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6503 return false;
6504 }
6505
6506 if (context->getClientMajorVersion() < 3)
6507 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006508 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006509 height);
6510 }
6511
6512 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006513 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006514 1);
6515}
6516
6517bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6518{
6519 if (!context->getExtensions().instancedArrays)
6520 {
6521 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6522 return false;
6523 }
6524
6525 if (index >= MAX_VERTEX_ATTRIBS)
6526 {
6527 context->handleError(InvalidValue());
6528 return false;
6529 }
6530
6531 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6532 {
6533 if (index == 0 && divisor != 0)
6534 {
6535 const char *errorMessage =
6536 "The current context doesn't support setting a non-zero divisor on the "
6537 "attribute with index zero. "
6538 "Please reorder the attributes in your vertex shader so that attribute zero "
6539 "can have a zero divisor.";
6540 context->handleError(InvalidOperation() << errorMessage);
6541
6542 // We also output an error message to the debugger window if tracing is active, so
6543 // that developers can see the error message.
6544 ERR() << errorMessage;
6545 return false;
6546 }
6547 }
6548
6549 return true;
6550}
6551
6552bool ValidateTexImage3DOES(Context *context,
6553 GLenum target,
6554 GLint level,
6555 GLenum internalformat,
6556 GLsizei width,
6557 GLsizei height,
6558 GLsizei depth,
6559 GLint border,
6560 GLenum format,
6561 GLenum type,
6562 const void *pixels)
6563{
6564 UNIMPLEMENTED(); // FIXME
6565 return false;
6566}
6567
6568bool ValidatePopGroupMarkerEXT(Context *context)
6569{
6570 if (!context->getExtensions().debugMarker)
6571 {
6572 // The debug marker calls should not set error state
6573 // However, it seems reasonable to set an error state if the extension is not enabled
6574 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6575 return false;
6576 }
6577
6578 return true;
6579}
6580
Jamie Madillfa920eb2018-01-04 11:45:50 -05006581bool ValidateTexStorage1DEXT(Context *context,
6582 GLenum target,
6583 GLsizei levels,
6584 GLenum internalformat,
6585 GLsizei width)
6586{
6587 UNIMPLEMENTED();
6588 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6589 return false;
6590}
6591
6592bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006593 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006594 GLsizei levels,
6595 GLenum internalformat,
6596 GLsizei width,
6597 GLsizei height,
6598 GLsizei depth)
6599{
6600 if (!context->getExtensions().textureStorage)
6601 {
6602 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6603 return false;
6604 }
6605
6606 if (context->getClientMajorVersion() < 3)
6607 {
6608 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6609 return false;
6610 }
6611
6612 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6613 depth);
6614}
6615
Jamie Madillc29968b2016-01-20 11:17:23 -05006616} // namespace gl