blob: 45c88581088cfb950373dd73648feda6271a4808 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070078 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030079 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madill5b772312018-03-08 20:28:32 -0500458bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700795 // GLES1 emulation: GLES1-specific caps
796 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700797 case GL_VERTEX_ARRAY:
798 case GL_NORMAL_ARRAY:
799 case GL_COLOR_ARRAY:
800 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700801 case GL_TEXTURE_2D:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700802 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700803 case GL_POINT_SIZE_ARRAY_OES:
804 return context->getClientVersion() < Version(2, 0) &&
805 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700806 case GL_TEXTURE_CUBE_MAP:
807 return context->getClientVersion() < Version(2, 0) &&
808 context->getExtensions().textureCubeMap;
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700809
Jamie Madillbe849e42017-05-02 15:49:00 -0400810 default:
811 return false;
812 }
813}
814
Geoff Langfc32e8b2017-05-31 14:16:59 -0400815// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
816// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400817bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400818{
819 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400820 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
821 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400822 {
823 return true;
824 }
825
826 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
827 if (c >= 9 && c <= 13)
828 {
829 return true;
830 }
831
832 return false;
833}
834
Geoff Langcab92ee2017-07-19 17:32:07 -0400835bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400836{
Geoff Langa71a98e2017-06-19 15:15:00 -0400837 for (size_t i = 0; i < len; i++)
838 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400839 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400840 {
841 return false;
842 }
843 }
844
845 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400846}
847
Geoff Langcab92ee2017-07-19 17:32:07 -0400848bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
849{
850 enum class ParseState
851 {
852 // Have not seen an ASCII non-whitespace character yet on
853 // this line. Possible that we might see a preprocessor
854 // directive.
855 BEGINING_OF_LINE,
856
857 // Have seen at least one ASCII non-whitespace character
858 // on this line.
859 MIDDLE_OF_LINE,
860
861 // Handling a preprocessor directive. Passes through all
862 // characters up to the end of the line. Disables comment
863 // processing.
864 IN_PREPROCESSOR_DIRECTIVE,
865
866 // Handling a single-line comment. The comment text is
867 // replaced with a single space.
868 IN_SINGLE_LINE_COMMENT,
869
870 // Handling a multi-line comment. Newlines are passed
871 // through to preserve line numbers.
872 IN_MULTI_LINE_COMMENT
873 };
874
875 ParseState state = ParseState::BEGINING_OF_LINE;
876 size_t pos = 0;
877
878 while (pos < len)
879 {
880 char c = str[pos];
881 char next = pos + 1 < len ? str[pos + 1] : 0;
882
883 // Check for newlines
884 if (c == '\n' || c == '\r')
885 {
886 if (state != ParseState::IN_MULTI_LINE_COMMENT)
887 {
888 state = ParseState::BEGINING_OF_LINE;
889 }
890
891 pos++;
892 continue;
893 }
894
895 switch (state)
896 {
897 case ParseState::BEGINING_OF_LINE:
898 if (c == ' ')
899 {
900 // Maintain the BEGINING_OF_LINE state until a non-space is seen
901 pos++;
902 }
903 else if (c == '#')
904 {
905 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
906 pos++;
907 }
908 else
909 {
910 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
911 state = ParseState::MIDDLE_OF_LINE;
912 }
913 break;
914
915 case ParseState::MIDDLE_OF_LINE:
916 if (c == '/' && next == '/')
917 {
918 state = ParseState::IN_SINGLE_LINE_COMMENT;
919 pos++;
920 }
921 else if (c == '/' && next == '*')
922 {
923 state = ParseState::IN_MULTI_LINE_COMMENT;
924 pos++;
925 }
926 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
927 {
928 // Skip line continuation characters
929 }
930 else if (!IsValidESSLCharacter(c))
931 {
932 return false;
933 }
934 pos++;
935 break;
936
937 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700938 // Line-continuation characters may not be permitted.
939 // Otherwise, just pass it through. Do not parse comments in this state.
940 if (!lineContinuationAllowed && c == '\\')
941 {
942 return false;
943 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400944 pos++;
945 break;
946
947 case ParseState::IN_SINGLE_LINE_COMMENT:
948 // Line-continuation characters are processed before comment processing.
949 // Advance string if a new line character is immediately behind
950 // line-continuation character.
951 if (c == '\\' && (next == '\n' || next == '\r'))
952 {
953 pos++;
954 }
955 pos++;
956 break;
957
958 case ParseState::IN_MULTI_LINE_COMMENT:
959 if (c == '*' && next == '/')
960 {
961 state = ParseState::MIDDLE_OF_LINE;
962 pos++;
963 }
964 pos++;
965 break;
966 }
967 }
968
969 return true;
970}
971
Jamie Madill5b772312018-03-08 20:28:32 -0500972bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700973{
974 ASSERT(context->isWebGL());
975
976 // WebGL 1.0 [Section 6.16] GLSL Constructs
977 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
978 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
979 {
980 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
981 return false;
982 }
983
984 return true;
985}
986
Jamie Madill5b772312018-03-08 20:28:32 -0500987bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700988{
989 ASSERT(context->isWebGL());
990
991 if (context->isWebGL1() && length > 256)
992 {
993 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
994 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
995 // locations.
996 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
997
998 return false;
999 }
1000 else if (length > 1024)
1001 {
1002 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1003 // uniform and attribute locations.
1004 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1005 return false;
1006 }
1007
1008 return true;
1009}
1010
Jamie Madill007530e2017-12-28 14:27:04 -05001011bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1012{
1013 if (!context->getExtensions().pathRendering)
1014 {
1015 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1016 return false;
1017 }
1018
1019 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1020 {
1021 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1022 return false;
1023 }
1024 return true;
1025}
Jamie Madillc29968b2016-01-20 11:17:23 -05001026} // anonymous namespace
1027
Geoff Langff5b2d52016-09-07 11:32:23 -04001028bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001029 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001030 GLint level,
1031 GLenum internalformat,
1032 bool isCompressed,
1033 bool isSubImage,
1034 GLint xoffset,
1035 GLint yoffset,
1036 GLsizei width,
1037 GLsizei height,
1038 GLint border,
1039 GLenum format,
1040 GLenum type,
1041 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001042 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001043{
Jamie Madill6f38f822014-06-06 17:12:20 -04001044 if (!ValidTexture2DDestinationTarget(context, target))
1045 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001046 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001047 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001048 }
1049
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001050 TextureType texType = TextureTargetToType(target);
1051 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001052 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001053 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001054 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001055 }
1056
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001057 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001058 {
1059 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1060 return false;
1061 }
1062
1063 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001064 std::numeric_limits<GLsizei>::max() - yoffset < height)
1065 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001066 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001067 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001068 }
1069
Geoff Lang6e898aa2017-06-02 11:17:26 -04001070 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1071 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1072 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1073 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1074 // case.
1075 bool nonEqualFormatsAllowed =
1076 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1077 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1078
1079 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001080 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001081 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001082 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001083 }
1084
Geoff Langaae65a42014-05-26 12:43:44 -04001085 const gl::Caps &caps = context->getCaps();
1086
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001087 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001088 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001089 case TextureType::_2D:
1090 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1091 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1092 {
1093 context->handleError(InvalidValue());
1094 return false;
1095 }
1096 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001097
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001098 case TextureType::Rectangle:
1099 ASSERT(level == 0);
1100 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1101 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1102 {
1103 context->handleError(InvalidValue());
1104 return false;
1105 }
1106 if (isCompressed)
1107 {
1108 context->handleError(InvalidEnum()
1109 << "Rectangle texture cannot have a compressed format.");
1110 return false;
1111 }
1112 break;
1113
1114 case TextureType::CubeMap:
1115 if (!isSubImage && width != height)
1116 {
1117 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1118 return false;
1119 }
1120
1121 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1122 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1123 {
1124 context->handleError(InvalidValue());
1125 return false;
1126 }
1127 break;
1128
1129 default:
1130 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001131 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001132 }
1133
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001134 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001135 if (!texture)
1136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001137 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001138 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001139 }
1140
Geoff Langa9be0dc2014-12-17 12:34:40 -05001141 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001142 {
Geoff Langca271392017-04-05 12:30:00 -04001143 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1144 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001145 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001146 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001147 return false;
1148 }
1149
Geoff Langa9be0dc2014-12-17 12:34:40 -05001150 if (format != GL_NONE)
1151 {
Geoff Langca271392017-04-05 12:30:00 -04001152 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1153 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001154 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001155 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001156 return false;
1157 }
1158 }
1159
1160 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1161 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001163 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001164 return false;
1165 }
Geoff Langfb052642017-10-24 13:42:09 -04001166
1167 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001168 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001169 {
1170 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1171 return false;
1172 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001173 }
1174 else
1175 {
Geoff Lang69cce582015-09-17 13:20:36 -04001176 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001177 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001178 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001179 return false;
1180 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001181 }
1182
1183 // Verify zero border
1184 if (border != 0)
1185 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001186 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001187 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001188 }
1189
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001190 if (isCompressed)
1191 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001192 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001193 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1194 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001195
1196 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1197
1198 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001199 {
Geoff Lange88e4542018-05-03 15:05:57 -04001200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1201 return false;
1202 }
1203
1204 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1205 context->getExtensions()))
1206 {
1207 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1208 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001209 }
Geoff Lang966c9402017-04-18 12:38:27 -04001210
1211 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001212 {
Geoff Lange88e4542018-05-03 15:05:57 -04001213 // From the OES_compressed_ETC1_RGB8_texture spec:
1214 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1215 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1216 // ETC1_RGB8_OES.
1217 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1218 {
1219 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1220 return false;
1221 }
1222
Geoff Lang966c9402017-04-18 12:38:27 -04001223 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1224 height, texture->getWidth(target, level),
1225 texture->getHeight(target, level)))
1226 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001227 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001228 return false;
1229 }
1230
1231 if (format != actualInternalFormat)
1232 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001233 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001234 return false;
1235 }
1236 }
1237 else
1238 {
1239 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001241 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001242 return false;
1243 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001244 }
1245 }
1246 else
1247 {
1248 // validate <type> by itself (used as secondary key below)
1249 switch (type)
1250 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001251 case GL_UNSIGNED_BYTE:
1252 case GL_UNSIGNED_SHORT_5_6_5:
1253 case GL_UNSIGNED_SHORT_4_4_4_4:
1254 case GL_UNSIGNED_SHORT_5_5_5_1:
1255 case GL_UNSIGNED_SHORT:
1256 case GL_UNSIGNED_INT:
1257 case GL_UNSIGNED_INT_24_8_OES:
1258 case GL_HALF_FLOAT_OES:
1259 case GL_FLOAT:
1260 break;
1261 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001262 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001263 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001264 }
1265
1266 // validate <format> + <type> combinations
1267 // - invalid <format> -> sets INVALID_ENUM
1268 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1269 switch (format)
1270 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001271 case GL_ALPHA:
1272 case GL_LUMINANCE:
1273 case GL_LUMINANCE_ALPHA:
1274 switch (type)
1275 {
1276 case GL_UNSIGNED_BYTE:
1277 case GL_FLOAT:
1278 case GL_HALF_FLOAT_OES:
1279 break;
1280 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001281 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001282 return false;
1283 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001284 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001285 case GL_RED:
1286 case GL_RG:
1287 if (!context->getExtensions().textureRG)
1288 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001289 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001290 return false;
1291 }
1292 switch (type)
1293 {
1294 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001295 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001296 case GL_FLOAT:
1297 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001298 if (!context->getExtensions().textureFloat)
1299 {
1300 context->handleError(InvalidEnum());
1301 return false;
1302 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 break;
1304 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001306 return false;
1307 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001308 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001309 case GL_RGB:
1310 switch (type)
1311 {
1312 case GL_UNSIGNED_BYTE:
1313 case GL_UNSIGNED_SHORT_5_6_5:
1314 case GL_FLOAT:
1315 case GL_HALF_FLOAT_OES:
1316 break;
1317 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001318 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001319 return false;
1320 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001321 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001322 case GL_RGBA:
1323 switch (type)
1324 {
1325 case GL_UNSIGNED_BYTE:
1326 case GL_UNSIGNED_SHORT_4_4_4_4:
1327 case GL_UNSIGNED_SHORT_5_5_5_1:
1328 case GL_FLOAT:
1329 case GL_HALF_FLOAT_OES:
1330 break;
1331 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001332 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001333 return false;
1334 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001335 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001336 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001337 if (!context->getExtensions().textureFormatBGRA8888)
1338 {
1339 context->handleError(InvalidEnum());
1340 return false;
1341 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001342 switch (type)
1343 {
1344 case GL_UNSIGNED_BYTE:
1345 break;
1346 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001347 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001348 return false;
1349 }
1350 break;
1351 case GL_SRGB_EXT:
1352 case GL_SRGB_ALPHA_EXT:
1353 if (!context->getExtensions().sRGB)
1354 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001355 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001356 return false;
1357 }
1358 switch (type)
1359 {
1360 case GL_UNSIGNED_BYTE:
1361 break;
1362 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001363 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001364 return false;
1365 }
1366 break;
1367 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1368 // handled below
1369 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1370 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1371 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1372 break;
1373 case GL_DEPTH_COMPONENT:
1374 switch (type)
1375 {
1376 case GL_UNSIGNED_SHORT:
1377 case GL_UNSIGNED_INT:
1378 break;
1379 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001380 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001381 return false;
1382 }
1383 break;
1384 case GL_DEPTH_STENCIL_OES:
1385 switch (type)
1386 {
1387 case GL_UNSIGNED_INT_24_8_OES:
1388 break;
1389 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001390 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001391 return false;
1392 }
1393 break;
1394 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001395 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001396 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001397 }
1398
1399 switch (format)
1400 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001401 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1402 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1403 if (context->getExtensions().textureCompressionDXT1)
1404 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001405 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001406 return false;
1407 }
1408 else
1409 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001410 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001411 return false;
1412 }
1413 break;
1414 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1415 if (context->getExtensions().textureCompressionDXT3)
1416 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001417 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001418 return false;
1419 }
1420 else
1421 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001422 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001423 return false;
1424 }
1425 break;
1426 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1427 if (context->getExtensions().textureCompressionDXT5)
1428 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001429 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001430 return false;
1431 }
1432 else
1433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001434 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001435 return false;
1436 }
1437 break;
1438 case GL_ETC1_RGB8_OES:
1439 if (context->getExtensions().compressedETC1RGB8Texture)
1440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001441 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001442 return false;
1443 }
1444 else
1445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001446 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001447 return false;
1448 }
1449 break;
1450 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001451 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1452 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1453 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1454 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001455 if (context->getExtensions().lossyETCDecode)
1456 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001457 context->handleError(InvalidOperation()
1458 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001459 return false;
1460 }
1461 else
1462 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001463 context->handleError(InvalidEnum()
1464 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001465 return false;
1466 }
1467 break;
1468 case GL_DEPTH_COMPONENT:
1469 case GL_DEPTH_STENCIL_OES:
1470 if (!context->getExtensions().depthTextures)
1471 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001472 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001473 return false;
1474 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001475 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001476 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001477 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001478 return false;
1479 }
1480 // OES_depth_texture supports loading depth data and multiple levels,
1481 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001482 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001483 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001484 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1485 return false;
1486 }
1487 if (level != 0)
1488 {
1489 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001490 return false;
1491 }
1492 break;
1493 default:
1494 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001495 }
1496
Geoff Lang6e898aa2017-06-02 11:17:26 -04001497 if (!isSubImage)
1498 {
1499 switch (internalformat)
1500 {
1501 case GL_RGBA32F:
1502 if (!context->getExtensions().colorBufferFloatRGBA)
1503 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001504 context->handleError(InvalidValue()
1505 << "Sized GL_RGBA32F internal format requires "
1506 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001507 return false;
1508 }
1509 if (type != GL_FLOAT)
1510 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001512 return false;
1513 }
1514 if (format != GL_RGBA)
1515 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001516 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001517 return false;
1518 }
1519 break;
1520
1521 case GL_RGB32F:
1522 if (!context->getExtensions().colorBufferFloatRGB)
1523 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001524 context->handleError(InvalidValue()
1525 << "Sized GL_RGB32F internal format requires "
1526 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001527 return false;
1528 }
1529 if (type != GL_FLOAT)
1530 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001532 return false;
1533 }
1534 if (format != GL_RGB)
1535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001536 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001537 return false;
1538 }
1539 break;
1540
1541 default:
1542 break;
1543 }
1544 }
1545
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001546 if (type == GL_FLOAT)
1547 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001548 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001549 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001550 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001551 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001552 }
1553 }
1554 else if (type == GL_HALF_FLOAT_OES)
1555 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001556 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001557 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001558 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001559 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001560 }
1561 }
1562 }
1563
Geoff Langdbcced82017-06-06 15:55:54 -04001564 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001565 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001566 imageSize))
1567 {
1568 return false;
1569 }
1570
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001571 return true;
1572}
1573
He Yunchaoced53ae2016-11-29 15:00:51 +08001574bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001575 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001576 GLsizei levels,
1577 GLenum internalformat,
1578 GLsizei width,
1579 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001580{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001581 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1582 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001583 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001584 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001585 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001586 }
1587
1588 if (width < 1 || height < 1 || levels < 1)
1589 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001590 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001591 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001592 }
1593
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001594 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001595 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001596 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001597 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001598 }
1599
1600 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1601 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001602 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001603 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001604 }
1605
Geoff Langca271392017-04-05 12:30:00 -04001606 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001607 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001608 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001609 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001610 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001611 }
1612
Geoff Langaae65a42014-05-26 12:43:44 -04001613 const gl::Caps &caps = context->getCaps();
1614
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001615 switch (target)
1616 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001617 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001618 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1619 static_cast<GLuint>(height) > caps.max2DTextureSize)
1620 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001621 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001622 return false;
1623 }
1624 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001625 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001626 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1627 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1628 {
1629 context->handleError(InvalidValue());
1630 return false;
1631 }
1632 if (formatInfo.compressed)
1633 {
1634 context->handleError(InvalidEnum()
1635 << "Rectangle texture cannot have a compressed format.");
1636 return false;
1637 }
1638 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001639 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001640 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1641 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1642 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001643 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001644 return false;
1645 }
1646 break;
1647 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001648 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001649 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001650 }
1651
Geoff Langc0b9ef42014-07-02 10:02:37 -04001652 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001653 {
1654 if (!gl::isPow2(width) || !gl::isPow2(height))
1655 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001656 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001657 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001658 }
1659 }
1660
1661 switch (internalformat)
1662 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001663 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1664 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1665 if (!context->getExtensions().textureCompressionDXT1)
1666 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001667 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001668 return false;
1669 }
1670 break;
1671 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1672 if (!context->getExtensions().textureCompressionDXT3)
1673 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001674 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001675 return false;
1676 }
1677 break;
1678 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1679 if (!context->getExtensions().textureCompressionDXT5)
1680 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001681 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001682 return false;
1683 }
1684 break;
1685 case GL_ETC1_RGB8_OES:
1686 if (!context->getExtensions().compressedETC1RGB8Texture)
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_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001693 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1694 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1695 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1696 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001697 if (!context->getExtensions().lossyETCDecode)
1698 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001699 context->handleError(InvalidEnum()
1700 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001701 return false;
1702 }
1703 break;
1704 case GL_RGBA32F_EXT:
1705 case GL_RGB32F_EXT:
1706 case GL_ALPHA32F_EXT:
1707 case GL_LUMINANCE32F_EXT:
1708 case GL_LUMINANCE_ALPHA32F_EXT:
1709 if (!context->getExtensions().textureFloat)
1710 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001711 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001712 return false;
1713 }
1714 break;
1715 case GL_RGBA16F_EXT:
1716 case GL_RGB16F_EXT:
1717 case GL_ALPHA16F_EXT:
1718 case GL_LUMINANCE16F_EXT:
1719 case GL_LUMINANCE_ALPHA16F_EXT:
1720 if (!context->getExtensions().textureHalfFloat)
1721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001722 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001723 return false;
1724 }
1725 break;
1726 case GL_R8_EXT:
1727 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001728 if (!context->getExtensions().textureRG)
1729 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001730 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001731 return false;
1732 }
1733 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001734 case GL_R16F_EXT:
1735 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001736 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1737 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001738 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001739 return false;
1740 }
1741 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001742 case GL_R32F_EXT:
1743 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001744 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001745 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001746 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001747 return false;
1748 }
1749 break;
1750 case GL_DEPTH_COMPONENT16:
1751 case GL_DEPTH_COMPONENT32_OES:
1752 case GL_DEPTH24_STENCIL8_OES:
1753 if (!context->getExtensions().depthTextures)
1754 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001755 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001756 return false;
1757 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001758 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001759 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001760 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001761 return false;
1762 }
1763 // ANGLE_depth_texture only supports 1-level textures
1764 if (levels != 1)
1765 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001766 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001767 return false;
1768 }
1769 break;
1770 default:
1771 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001772 }
1773
Geoff Lang691e58c2014-12-19 17:03:25 -05001774 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001775 if (!texture || texture->id() == 0)
1776 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001777 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001778 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001779 }
1780
Geoff Lang69cce582015-09-17 13:20:36 -04001781 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001782 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001783 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001784 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001785 }
1786
1787 return true;
1788}
1789
He Yunchaoced53ae2016-11-29 15:00:51 +08001790bool ValidateDiscardFramebufferEXT(Context *context,
1791 GLenum target,
1792 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001793 const GLenum *attachments)
1794{
Jamie Madillc29968b2016-01-20 11:17:23 -05001795 if (!context->getExtensions().discardFramebuffer)
1796 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001797 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001798 return false;
1799 }
1800
Austin Kinross08332632015-05-05 13:35:47 -07001801 bool defaultFramebuffer = false;
1802
1803 switch (target)
1804 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001805 case GL_FRAMEBUFFER:
1806 defaultFramebuffer =
1807 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1808 break;
1809 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001810 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001811 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001812 }
1813
He Yunchaoced53ae2016-11-29 15:00:51 +08001814 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1815 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001816}
1817
Austin Kinrossbc781f32015-10-26 09:27:38 -07001818bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1819{
1820 if (!context->getExtensions().vertexArrayObject)
1821 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001822 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001823 return false;
1824 }
1825
1826 return ValidateBindVertexArrayBase(context, array);
1827}
1828
Jamie Madilld7576732017-08-26 18:49:50 -04001829bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001830{
1831 if (!context->getExtensions().vertexArrayObject)
1832 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001833 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001834 return false;
1835 }
1836
Olli Etuaho41997e72016-03-10 13:38:39 +02001837 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001838}
1839
Jamie Madilld7576732017-08-26 18:49:50 -04001840bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001841{
1842 if (!context->getExtensions().vertexArrayObject)
1843 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001844 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001845 return false;
1846 }
1847
Olli Etuaho41997e72016-03-10 13:38:39 +02001848 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001849}
1850
Jamie Madilld7576732017-08-26 18:49:50 -04001851bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001852{
1853 if (!context->getExtensions().vertexArrayObject)
1854 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001855 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001856 return false;
1857 }
1858
1859 return true;
1860}
Geoff Langc5629752015-12-07 16:29:04 -05001861
1862bool ValidateProgramBinaryOES(Context *context,
1863 GLuint program,
1864 GLenum binaryFormat,
1865 const void *binary,
1866 GLint length)
1867{
1868 if (!context->getExtensions().getProgramBinary)
1869 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001870 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001871 return false;
1872 }
1873
1874 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1875}
1876
1877bool ValidateGetProgramBinaryOES(Context *context,
1878 GLuint program,
1879 GLsizei bufSize,
1880 GLsizei *length,
1881 GLenum *binaryFormat,
1882 void *binary)
1883{
1884 if (!context->getExtensions().getProgramBinary)
1885 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001886 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001887 return false;
1888 }
1889
1890 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1891}
Geoff Lange102fee2015-12-10 11:23:30 -05001892
Geoff Lang70d0f492015-12-10 17:45:46 -05001893static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1894{
1895 switch (source)
1896 {
1897 case GL_DEBUG_SOURCE_API:
1898 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1899 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1900 case GL_DEBUG_SOURCE_OTHER:
1901 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1902 return !mustBeThirdPartyOrApplication;
1903
1904 case GL_DEBUG_SOURCE_THIRD_PARTY:
1905 case GL_DEBUG_SOURCE_APPLICATION:
1906 return true;
1907
1908 default:
1909 return false;
1910 }
1911}
1912
1913static bool ValidDebugType(GLenum type)
1914{
1915 switch (type)
1916 {
1917 case GL_DEBUG_TYPE_ERROR:
1918 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1919 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1920 case GL_DEBUG_TYPE_PERFORMANCE:
1921 case GL_DEBUG_TYPE_PORTABILITY:
1922 case GL_DEBUG_TYPE_OTHER:
1923 case GL_DEBUG_TYPE_MARKER:
1924 case GL_DEBUG_TYPE_PUSH_GROUP:
1925 case GL_DEBUG_TYPE_POP_GROUP:
1926 return true;
1927
1928 default:
1929 return false;
1930 }
1931}
1932
1933static bool ValidDebugSeverity(GLenum severity)
1934{
1935 switch (severity)
1936 {
1937 case GL_DEBUG_SEVERITY_HIGH:
1938 case GL_DEBUG_SEVERITY_MEDIUM:
1939 case GL_DEBUG_SEVERITY_LOW:
1940 case GL_DEBUG_SEVERITY_NOTIFICATION:
1941 return true;
1942
1943 default:
1944 return false;
1945 }
1946}
1947
Geoff Lange102fee2015-12-10 11:23:30 -05001948bool ValidateDebugMessageControlKHR(Context *context,
1949 GLenum source,
1950 GLenum type,
1951 GLenum severity,
1952 GLsizei count,
1953 const GLuint *ids,
1954 GLboolean enabled)
1955{
1956 if (!context->getExtensions().debug)
1957 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001958 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001959 return false;
1960 }
1961
Geoff Lang70d0f492015-12-10 17:45:46 -05001962 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1963 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001964 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001965 return false;
1966 }
1967
1968 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1969 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001970 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001971 return false;
1972 }
1973
1974 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1975 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001976 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001977 return false;
1978 }
1979
1980 if (count > 0)
1981 {
1982 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001984 context->handleError(
1985 InvalidOperation()
1986 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05001987 return false;
1988 }
1989
1990 if (severity != GL_DONT_CARE)
1991 {
Jamie Madill437fa652016-05-03 15:13:24 -04001992 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001993 InvalidOperation()
1994 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05001995 return false;
1996 }
1997 }
1998
Geoff Lange102fee2015-12-10 11:23:30 -05001999 return true;
2000}
2001
2002bool ValidateDebugMessageInsertKHR(Context *context,
2003 GLenum source,
2004 GLenum type,
2005 GLuint id,
2006 GLenum severity,
2007 GLsizei length,
2008 const GLchar *buf)
2009{
2010 if (!context->getExtensions().debug)
2011 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002012 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002013 return false;
2014 }
2015
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002016 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002017 {
2018 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2019 // not generate an error.
2020 return false;
2021 }
2022
2023 if (!ValidDebugSeverity(severity))
2024 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002025 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002026 return false;
2027 }
2028
2029 if (!ValidDebugType(type))
2030 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002031 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002032 return false;
2033 }
2034
2035 if (!ValidDebugSource(source, true))
2036 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002037 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002038 return false;
2039 }
2040
2041 size_t messageLength = (length < 0) ? strlen(buf) : length;
2042 if (messageLength > context->getExtensions().maxDebugMessageLength)
2043 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002044 context->handleError(InvalidValue()
2045 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002046 return false;
2047 }
2048
Geoff Lange102fee2015-12-10 11:23:30 -05002049 return true;
2050}
2051
2052bool ValidateDebugMessageCallbackKHR(Context *context,
2053 GLDEBUGPROCKHR callback,
2054 const void *userParam)
2055{
2056 if (!context->getExtensions().debug)
2057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002058 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002059 return false;
2060 }
2061
Geoff Lange102fee2015-12-10 11:23:30 -05002062 return true;
2063}
2064
2065bool ValidateGetDebugMessageLogKHR(Context *context,
2066 GLuint count,
2067 GLsizei bufSize,
2068 GLenum *sources,
2069 GLenum *types,
2070 GLuint *ids,
2071 GLenum *severities,
2072 GLsizei *lengths,
2073 GLchar *messageLog)
2074{
2075 if (!context->getExtensions().debug)
2076 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002077 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002078 return false;
2079 }
2080
Geoff Lang70d0f492015-12-10 17:45:46 -05002081 if (bufSize < 0 && messageLog != nullptr)
2082 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002083 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002084 return false;
2085 }
2086
Geoff Lange102fee2015-12-10 11:23:30 -05002087 return true;
2088}
2089
2090bool ValidatePushDebugGroupKHR(Context *context,
2091 GLenum source,
2092 GLuint id,
2093 GLsizei length,
2094 const GLchar *message)
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 (!ValidDebugSource(source, true))
2103 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002104 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002105 return false;
2106 }
2107
2108 size_t messageLength = (length < 0) ? strlen(message) : length;
2109 if (messageLength > context->getExtensions().maxDebugMessageLength)
2110 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002111 context->handleError(InvalidValue()
2112 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002113 return false;
2114 }
2115
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002116 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002117 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2118 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002119 context
2120 ->handleError(StackOverflow()
2121 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002122 return false;
2123 }
2124
Geoff Lange102fee2015-12-10 11:23:30 -05002125 return true;
2126}
2127
2128bool ValidatePopDebugGroupKHR(Context *context)
2129{
2130 if (!context->getExtensions().debug)
2131 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002132 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002133 return false;
2134 }
2135
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002136 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002137 if (currentStackSize <= 1)
2138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002139 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002140 return false;
2141 }
2142
2143 return true;
2144}
2145
2146static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2147{
2148 switch (identifier)
2149 {
2150 case GL_BUFFER:
2151 if (context->getBuffer(name) == nullptr)
2152 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002153 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002154 return false;
2155 }
2156 return true;
2157
2158 case GL_SHADER:
2159 if (context->getShader(name) == nullptr)
2160 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002161 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002162 return false;
2163 }
2164 return true;
2165
2166 case GL_PROGRAM:
2167 if (context->getProgram(name) == nullptr)
2168 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002169 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002170 return false;
2171 }
2172 return true;
2173
2174 case GL_VERTEX_ARRAY:
2175 if (context->getVertexArray(name) == nullptr)
2176 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002177 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002178 return false;
2179 }
2180 return true;
2181
2182 case GL_QUERY:
2183 if (context->getQuery(name) == nullptr)
2184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002185 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002186 return false;
2187 }
2188 return true;
2189
2190 case GL_TRANSFORM_FEEDBACK:
2191 if (context->getTransformFeedback(name) == nullptr)
2192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002193 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002194 return false;
2195 }
2196 return true;
2197
2198 case GL_SAMPLER:
2199 if (context->getSampler(name) == nullptr)
2200 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002201 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002202 return false;
2203 }
2204 return true;
2205
2206 case GL_TEXTURE:
2207 if (context->getTexture(name) == nullptr)
2208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002209 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002210 return false;
2211 }
2212 return true;
2213
2214 case GL_RENDERBUFFER:
2215 if (context->getRenderbuffer(name) == nullptr)
2216 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002217 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002218 return false;
2219 }
2220 return true;
2221
2222 case GL_FRAMEBUFFER:
2223 if (context->getFramebuffer(name) == nullptr)
2224 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002225 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002226 return false;
2227 }
2228 return true;
2229
2230 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002231 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002232 return false;
2233 }
Geoff Lange102fee2015-12-10 11:23:30 -05002234}
2235
Martin Radev9d901792016-07-15 15:58:58 +03002236static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2237{
2238 size_t labelLength = 0;
2239
2240 if (length < 0)
2241 {
2242 if (label != nullptr)
2243 {
2244 labelLength = strlen(label);
2245 }
2246 }
2247 else
2248 {
2249 labelLength = static_cast<size_t>(length);
2250 }
2251
2252 if (labelLength > context->getExtensions().maxLabelLength)
2253 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002254 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002255 return false;
2256 }
2257
2258 return true;
2259}
2260
Geoff Lange102fee2015-12-10 11:23:30 -05002261bool ValidateObjectLabelKHR(Context *context,
2262 GLenum identifier,
2263 GLuint name,
2264 GLsizei length,
2265 const GLchar *label)
2266{
2267 if (!context->getExtensions().debug)
2268 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002269 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002270 return false;
2271 }
2272
Geoff Lang70d0f492015-12-10 17:45:46 -05002273 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2274 {
2275 return false;
2276 }
2277
Martin Radev9d901792016-07-15 15:58:58 +03002278 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002279 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002280 return false;
2281 }
2282
Geoff Lange102fee2015-12-10 11:23:30 -05002283 return true;
2284}
2285
2286bool ValidateGetObjectLabelKHR(Context *context,
2287 GLenum identifier,
2288 GLuint name,
2289 GLsizei bufSize,
2290 GLsizei *length,
2291 GLchar *label)
2292{
2293 if (!context->getExtensions().debug)
2294 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002296 return false;
2297 }
2298
Geoff Lang70d0f492015-12-10 17:45:46 -05002299 if (bufSize < 0)
2300 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002301 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002302 return false;
2303 }
2304
2305 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2306 {
2307 return false;
2308 }
2309
Martin Radev9d901792016-07-15 15:58:58 +03002310 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002311}
2312
2313static bool ValidateObjectPtrName(Context *context, const void *ptr)
2314{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002315 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002316 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002317 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002318 return false;
2319 }
2320
Geoff Lange102fee2015-12-10 11:23:30 -05002321 return true;
2322}
2323
2324bool ValidateObjectPtrLabelKHR(Context *context,
2325 const void *ptr,
2326 GLsizei length,
2327 const GLchar *label)
2328{
2329 if (!context->getExtensions().debug)
2330 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002331 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002332 return false;
2333 }
2334
Geoff Lang70d0f492015-12-10 17:45:46 -05002335 if (!ValidateObjectPtrName(context, ptr))
2336 {
2337 return false;
2338 }
2339
Martin Radev9d901792016-07-15 15:58:58 +03002340 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002341 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002342 return false;
2343 }
2344
Geoff Lange102fee2015-12-10 11:23:30 -05002345 return true;
2346}
2347
2348bool ValidateGetObjectPtrLabelKHR(Context *context,
2349 const void *ptr,
2350 GLsizei bufSize,
2351 GLsizei *length,
2352 GLchar *label)
2353{
2354 if (!context->getExtensions().debug)
2355 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002356 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002357 return false;
2358 }
2359
Geoff Lang70d0f492015-12-10 17:45:46 -05002360 if (bufSize < 0)
2361 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002362 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002363 return false;
2364 }
2365
2366 if (!ValidateObjectPtrName(context, ptr))
2367 {
2368 return false;
2369 }
2370
Martin Radev9d901792016-07-15 15:58:58 +03002371 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002372}
2373
2374bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2375{
2376 if (!context->getExtensions().debug)
2377 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002378 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002379 return false;
2380 }
2381
Geoff Lang70d0f492015-12-10 17:45:46 -05002382 // TODO: represent this in Context::getQueryParameterInfo.
2383 switch (pname)
2384 {
2385 case GL_DEBUG_CALLBACK_FUNCTION:
2386 case GL_DEBUG_CALLBACK_USER_PARAM:
2387 break;
2388
2389 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002390 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002391 return false;
2392 }
2393
Geoff Lange102fee2015-12-10 11:23:30 -05002394 return true;
2395}
Jamie Madillc29968b2016-01-20 11:17:23 -05002396
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002397bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2398 GLenum pname,
2399 GLsizei bufSize,
2400 GLsizei *length,
2401 void **params)
2402{
2403 UNIMPLEMENTED();
2404 return false;
2405}
2406
Jamie Madillc29968b2016-01-20 11:17:23 -05002407bool ValidateBlitFramebufferANGLE(Context *context,
2408 GLint srcX0,
2409 GLint srcY0,
2410 GLint srcX1,
2411 GLint srcY1,
2412 GLint dstX0,
2413 GLint dstY0,
2414 GLint dstX1,
2415 GLint dstY1,
2416 GLbitfield mask,
2417 GLenum filter)
2418{
2419 if (!context->getExtensions().framebufferBlit)
2420 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002421 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002422 return false;
2423 }
2424
2425 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2426 {
2427 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002428 context->handleError(InvalidOperation() << "Scaling and flipping in "
2429 "BlitFramebufferANGLE not supported by this "
2430 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002431 return false;
2432 }
2433
2434 if (filter == GL_LINEAR)
2435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002436 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002437 return false;
2438 }
2439
Jamie Madill51f40ec2016-06-15 14:06:00 -04002440 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2441 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002442
2443 if (mask & GL_COLOR_BUFFER_BIT)
2444 {
2445 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2446 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2447
2448 if (readColorAttachment && drawColorAttachment)
2449 {
2450 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002451 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002452 readColorAttachment->type() != GL_RENDERBUFFER &&
2453 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002455 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002456 return false;
2457 }
2458
Geoff Langa15472a2015-08-11 11:48:03 -04002459 for (size_t drawbufferIdx = 0;
2460 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002461 {
Geoff Langa15472a2015-08-11 11:48:03 -04002462 const FramebufferAttachment *attachment =
2463 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2464 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002465 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002466 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002467 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002468 attachment->type() != GL_RENDERBUFFER &&
2469 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2470 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002471 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002472 return false;
2473 }
2474
2475 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002476 if (!Format::EquivalentForBlit(attachment->getFormat(),
2477 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002478 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002479 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002480 return false;
2481 }
2482 }
2483 }
2484
Jamie Madill427064d2018-04-13 16:20:34 -04002485 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002486 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002487 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2488 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002490 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 return false;
2492 }
2493 }
2494 }
2495
2496 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2497 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2498 for (size_t i = 0; i < 2; i++)
2499 {
2500 if (mask & masks[i])
2501 {
2502 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002503 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002504 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002505 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002506
2507 if (readBuffer && drawBuffer)
2508 {
2509 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2510 dstX0, dstY0, dstX1, dstY1))
2511 {
2512 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002513 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2514 "stencil blits are supported by "
2515 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002516 return false;
2517 }
2518
2519 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2520 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002521 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002522 return false;
2523 }
2524 }
2525 }
2526 }
2527
2528 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2529 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002530}
Jamie Madillc29968b2016-01-20 11:17:23 -05002531
Jamie Madill5b772312018-03-08 20:28:32 -05002532bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002533{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002534 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002535
Jamie Madill427064d2018-04-13 16:20:34 -04002536 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002537 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 return false;
2539 }
2540
2541 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2542 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002543 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002544 return false;
2545 }
2546
Geoff Lang76e65652017-03-27 14:58:02 -04002547 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2548 {
2549 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2550 GL_SIGNED_NORMALIZED};
2551
Corentin Wallez59c41592017-07-11 13:19:54 -04002552 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002553 drawBufferIdx++)
2554 {
2555 if (!ValidateWebGLFramebufferAttachmentClearType(
2556 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2557 {
2558 return false;
2559 }
2560 }
2561 }
2562
Jamie Madillc29968b2016-01-20 11:17:23 -05002563 return true;
2564}
2565
Jamie Madill5b772312018-03-08 20:28:32 -05002566bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002567{
2568 if (!context->getExtensions().drawBuffers)
2569 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002570 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002571 return false;
2572 }
2573
2574 return ValidateDrawBuffersBase(context, n, bufs);
2575}
2576
Jamie Madill73a84962016-02-12 09:27:23 -05002577bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002578 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002579 GLint level,
2580 GLint internalformat,
2581 GLsizei width,
2582 GLsizei height,
2583 GLint border,
2584 GLenum format,
2585 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002586 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002587{
Martin Radev1be913c2016-07-11 17:59:16 +03002588 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002589 {
2590 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002591 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002592 }
2593
Martin Radev1be913c2016-07-11 17:59:16 +03002594 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002595 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002596 0, 0, width, height, 1, border, format, type, -1,
2597 pixels);
2598}
2599
Brandon Jones416aaf92018-04-10 08:10:16 -07002600bool ValidateTexImage2DRobustANGLE(Context *context,
2601 TextureTarget target,
2602 GLint level,
2603 GLint internalformat,
2604 GLsizei width,
2605 GLsizei height,
2606 GLint border,
2607 GLenum format,
2608 GLenum type,
2609 GLsizei bufSize,
2610 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002611{
2612 if (!ValidateRobustEntryPoint(context, bufSize))
2613 {
2614 return false;
2615 }
2616
2617 if (context->getClientMajorVersion() < 3)
2618 {
2619 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2620 0, 0, width, height, border, format, type, bufSize,
2621 pixels);
2622 }
2623
2624 ASSERT(context->getClientMajorVersion() >= 3);
2625 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2626 0, 0, width, height, 1, border, format, type, bufSize,
2627 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002628}
2629
2630bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002631 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002632 GLint level,
2633 GLint xoffset,
2634 GLint yoffset,
2635 GLsizei width,
2636 GLsizei height,
2637 GLenum format,
2638 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002639 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002640{
2641
Martin Radev1be913c2016-07-11 17:59:16 +03002642 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002643 {
2644 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002645 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002646 }
2647
Martin Radev1be913c2016-07-11 17:59:16 +03002648 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002649 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002650 yoffset, 0, width, height, 1, 0, format, type, -1,
2651 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002652}
2653
Geoff Langc52f6f12016-10-14 10:18:00 -04002654bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002655 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002656 GLint level,
2657 GLint xoffset,
2658 GLint yoffset,
2659 GLsizei width,
2660 GLsizei height,
2661 GLenum format,
2662 GLenum type,
2663 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002664 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002665{
2666 if (!ValidateRobustEntryPoint(context, bufSize))
2667 {
2668 return false;
2669 }
2670
2671 if (context->getClientMajorVersion() < 3)
2672 {
2673 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2674 yoffset, width, height, 0, format, type, bufSize,
2675 pixels);
2676 }
2677
2678 ASSERT(context->getClientMajorVersion() >= 3);
2679 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2680 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2681 pixels);
2682}
2683
Jamie Madill73a84962016-02-12 09:27:23 -05002684bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002685 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002686 GLint level,
2687 GLenum internalformat,
2688 GLsizei width,
2689 GLsizei height,
2690 GLint border,
2691 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002692 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002693{
Martin Radev1be913c2016-07-11 17:59:16 +03002694 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002695 {
2696 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002697 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002698 {
2699 return false;
2700 }
2701 }
2702 else
2703 {
Martin Radev1be913c2016-07-11 17:59:16 +03002704 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002705 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002706 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002707 data))
2708 {
2709 return false;
2710 }
2711 }
2712
Geoff Langca271392017-04-05 12:30:00 -04002713 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002714 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002715 if (blockSizeOrErr.isError())
2716 {
2717 context->handleError(blockSizeOrErr.getError());
2718 return false;
2719 }
2720
2721 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002722 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002723 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002724 return false;
2725 }
2726
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002727 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002728 {
2729 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2730 return false;
2731 }
2732
Jamie Madill73a84962016-02-12 09:27:23 -05002733 return true;
2734}
2735
Corentin Wallezb2931602017-04-11 15:58:57 -04002736bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002737 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002738 GLint level,
2739 GLenum internalformat,
2740 GLsizei width,
2741 GLsizei height,
2742 GLint border,
2743 GLsizei imageSize,
2744 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002745 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002746{
2747 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2748 {
2749 return false;
2750 }
2751
2752 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2753 border, imageSize, data);
2754}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002755
Corentin Wallezb2931602017-04-11 15:58:57 -04002756bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002757 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002758 GLint level,
2759 GLint xoffset,
2760 GLint yoffset,
2761 GLsizei width,
2762 GLsizei height,
2763 GLenum format,
2764 GLsizei imageSize,
2765 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002766 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002767{
2768 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2769 {
2770 return false;
2771 }
2772
2773 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2774 format, imageSize, data);
2775}
2776
Jamie Madill73a84962016-02-12 09:27:23 -05002777bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002778 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002779 GLint level,
2780 GLint xoffset,
2781 GLint yoffset,
2782 GLsizei width,
2783 GLsizei height,
2784 GLenum format,
2785 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002786 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002787{
Martin Radev1be913c2016-07-11 17:59:16 +03002788 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002789 {
2790 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002791 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002792 {
2793 return false;
2794 }
2795 }
2796 else
2797 {
Martin Radev1be913c2016-07-11 17:59:16 +03002798 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002799 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002800 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002801 data))
2802 {
2803 return false;
2804 }
2805 }
2806
Geoff Langca271392017-04-05 12:30:00 -04002807 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002808 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002809 if (blockSizeOrErr.isError())
2810 {
2811 context->handleError(blockSizeOrErr.getError());
2812 return false;
2813 }
2814
2815 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002816 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002817 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002818 return false;
2819 }
2820
2821 return true;
2822}
2823
Corentin Wallez336129f2017-10-17 15:55:40 -04002824bool ValidateGetBufferPointervOES(Context *context,
2825 BufferBinding target,
2826 GLenum pname,
2827 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002828{
Geoff Lang496c02d2016-10-20 11:38:11 -07002829 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002830}
2831
Corentin Wallez336129f2017-10-17 15:55:40 -04002832bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002833{
2834 if (!context->getExtensions().mapBuffer)
2835 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002836 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002837 return false;
2838 }
2839
Corentin Walleze4477002017-12-01 14:39:58 -05002840 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002841 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002842 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002843 return false;
2844 }
2845
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002846 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002847
2848 if (buffer == nullptr)
2849 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002850 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002851 return false;
2852 }
2853
2854 if (access != GL_WRITE_ONLY_OES)
2855 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002856 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002857 return false;
2858 }
2859
2860 if (buffer->isMapped())
2861 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002862 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002863 return false;
2864 }
2865
Geoff Lang79f71042017-08-14 16:43:43 -04002866 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002867}
2868
Corentin Wallez336129f2017-10-17 15:55:40 -04002869bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002870{
2871 if (!context->getExtensions().mapBuffer)
2872 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002873 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002874 return false;
2875 }
2876
2877 return ValidateUnmapBufferBase(context, target);
2878}
2879
2880bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002881 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002882 GLintptr offset,
2883 GLsizeiptr length,
2884 GLbitfield access)
2885{
2886 if (!context->getExtensions().mapBufferRange)
2887 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002888 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002889 return false;
2890 }
2891
2892 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2893}
2894
Corentin Wallez336129f2017-10-17 15:55:40 -04002895bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002896{
2897 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2898 ASSERT(buffer != nullptr);
2899
2900 // Check if this buffer is currently being used as a transform feedback output buffer
2901 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2902 if (transformFeedback != nullptr && transformFeedback->isActive())
2903 {
2904 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2905 {
2906 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2907 if (transformFeedbackBuffer.get() == buffer)
2908 {
2909 context->handleError(InvalidOperation()
2910 << "Buffer is currently bound for transform feedback.");
2911 return false;
2912 }
2913 }
2914 }
2915
James Darpiniane8a93c62018-01-04 18:02:24 -08002916 if (context->getExtensions().webglCompatibility &&
2917 buffer->isBoundForTransformFeedbackAndOtherUse())
2918 {
2919 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2920 return false;
2921 }
2922
Geoff Lang79f71042017-08-14 16:43:43 -04002923 return true;
2924}
2925
Olli Etuaho4f667482016-03-30 15:56:35 +03002926bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002927 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002928 GLintptr offset,
2929 GLsizeiptr length)
2930{
2931 if (!context->getExtensions().mapBufferRange)
2932 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002933 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002934 return false;
2935 }
2936
2937 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2938}
2939
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002940bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002941{
2942 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002943 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002944 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002945 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002946 return false;
2947 }
2948
Geoff Langf41a7152016-09-19 15:11:17 -04002949 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2950 !context->isTextureGenerated(texture))
2951 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002952 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002953 return false;
2954 }
2955
Ian Ewell54f87462016-03-10 13:47:21 -05002956 switch (target)
2957 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002958 case TextureType::_2D:
2959 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002960 break;
2961
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002962 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002963 if (!context->getExtensions().textureRectangle)
2964 {
2965 context->handleError(InvalidEnum()
2966 << "Context does not support GL_ANGLE_texture_rectangle");
2967 return false;
2968 }
2969 break;
2970
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002971 case TextureType::_3D:
2972 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002973 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002974 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002975 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002976 return false;
2977 }
2978 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002979
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002980 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04002981 if (context->getClientVersion() < Version(3, 1))
2982 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002983 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002984 return false;
2985 }
Geoff Lang3b573612016-10-31 14:08:10 -04002986 break;
2987
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002988 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04002989 if (!context->getExtensions().eglImageExternal &&
2990 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05002991 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002992 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05002993 return false;
2994 }
2995 break;
2996 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002997 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05002998 return false;
2999 }
3000
3001 return true;
3002}
3003
Geoff Langd8605522016-04-13 10:19:12 -04003004bool ValidateBindUniformLocationCHROMIUM(Context *context,
3005 GLuint program,
3006 GLint location,
3007 const GLchar *name)
3008{
3009 if (!context->getExtensions().bindUniformLocation)
3010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003011 context->handleError(InvalidOperation()
3012 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003013 return false;
3014 }
3015
3016 Program *programObject = GetValidProgram(context, program);
3017 if (!programObject)
3018 {
3019 return false;
3020 }
3021
3022 if (location < 0)
3023 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003024 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003025 return false;
3026 }
3027
3028 const Caps &caps = context->getCaps();
3029 if (static_cast<size_t>(location) >=
3030 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3031 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003032 context->handleError(InvalidValue() << "Location must be less than "
3033 "(MAX_VERTEX_UNIFORM_VECTORS + "
3034 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003035 return false;
3036 }
3037
Geoff Langfc32e8b2017-05-31 14:16:59 -04003038 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3039 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003040 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003041 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003042 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003043 return false;
3044 }
3045
Geoff Langd8605522016-04-13 10:19:12 -04003046 if (strncmp(name, "gl_", 3) == 0)
3047 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003048 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003049 return false;
3050 }
3051
3052 return true;
3053}
3054
Jamie Madille2e406c2016-06-02 13:04:10 -04003055bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003056{
3057 if (!context->getExtensions().framebufferMixedSamples)
3058 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003059 context->handleError(InvalidOperation()
3060 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003061 return false;
3062 }
3063 switch (components)
3064 {
3065 case GL_RGB:
3066 case GL_RGBA:
3067 case GL_ALPHA:
3068 case GL_NONE:
3069 break;
3070 default:
3071 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003072 InvalidEnum()
3073 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003074 return false;
3075 }
3076
3077 return true;
3078}
3079
Sami Väisänene45e53b2016-05-25 10:36:04 +03003080// CHROMIUM_path_rendering
3081
Jamie Madill007530e2017-12-28 14:27:04 -05003082bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003083{
Jamie Madill007530e2017-12-28 14:27:04 -05003084 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003085 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003086 return false;
3087 }
Jamie Madill007530e2017-12-28 14:27:04 -05003088
Sami Väisänene45e53b2016-05-25 10:36:04 +03003089 if (matrix == nullptr)
3090 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003091 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003092 return false;
3093 }
Jamie Madill007530e2017-12-28 14:27:04 -05003094
Sami Väisänene45e53b2016-05-25 10:36:04 +03003095 return true;
3096}
3097
Jamie Madill007530e2017-12-28 14:27:04 -05003098bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003099{
Jamie Madill007530e2017-12-28 14:27:04 -05003100 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003101}
3102
Jamie Madill007530e2017-12-28 14:27:04 -05003103bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003104{
3105 if (!context->getExtensions().pathRendering)
3106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003107 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003108 return false;
3109 }
3110
3111 // range = 0 is undefined in NV_path_rendering.
3112 // we add stricter semantic check here and require a non zero positive range.
3113 if (range <= 0)
3114 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003115 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003116 return false;
3117 }
3118
3119 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3120 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003121 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003122 return false;
3123 }
3124
3125 return true;
3126}
3127
Jamie Madill007530e2017-12-28 14:27:04 -05003128bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003129{
3130 if (!context->getExtensions().pathRendering)
3131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003132 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003133 return false;
3134 }
3135
3136 // range = 0 is undefined in NV_path_rendering.
3137 // we add stricter semantic check here and require a non zero positive range.
3138 if (range <= 0)
3139 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003140 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003141 return false;
3142 }
3143
3144 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3145 checkedRange += range;
3146
3147 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3148 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003149 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003150 return false;
3151 }
3152 return true;
3153}
3154
Jamie Madill007530e2017-12-28 14:27:04 -05003155bool ValidatePathCommandsCHROMIUM(Context *context,
3156 GLuint path,
3157 GLsizei numCommands,
3158 const GLubyte *commands,
3159 GLsizei numCoords,
3160 GLenum coordType,
3161 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003162{
3163 if (!context->getExtensions().pathRendering)
3164 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003165 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003166 return false;
3167 }
Brandon Jones59770802018-04-02 13:18:42 -07003168 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003169 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003170 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003171 return false;
3172 }
3173
3174 if (numCommands < 0)
3175 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003176 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003177 return false;
3178 }
3179 else if (numCommands > 0)
3180 {
3181 if (!commands)
3182 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003183 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003184 return false;
3185 }
3186 }
3187
3188 if (numCoords < 0)
3189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003190 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003191 return false;
3192 }
3193 else if (numCoords > 0)
3194 {
3195 if (!coords)
3196 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003197 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003198 return false;
3199 }
3200 }
3201
3202 std::uint32_t coordTypeSize = 0;
3203 switch (coordType)
3204 {
3205 case GL_BYTE:
3206 coordTypeSize = sizeof(GLbyte);
3207 break;
3208
3209 case GL_UNSIGNED_BYTE:
3210 coordTypeSize = sizeof(GLubyte);
3211 break;
3212
3213 case GL_SHORT:
3214 coordTypeSize = sizeof(GLshort);
3215 break;
3216
3217 case GL_UNSIGNED_SHORT:
3218 coordTypeSize = sizeof(GLushort);
3219 break;
3220
3221 case GL_FLOAT:
3222 coordTypeSize = sizeof(GLfloat);
3223 break;
3224
3225 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003226 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003227 return false;
3228 }
3229
3230 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3231 checkedSize += (coordTypeSize * numCoords);
3232 if (!checkedSize.IsValid())
3233 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003234 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003235 return false;
3236 }
3237
3238 // early return skips command data validation when it doesn't exist.
3239 if (!commands)
3240 return true;
3241
3242 GLsizei expectedNumCoords = 0;
3243 for (GLsizei i = 0; i < numCommands; ++i)
3244 {
3245 switch (commands[i])
3246 {
3247 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3248 break;
3249 case GL_MOVE_TO_CHROMIUM:
3250 case GL_LINE_TO_CHROMIUM:
3251 expectedNumCoords += 2;
3252 break;
3253 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3254 expectedNumCoords += 4;
3255 break;
3256 case GL_CUBIC_CURVE_TO_CHROMIUM:
3257 expectedNumCoords += 6;
3258 break;
3259 case GL_CONIC_CURVE_TO_CHROMIUM:
3260 expectedNumCoords += 5;
3261 break;
3262 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003263 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003264 return false;
3265 }
3266 }
3267 if (expectedNumCoords != numCoords)
3268 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003269 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003270 return false;
3271 }
3272
3273 return true;
3274}
3275
Jamie Madill007530e2017-12-28 14:27:04 -05003276bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003277{
3278 if (!context->getExtensions().pathRendering)
3279 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003280 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003281 return false;
3282 }
Brandon Jones59770802018-04-02 13:18:42 -07003283 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003284 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003285 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003286 return false;
3287 }
3288
3289 switch (pname)
3290 {
3291 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3292 if (value < 0.0f)
3293 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003294 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003295 return false;
3296 }
3297 break;
3298 case GL_PATH_END_CAPS_CHROMIUM:
3299 switch (static_cast<GLenum>(value))
3300 {
3301 case GL_FLAT_CHROMIUM:
3302 case GL_SQUARE_CHROMIUM:
3303 case GL_ROUND_CHROMIUM:
3304 break;
3305 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003306 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003307 return false;
3308 }
3309 break;
3310 case GL_PATH_JOIN_STYLE_CHROMIUM:
3311 switch (static_cast<GLenum>(value))
3312 {
3313 case GL_MITER_REVERT_CHROMIUM:
3314 case GL_BEVEL_CHROMIUM:
3315 case GL_ROUND_CHROMIUM:
3316 break;
3317 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003318 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003319 return false;
3320 }
Nico Weber41b072b2018-02-09 10:01:32 -05003321 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003322 case GL_PATH_MITER_LIMIT_CHROMIUM:
3323 if (value < 0.0f)
3324 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003325 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003326 return false;
3327 }
3328 break;
3329
3330 case GL_PATH_STROKE_BOUND_CHROMIUM:
3331 // no errors, only clamping.
3332 break;
3333
3334 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003335 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003336 return false;
3337 }
3338 return true;
3339}
3340
Jamie Madill007530e2017-12-28 14:27:04 -05003341bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3342{
3343 // TODO(jmadill): Use proper clamping cast.
3344 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3345}
3346
3347bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003348{
3349 if (!context->getExtensions().pathRendering)
3350 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003351 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003352 return false;
3353 }
3354
Brandon Jones59770802018-04-02 13:18:42 -07003355 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003356 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003358 return false;
3359 }
3360 if (!value)
3361 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003362 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003363 return false;
3364 }
3365
3366 switch (pname)
3367 {
3368 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3369 case GL_PATH_END_CAPS_CHROMIUM:
3370 case GL_PATH_JOIN_STYLE_CHROMIUM:
3371 case GL_PATH_MITER_LIMIT_CHROMIUM:
3372 case GL_PATH_STROKE_BOUND_CHROMIUM:
3373 break;
3374
3375 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003376 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003377 return false;
3378 }
3379
3380 return true;
3381}
3382
Jamie Madill007530e2017-12-28 14:27:04 -05003383bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3384{
3385 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3386 reinterpret_cast<GLfloat *>(value));
3387}
3388
3389bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003390{
3391 if (!context->getExtensions().pathRendering)
3392 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003393 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003394 return false;
3395 }
3396
3397 switch (func)
3398 {
3399 case GL_NEVER:
3400 case GL_ALWAYS:
3401 case GL_LESS:
3402 case GL_LEQUAL:
3403 case GL_EQUAL:
3404 case GL_GEQUAL:
3405 case GL_GREATER:
3406 case GL_NOTEQUAL:
3407 break;
3408 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003409 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003410 return false;
3411 }
3412
3413 return true;
3414}
3415
3416// Note that the spec specifies that for the path drawing commands
3417// if the path object is not an existing path object the command
3418// does nothing and no error is generated.
3419// However if the path object exists but has not been specified any
3420// commands then an error is generated.
3421
Jamie Madill007530e2017-12-28 14:27:04 -05003422bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003423{
3424 if (!context->getExtensions().pathRendering)
3425 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003426 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003427 return false;
3428 }
Brandon Jones59770802018-04-02 13:18:42 -07003429 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003430 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003431 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003432 return false;
3433 }
3434
3435 switch (fillMode)
3436 {
3437 case GL_COUNT_UP_CHROMIUM:
3438 case GL_COUNT_DOWN_CHROMIUM:
3439 break;
3440 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003441 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003442 return false;
3443 }
3444
3445 if (!isPow2(mask + 1))
3446 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003447 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003448 return false;
3449 }
3450
3451 return true;
3452}
3453
Jamie Madill007530e2017-12-28 14:27:04 -05003454bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003455{
3456 if (!context->getExtensions().pathRendering)
3457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003458 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003459 return false;
3460 }
Brandon Jones59770802018-04-02 13:18:42 -07003461 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003462 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003463 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003464 return false;
3465 }
3466
3467 return true;
3468}
3469
Brandon Jonesd1049182018-03-28 10:02:20 -07003470bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3471{
3472 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3473}
3474
3475bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3476{
3477 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3478}
3479
Jamie Madill007530e2017-12-28 14:27:04 -05003480bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003481{
3482 if (!context->getExtensions().pathRendering)
3483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003484 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003485 return false;
3486 }
Brandon Jones59770802018-04-02 13:18:42 -07003487 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003488 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003489 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003490 return false;
3491 }
3492
3493 switch (coverMode)
3494 {
3495 case GL_CONVEX_HULL_CHROMIUM:
3496 case GL_BOUNDING_BOX_CHROMIUM:
3497 break;
3498 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003499 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003500 return false;
3501 }
3502 return true;
3503}
3504
Jamie Madill007530e2017-12-28 14:27:04 -05003505bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3506 GLuint path,
3507 GLenum fillMode,
3508 GLuint mask,
3509 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510{
Jamie Madill007530e2017-12-28 14:27:04 -05003511 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3512 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003513}
3514
Jamie Madill007530e2017-12-28 14:27:04 -05003515bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3516 GLuint path,
3517 GLint reference,
3518 GLuint mask,
3519 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003520{
Jamie Madill007530e2017-12-28 14:27:04 -05003521 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3522 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003523}
3524
Brandon Jonesd1049182018-03-28 10:02:20 -07003525bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003526{
3527 if (!context->getExtensions().pathRendering)
3528 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003529 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003530 return false;
3531 }
3532 return true;
3533}
3534
Jamie Madill007530e2017-12-28 14:27:04 -05003535bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3536 GLsizei numPaths,
3537 GLenum pathNameType,
3538 const void *paths,
3539 GLuint pathBase,
3540 GLenum coverMode,
3541 GLenum transformType,
3542 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003543{
3544 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3545 transformType, transformValues))
3546 return false;
3547
3548 switch (coverMode)
3549 {
3550 case GL_CONVEX_HULL_CHROMIUM:
3551 case GL_BOUNDING_BOX_CHROMIUM:
3552 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3553 break;
3554 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003555 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003556 return false;
3557 }
3558
3559 return true;
3560}
3561
Jamie Madill007530e2017-12-28 14:27:04 -05003562bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3563 GLsizei numPaths,
3564 GLenum pathNameType,
3565 const void *paths,
3566 GLuint pathBase,
3567 GLenum coverMode,
3568 GLenum transformType,
3569 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003570{
3571 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3572 transformType, transformValues))
3573 return false;
3574
3575 switch (coverMode)
3576 {
3577 case GL_CONVEX_HULL_CHROMIUM:
3578 case GL_BOUNDING_BOX_CHROMIUM:
3579 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3580 break;
3581 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003582 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003583 return false;
3584 }
3585
3586 return true;
3587}
3588
Jamie Madill007530e2017-12-28 14:27:04 -05003589bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3590 GLsizei numPaths,
3591 GLenum pathNameType,
3592 const void *paths,
3593 GLuint pathBase,
3594 GLenum fillMode,
3595 GLuint mask,
3596 GLenum transformType,
3597 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003598{
3599
3600 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3601 transformType, transformValues))
3602 return false;
3603
3604 switch (fillMode)
3605 {
3606 case GL_COUNT_UP_CHROMIUM:
3607 case GL_COUNT_DOWN_CHROMIUM:
3608 break;
3609 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003610 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003611 return false;
3612 }
3613 if (!isPow2(mask + 1))
3614 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003615 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003616 return false;
3617 }
3618 return true;
3619}
3620
Jamie Madill007530e2017-12-28 14:27:04 -05003621bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3622 GLsizei numPaths,
3623 GLenum pathNameType,
3624 const void *paths,
3625 GLuint pathBase,
3626 GLint reference,
3627 GLuint mask,
3628 GLenum transformType,
3629 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003630{
3631 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3632 transformType, transformValues))
3633 return false;
3634
3635 // no more validation here.
3636
3637 return true;
3638}
3639
Jamie Madill007530e2017-12-28 14:27:04 -05003640bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3641 GLsizei numPaths,
3642 GLenum pathNameType,
3643 const void *paths,
3644 GLuint pathBase,
3645 GLenum fillMode,
3646 GLuint mask,
3647 GLenum coverMode,
3648 GLenum transformType,
3649 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003650{
3651 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3652 transformType, transformValues))
3653 return false;
3654
3655 switch (coverMode)
3656 {
3657 case GL_CONVEX_HULL_CHROMIUM:
3658 case GL_BOUNDING_BOX_CHROMIUM:
3659 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3660 break;
3661 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003662 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003663 return false;
3664 }
3665
3666 switch (fillMode)
3667 {
3668 case GL_COUNT_UP_CHROMIUM:
3669 case GL_COUNT_DOWN_CHROMIUM:
3670 break;
3671 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003672 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003673 return false;
3674 }
3675 if (!isPow2(mask + 1))
3676 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003677 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003678 return false;
3679 }
3680
3681 return true;
3682}
3683
Jamie Madill007530e2017-12-28 14:27:04 -05003684bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3685 GLsizei numPaths,
3686 GLenum pathNameType,
3687 const void *paths,
3688 GLuint pathBase,
3689 GLint reference,
3690 GLuint mask,
3691 GLenum coverMode,
3692 GLenum transformType,
3693 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003694{
3695 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3696 transformType, transformValues))
3697 return false;
3698
3699 switch (coverMode)
3700 {
3701 case GL_CONVEX_HULL_CHROMIUM:
3702 case GL_BOUNDING_BOX_CHROMIUM:
3703 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3704 break;
3705 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003706 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003707 return false;
3708 }
3709
3710 return true;
3711}
3712
Jamie Madill007530e2017-12-28 14:27:04 -05003713bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3714 GLuint program,
3715 GLint location,
3716 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003717{
3718 if (!context->getExtensions().pathRendering)
3719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003720 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003721 return false;
3722 }
3723
3724 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3725 if (location >= MaxLocation)
3726 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003727 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003728 return false;
3729 }
3730
3731 const auto *programObject = context->getProgram(program);
3732 if (!programObject)
3733 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003734 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003735 return false;
3736 }
3737
3738 if (!name)
3739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003740 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003741 return false;
3742 }
3743
3744 if (angle::BeginsWith(name, "gl_"))
3745 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003746 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003747 return false;
3748 }
3749
3750 return true;
3751}
3752
Jamie Madill007530e2017-12-28 14:27:04 -05003753bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3754 GLuint program,
3755 GLint location,
3756 GLenum genMode,
3757 GLint components,
3758 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003759{
3760 if (!context->getExtensions().pathRendering)
3761 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003762 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003763 return false;
3764 }
3765
3766 const auto *programObject = context->getProgram(program);
3767 if (!programObject || programObject->isFlaggedForDeletion())
3768 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003769 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003770 return false;
3771 }
3772
3773 if (!programObject->isLinked())
3774 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003775 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003776 return false;
3777 }
3778
3779 switch (genMode)
3780 {
3781 case GL_NONE:
3782 if (components != 0)
3783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003784 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003785 return false;
3786 }
3787 break;
3788
3789 case GL_OBJECT_LINEAR_CHROMIUM:
3790 case GL_EYE_LINEAR_CHROMIUM:
3791 case GL_CONSTANT_CHROMIUM:
3792 if (components < 1 || components > 4)
3793 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003794 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003795 return false;
3796 }
3797 if (!coeffs)
3798 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003799 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003800 return false;
3801 }
3802 break;
3803
3804 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003805 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003806 return false;
3807 }
3808
3809 // If the location is -1 then the command is silently ignored
3810 // and no further validation is needed.
3811 if (location == -1)
3812 return true;
3813
Jamie Madillbd044ed2017-06-05 12:59:21 -04003814 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003815
3816 if (!binding.valid)
3817 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003818 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003819 return false;
3820 }
3821
3822 if (binding.type != GL_NONE)
3823 {
3824 GLint expectedComponents = 0;
3825 switch (binding.type)
3826 {
3827 case GL_FLOAT:
3828 expectedComponents = 1;
3829 break;
3830 case GL_FLOAT_VEC2:
3831 expectedComponents = 2;
3832 break;
3833 case GL_FLOAT_VEC3:
3834 expectedComponents = 3;
3835 break;
3836 case GL_FLOAT_VEC4:
3837 expectedComponents = 4;
3838 break;
3839 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003840 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003841 InvalidOperation()
3842 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003843 return false;
3844 }
3845 if (expectedComponents != components && genMode != GL_NONE)
3846 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003847 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003848 return false;
3849 }
3850 }
3851 return true;
3852}
3853
Geoff Lang97073d12016-04-20 10:42:34 -07003854bool ValidateCopyTextureCHROMIUM(Context *context,
3855 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003856 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003857 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003858 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003859 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003860 GLint internalFormat,
3861 GLenum destType,
3862 GLboolean unpackFlipY,
3863 GLboolean unpackPremultiplyAlpha,
3864 GLboolean unpackUnmultiplyAlpha)
3865{
3866 if (!context->getExtensions().copyTexture)
3867 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003868 context->handleError(InvalidOperation()
3869 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003870 return false;
3871 }
3872
Geoff Lang4f0e0032017-05-01 16:04:35 -04003873 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003874 if (source == nullptr)
3875 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003876 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003877 return false;
3878 }
3879
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003880 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003881 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003882 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003883 return false;
3884 }
3885
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003886 TextureType sourceType = source->getType();
3887 ASSERT(sourceType != TextureType::CubeMap);
3888 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003889
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003890 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003892 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003893 return false;
3894 }
3895
Geoff Lang4f0e0032017-05-01 16:04:35 -04003896 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3897 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3898 if (sourceWidth == 0 || sourceHeight == 0)
3899 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003900 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003901 return false;
3902 }
3903
3904 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3905 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003906 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003907 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003908 return false;
3909 }
3910
Geoff Lang63458a32017-10-30 15:16:53 -04003911 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3912 {
3913 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3914 return false;
3915 }
3916
Geoff Lang4f0e0032017-05-01 16:04:35 -04003917 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003918 if (dest == nullptr)
3919 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003920 context->handleError(InvalidValue()
3921 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003922 return false;
3923 }
3924
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003925 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003926 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003927 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003928 return false;
3929 }
3930
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003931 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003932 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003933 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003934 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003935 return false;
3936 }
3937
Geoff Lang97073d12016-04-20 10:42:34 -07003938 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3939 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003940 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003941 return false;
3942 }
3943
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003944 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003945 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003946 context->handleError(
3947 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003948 return false;
3949 }
3950
Geoff Lang97073d12016-04-20 10:42:34 -07003951 if (dest->getImmutableFormat())
3952 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003953 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003954 return false;
3955 }
3956
3957 return true;
3958}
3959
3960bool ValidateCopySubTextureCHROMIUM(Context *context,
3961 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003962 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003963 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003964 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003965 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003966 GLint xoffset,
3967 GLint yoffset,
3968 GLint x,
3969 GLint y,
3970 GLsizei width,
3971 GLsizei height,
3972 GLboolean unpackFlipY,
3973 GLboolean unpackPremultiplyAlpha,
3974 GLboolean unpackUnmultiplyAlpha)
3975{
3976 if (!context->getExtensions().copyTexture)
3977 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003978 context->handleError(InvalidOperation()
3979 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003980 return false;
3981 }
3982
Geoff Lang4f0e0032017-05-01 16:04:35 -04003983 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003984 if (source == nullptr)
3985 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003986 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003987 return false;
3988 }
3989
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003990 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003991 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003992 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003993 return false;
3994 }
3995
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003996 TextureType sourceType = source->getType();
3997 ASSERT(sourceType != TextureType::CubeMap);
3998 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003999
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004000 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004001 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004002 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004003 return false;
4004 }
4005
4006 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4007 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004008 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004009 context->handleError(InvalidValue()
4010 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004011 return false;
4012 }
4013
4014 if (x < 0 || y < 0)
4015 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004016 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004017 return false;
4018 }
4019
4020 if (width < 0 || height < 0)
4021 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004022 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004023 return false;
4024 }
4025
Geoff Lang4f0e0032017-05-01 16:04:35 -04004026 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4027 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004028 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004029 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004030 return false;
4031 }
4032
Geoff Lang4f0e0032017-05-01 16:04:35 -04004033 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4034 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004035 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004036 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004037 return false;
4038 }
4039
Geoff Lang63458a32017-10-30 15:16:53 -04004040 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4041 {
4042 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4043 return false;
4044 }
4045
Geoff Lang4f0e0032017-05-01 16:04:35 -04004046 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004047 if (dest == nullptr)
4048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004049 context->handleError(InvalidValue()
4050 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004051 return false;
4052 }
4053
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004054 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004055 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004056 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004057 return false;
4058 }
4059
Brandon Jones28783792018-03-05 09:37:32 -08004060 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4061 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004062 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004063 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004064 return false;
4065 }
4066
Geoff Lang4f0e0032017-05-01 16:04:35 -04004067 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4068 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004069 context
4070 ->handleError(InvalidOperation()
4071 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004072 return false;
4073 }
4074
4075 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4076 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004077 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004078 context->handleError(InvalidOperation()
4079 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004080 return false;
4081 }
4082
4083 if (xoffset < 0 || yoffset < 0)
4084 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004085 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004086 return false;
4087 }
4088
Geoff Lang4f0e0032017-05-01 16:04:35 -04004089 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4090 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004091 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004092 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004093 return false;
4094 }
4095
4096 return true;
4097}
4098
Geoff Lang47110bf2016-04-20 11:13:22 -07004099bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4100{
4101 if (!context->getExtensions().copyCompressedTexture)
4102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004103 context->handleError(InvalidOperation()
4104 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004105 return false;
4106 }
4107
4108 const gl::Texture *source = context->getTexture(sourceId);
4109 if (source == nullptr)
4110 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004111 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004112 return false;
4113 }
4114
Corentin Wallez99d492c2018-02-27 15:17:10 -05004115 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004117 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004118 return false;
4119 }
4120
Corentin Wallez99d492c2018-02-27 15:17:10 -05004121 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4122 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004124 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004125 return false;
4126 }
4127
Corentin Wallez99d492c2018-02-27 15:17:10 -05004128 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004129 if (!sourceFormat.info->compressed)
4130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004131 context->handleError(InvalidOperation()
4132 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004133 return false;
4134 }
4135
4136 const gl::Texture *dest = context->getTexture(destId);
4137 if (dest == nullptr)
4138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004139 context->handleError(InvalidValue()
4140 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004141 return false;
4142 }
4143
Corentin Wallez99d492c2018-02-27 15:17:10 -05004144 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004145 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004146 context->handleError(InvalidValue()
4147 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004148 return false;
4149 }
4150
4151 if (dest->getImmutableFormat())
4152 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004153 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004154 return false;
4155 }
4156
4157 return true;
4158}
4159
Jiawei Shao385b3e02018-03-21 09:43:28 +08004160bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004161{
4162 switch (type)
4163 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004164 case ShaderType::Vertex:
4165 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004166 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004167
Jiawei Shao385b3e02018-03-21 09:43:28 +08004168 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004169 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004170 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004171 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004172 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004173 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004174 break;
4175
Jiawei Shao385b3e02018-03-21 09:43:28 +08004176 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004177 if (!context->getExtensions().geometryShader)
4178 {
4179 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4180 return false;
4181 }
4182 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004183 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004184 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004185 return false;
4186 }
Jamie Madill29639852016-09-02 15:00:09 -04004187
4188 return true;
4189}
4190
Jamie Madill5b772312018-03-08 20:28:32 -05004191bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004192 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004193 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004194 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004195 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004196{
4197 if (size < 0)
4198 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004199 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004200 return false;
4201 }
4202
4203 switch (usage)
4204 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004205 case BufferUsage::StreamDraw:
4206 case BufferUsage::StaticDraw:
4207 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004208 break;
4209
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004210 case BufferUsage::StreamRead:
4211 case BufferUsage::StaticRead:
4212 case BufferUsage::DynamicRead:
4213 case BufferUsage::StreamCopy:
4214 case BufferUsage::StaticCopy:
4215 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004216 if (context->getClientMajorVersion() < 3)
4217 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004218 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004219 return false;
4220 }
4221 break;
4222
4223 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004224 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004225 return false;
4226 }
4227
Corentin Walleze4477002017-12-01 14:39:58 -05004228 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004229 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004230 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004231 return false;
4232 }
4233
4234 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4235
4236 if (!buffer)
4237 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004238 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004239 return false;
4240 }
4241
James Darpiniane8a93c62018-01-04 18:02:24 -08004242 if (context->getExtensions().webglCompatibility &&
4243 buffer->isBoundForTransformFeedbackAndOtherUse())
4244 {
4245 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4246 return false;
4247 }
4248
Jamie Madill29639852016-09-02 15:00:09 -04004249 return true;
4250}
4251
Jamie Madill5b772312018-03-08 20:28:32 -05004252bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004253 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004254 GLintptr offset,
4255 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004256 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004257{
Brandon Jones6cad5662017-06-14 13:25:13 -07004258 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004259 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004260 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4261 return false;
4262 }
4263
4264 if (offset < 0)
4265 {
4266 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004267 return false;
4268 }
4269
Corentin Walleze4477002017-12-01 14:39:58 -05004270 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004271 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004272 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004273 return false;
4274 }
4275
4276 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4277
4278 if (!buffer)
4279 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004280 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004281 return false;
4282 }
4283
4284 if (buffer->isMapped())
4285 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004286 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004287 return false;
4288 }
4289
James Darpiniane8a93c62018-01-04 18:02:24 -08004290 if (context->getExtensions().webglCompatibility &&
4291 buffer->isBoundForTransformFeedbackAndOtherUse())
4292 {
4293 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4294 return false;
4295 }
4296
Jamie Madill29639852016-09-02 15:00:09 -04004297 // Check for possible overflow of size + offset
4298 angle::CheckedNumeric<size_t> checkedSize(size);
4299 checkedSize += offset;
4300 if (!checkedSize.IsValid())
4301 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004302 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004303 return false;
4304 }
4305
4306 if (size + offset > buffer->getSize())
4307 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004308 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004309 return false;
4310 }
4311
Martin Radev4c4c8e72016-08-04 12:25:34 +03004312 return true;
4313}
4314
Geoff Lang111a99e2017-10-17 10:58:41 -04004315bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004316{
Geoff Langc339c4e2016-11-29 10:37:36 -05004317 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004318 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004319 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004320 return false;
4321 }
4322
Geoff Lang111a99e2017-10-17 10:58:41 -04004323 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004324 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004325 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004326 return false;
4327 }
4328
4329 return true;
4330}
4331
Jamie Madill5b772312018-03-08 20:28:32 -05004332bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004333{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004334 if (context->getClientMajorVersion() < 2)
4335 {
4336 return ValidateMultitextureUnit(context, texture);
4337 }
4338
Jamie Madillef300b12016-10-07 15:12:09 -04004339 if (texture < GL_TEXTURE0 ||
4340 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4341 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004342 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004343 return false;
4344 }
4345
4346 return true;
4347}
4348
Jamie Madill5b772312018-03-08 20:28:32 -05004349bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004350{
4351 Program *programObject = GetValidProgram(context, program);
4352 if (!programObject)
4353 {
4354 return false;
4355 }
4356
4357 Shader *shaderObject = GetValidShader(context, shader);
4358 if (!shaderObject)
4359 {
4360 return false;
4361 }
4362
Jiawei Shao385b3e02018-03-21 09:43:28 +08004363 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004364 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004365 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4366 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004367 }
4368
4369 return true;
4370}
4371
Jamie Madill5b772312018-03-08 20:28:32 -05004372bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004373{
4374 if (index >= MAX_VERTEX_ATTRIBS)
4375 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004376 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004377 return false;
4378 }
4379
4380 if (strncmp(name, "gl_", 3) == 0)
4381 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004383 return false;
4384 }
4385
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004386 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004387 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004388 const size_t length = strlen(name);
4389
4390 if (!IsValidESSLString(name, length))
4391 {
4392 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4393 // for shader-related entry points
4394 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4395 return false;
4396 }
4397
4398 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4399 {
4400 return false;
4401 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004402 }
4403
Jamie Madill01a80ee2016-11-07 12:06:18 -05004404 return GetValidProgram(context, program) != nullptr;
4405}
4406
Jamie Madill5b772312018-03-08 20:28:32 -05004407bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004408{
Corentin Walleze4477002017-12-01 14:39:58 -05004409 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004410 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004411 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004412 return false;
4413 }
4414
4415 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4416 !context->isBufferGenerated(buffer))
4417 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004418 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004419 return false;
4420 }
4421
4422 return true;
4423}
4424
Jamie Madill5b772312018-03-08 20:28:32 -05004425bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004426{
Geoff Lange8afa902017-09-27 15:00:43 -04004427 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004428 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004429 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004430 return false;
4431 }
4432
4433 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4434 !context->isFramebufferGenerated(framebuffer))
4435 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004436 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004437 return false;
4438 }
4439
4440 return true;
4441}
4442
Jamie Madill5b772312018-03-08 20:28:32 -05004443bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444{
4445 if (target != GL_RENDERBUFFER)
4446 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004447 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004448 return false;
4449 }
4450
4451 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4452 !context->isRenderbufferGenerated(renderbuffer))
4453 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004454 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004455 return false;
4456 }
4457
4458 return true;
4459}
4460
Jamie Madill5b772312018-03-08 20:28:32 -05004461static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004462{
4463 switch (mode)
4464 {
4465 case GL_FUNC_ADD:
4466 case GL_FUNC_SUBTRACT:
4467 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004468 return true;
4469
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004470 case GL_MIN:
4471 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004472 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004473
4474 default:
4475 return false;
4476 }
4477}
4478
Jamie Madill5b772312018-03-08 20:28:32 -05004479bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004480{
4481 return true;
4482}
4483
Jamie Madill5b772312018-03-08 20:28:32 -05004484bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004485{
Geoff Lang50cac572017-09-26 17:37:43 -04004486 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004487 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004488 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004489 return false;
4490 }
4491
4492 return true;
4493}
4494
Jamie Madill5b772312018-03-08 20:28:32 -05004495bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004496{
Geoff Lang50cac572017-09-26 17:37:43 -04004497 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004498 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004499 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004500 return false;
4501 }
4502
Geoff Lang50cac572017-09-26 17:37:43 -04004503 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004504 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004505 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004506 return false;
4507 }
4508
4509 return true;
4510}
4511
Jamie Madill5b772312018-03-08 20:28:32 -05004512bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004513{
4514 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4515}
4516
4517static bool ValidSrcBlendFunc(GLenum srcBlend)
4518{
4519 switch (srcBlend)
4520 {
4521 case GL_ZERO:
4522 case GL_ONE:
4523 case GL_SRC_COLOR:
4524 case GL_ONE_MINUS_SRC_COLOR:
4525 case GL_DST_COLOR:
4526 case GL_ONE_MINUS_DST_COLOR:
4527 case GL_SRC_ALPHA:
4528 case GL_ONE_MINUS_SRC_ALPHA:
4529 case GL_DST_ALPHA:
4530 case GL_ONE_MINUS_DST_ALPHA:
4531 case GL_CONSTANT_COLOR:
4532 case GL_ONE_MINUS_CONSTANT_COLOR:
4533 case GL_CONSTANT_ALPHA:
4534 case GL_ONE_MINUS_CONSTANT_ALPHA:
4535 case GL_SRC_ALPHA_SATURATE:
4536 return true;
4537
4538 default:
4539 return false;
4540 }
4541}
4542
4543static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4544{
4545 switch (dstBlend)
4546 {
4547 case GL_ZERO:
4548 case GL_ONE:
4549 case GL_SRC_COLOR:
4550 case GL_ONE_MINUS_SRC_COLOR:
4551 case GL_DST_COLOR:
4552 case GL_ONE_MINUS_DST_COLOR:
4553 case GL_SRC_ALPHA:
4554 case GL_ONE_MINUS_SRC_ALPHA:
4555 case GL_DST_ALPHA:
4556 case GL_ONE_MINUS_DST_ALPHA:
4557 case GL_CONSTANT_COLOR:
4558 case GL_ONE_MINUS_CONSTANT_COLOR:
4559 case GL_CONSTANT_ALPHA:
4560 case GL_ONE_MINUS_CONSTANT_ALPHA:
4561 return true;
4562
4563 case GL_SRC_ALPHA_SATURATE:
4564 return (contextMajorVersion >= 3);
4565
4566 default:
4567 return false;
4568 }
4569}
4570
Jamie Madill5b772312018-03-08 20:28:32 -05004571bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004572 GLenum srcRGB,
4573 GLenum dstRGB,
4574 GLenum srcAlpha,
4575 GLenum dstAlpha)
4576{
4577 if (!ValidSrcBlendFunc(srcRGB))
4578 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004579 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004580 return false;
4581 }
4582
4583 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4584 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004585 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004586 return false;
4587 }
4588
4589 if (!ValidSrcBlendFunc(srcAlpha))
4590 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004591 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004592 return false;
4593 }
4594
4595 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4596 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004597 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004598 return false;
4599 }
4600
Frank Henigman146e8a12017-03-02 23:22:37 -05004601 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4602 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004603 {
4604 bool constantColorUsed =
4605 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4606 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4607
4608 bool constantAlphaUsed =
4609 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4610 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4611
4612 if (constantColorUsed && constantAlphaUsed)
4613 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004614 const char *msg;
4615 if (context->getExtensions().webglCompatibility)
4616 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004617 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004618 }
4619 else
4620 {
4621 msg =
4622 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4623 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4624 "implementation.";
4625 ERR() << msg;
4626 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004627 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004628 return false;
4629 }
4630 }
4631
4632 return true;
4633}
4634
Geoff Langc339c4e2016-11-29 10:37:36 -05004635bool ValidateGetString(Context *context, GLenum name)
4636{
4637 switch (name)
4638 {
4639 case GL_VENDOR:
4640 case GL_RENDERER:
4641 case GL_VERSION:
4642 case GL_SHADING_LANGUAGE_VERSION:
4643 case GL_EXTENSIONS:
4644 break;
4645
4646 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4647 if (!context->getExtensions().requestExtension)
4648 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004649 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004650 return false;
4651 }
4652 break;
4653
4654 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004655 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004656 return false;
4657 }
4658
4659 return true;
4660}
4661
Jamie Madill5b772312018-03-08 20:28:32 -05004662bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004663{
4664 if (width <= 0.0f || isNaN(width))
4665 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004666 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004667 return false;
4668 }
4669
4670 return true;
4671}
4672
Jamie Madill5b772312018-03-08 20:28:32 -05004673bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004674 GLuint index,
4675 GLint size,
4676 GLenum type,
4677 GLboolean normalized,
4678 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004679 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004680{
Shao80957d92017-02-20 21:25:59 +08004681 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004682 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004683 return false;
4684 }
4685
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004686 if (stride < 0)
4687 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004688 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004689 return false;
4690 }
4691
Shao80957d92017-02-20 21:25:59 +08004692 const Caps &caps = context->getCaps();
4693 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004694 {
Shao80957d92017-02-20 21:25:59 +08004695 if (stride > caps.maxVertexAttribStride)
4696 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004697 context->handleError(InvalidValue()
4698 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004699 return false;
4700 }
4701
4702 if (index >= caps.maxVertexAttribBindings)
4703 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004704 context->handleError(InvalidValue()
4705 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004706 return false;
4707 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004708 }
4709
4710 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4711 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4712 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4713 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004714 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4715 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004716 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4717 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004718 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004719 context
4720 ->handleError(InvalidOperation()
4721 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004722 return false;
4723 }
4724
4725 if (context->getExtensions().webglCompatibility)
4726 {
4727 // WebGL 1.0 [Section 6.14] Fixed point support
4728 // The WebGL API does not support the GL_FIXED data type.
4729 if (type == GL_FIXED)
4730 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004731 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004732 return false;
4733 }
4734
Geoff Lang2d62ab72017-03-23 16:54:40 -04004735 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004736 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004737 return false;
4738 }
4739 }
4740
4741 return true;
4742}
4743
Jamie Madill5b772312018-03-08 20:28:32 -05004744bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004745{
4746 if (context->getExtensions().webglCompatibility && zNear > zFar)
4747 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004748 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004749 return false;
4750 }
4751
4752 return true;
4753}
4754
Jamie Madill5b772312018-03-08 20:28:32 -05004755bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004756 GLenum target,
4757 GLenum internalformat,
4758 GLsizei width,
4759 GLsizei height)
4760{
4761 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4762 height);
4763}
4764
Jamie Madill5b772312018-03-08 20:28:32 -05004765bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004766 GLenum target,
4767 GLsizei samples,
4768 GLenum internalformat,
4769 GLsizei width,
4770 GLsizei height)
4771{
4772 if (!context->getExtensions().framebufferMultisample)
4773 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004774 context->handleError(InvalidOperation()
4775 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004776 return false;
4777 }
4778
4779 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4780 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4781 // generated.
4782 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004784 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004785 return false;
4786 }
4787
4788 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4789 // the specified storage. This is different than ES 3.0 in which a sample number higher
4790 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4791 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4792 if (context->getClientMajorVersion() >= 3)
4793 {
4794 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4795 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4796 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004797 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004798 return false;
4799 }
4800 }
4801
4802 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4803 width, height);
4804}
4805
Jamie Madill5b772312018-03-08 20:28:32 -05004806bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004807{
Geoff Lange8afa902017-09-27 15:00:43 -04004808 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004809 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004810 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004811 return false;
4812 }
4813
4814 return true;
4815}
4816
Jamie Madill5b772312018-03-08 20:28:32 -05004817bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004818{
4819 return true;
4820}
4821
Jamie Madill5b772312018-03-08 20:28:32 -05004822bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004823{
4824 return true;
4825}
4826
Jamie Madill5b772312018-03-08 20:28:32 -05004827bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004828{
4829 return true;
4830}
4831
Jamie Madill5b772312018-03-08 20:28:32 -05004832bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004833 GLboolean red,
4834 GLboolean green,
4835 GLboolean blue,
4836 GLboolean alpha)
4837{
4838 return true;
4839}
4840
Jamie Madill5b772312018-03-08 20:28:32 -05004841bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004842{
4843 return true;
4844}
4845
Jamie Madill5b772312018-03-08 20:28:32 -05004846bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004847{
4848 return true;
4849}
4850
Jamie Madill5b772312018-03-08 20:28:32 -05004851bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004852{
4853 switch (mode)
4854 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004855 case CullFaceMode::Front:
4856 case CullFaceMode::Back:
4857 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004858 break;
4859
4860 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004861 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004862 return false;
4863 }
4864
4865 return true;
4866}
4867
Jamie Madill5b772312018-03-08 20:28:32 -05004868bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004869{
4870 if (program == 0)
4871 {
4872 return false;
4873 }
4874
4875 if (!context->getProgram(program))
4876 {
4877 if (context->getShader(program))
4878 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004879 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004880 return false;
4881 }
4882 else
4883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004884 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004885 return false;
4886 }
4887 }
4888
4889 return true;
4890}
4891
Jamie Madill5b772312018-03-08 20:28:32 -05004892bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004893{
4894 if (shader == 0)
4895 {
4896 return false;
4897 }
4898
4899 if (!context->getShader(shader))
4900 {
4901 if (context->getProgram(shader))
4902 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004903 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004904 return false;
4905 }
4906 else
4907 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004908 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004909 return false;
4910 }
4911 }
4912
4913 return true;
4914}
4915
Jamie Madill5b772312018-03-08 20:28:32 -05004916bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004917{
4918 switch (func)
4919 {
4920 case GL_NEVER:
4921 case GL_ALWAYS:
4922 case GL_LESS:
4923 case GL_LEQUAL:
4924 case GL_EQUAL:
4925 case GL_GREATER:
4926 case GL_GEQUAL:
4927 case GL_NOTEQUAL:
4928 break;
4929
4930 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004931 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004932 return false;
4933 }
4934
4935 return true;
4936}
4937
Jamie Madill5b772312018-03-08 20:28:32 -05004938bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004939{
4940 return true;
4941}
4942
Jamie Madill5b772312018-03-08 20:28:32 -05004943bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004944{
4945 Program *programObject = GetValidProgram(context, program);
4946 if (!programObject)
4947 {
4948 return false;
4949 }
4950
4951 Shader *shaderObject = GetValidShader(context, shader);
4952 if (!shaderObject)
4953 {
4954 return false;
4955 }
4956
Jiawei Shao385b3e02018-03-21 09:43:28 +08004957 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004958 if (attachedShader != shaderObject)
4959 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004960 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004961 return false;
4962 }
4963
4964 return true;
4965}
4966
Jamie Madill5b772312018-03-08 20:28:32 -05004967bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004968{
4969 if (index >= MAX_VERTEX_ATTRIBS)
4970 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004971 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004972 return false;
4973 }
4974
4975 return true;
4976}
4977
Jamie Madill5b772312018-03-08 20:28:32 -05004978bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004979{
4980 if (index >= MAX_VERTEX_ATTRIBS)
4981 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004982 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004983 return false;
4984 }
4985
4986 return true;
4987}
4988
Jamie Madill5b772312018-03-08 20:28:32 -05004989bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004990{
4991 return true;
4992}
4993
Jamie Madill5b772312018-03-08 20:28:32 -05004994bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004995{
4996 return true;
4997}
4998
Jamie Madill5b772312018-03-08 20:28:32 -05004999bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005000{
5001 switch (mode)
5002 {
5003 case GL_CW:
5004 case GL_CCW:
5005 break;
5006 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005007 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005008 return false;
5009 }
5010
5011 return true;
5012}
5013
Jamie Madill5b772312018-03-08 20:28:32 -05005014bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005015 GLuint program,
5016 GLuint index,
5017 GLsizei bufsize,
5018 GLsizei *length,
5019 GLint *size,
5020 GLenum *type,
5021 GLchar *name)
5022{
5023 if (bufsize < 0)
5024 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005025 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005026 return false;
5027 }
5028
5029 Program *programObject = GetValidProgram(context, program);
5030
5031 if (!programObject)
5032 {
5033 return false;
5034 }
5035
5036 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5037 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005038 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005039 return false;
5040 }
5041
5042 return true;
5043}
5044
Jamie Madill5b772312018-03-08 20:28:32 -05005045bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005046 GLuint program,
5047 GLuint index,
5048 GLsizei bufsize,
5049 GLsizei *length,
5050 GLint *size,
5051 GLenum *type,
5052 GLchar *name)
5053{
5054 if (bufsize < 0)
5055 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005056 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005057 return false;
5058 }
5059
5060 Program *programObject = GetValidProgram(context, program);
5061
5062 if (!programObject)
5063 {
5064 return false;
5065 }
5066
5067 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5068 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005069 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005070 return false;
5071 }
5072
5073 return true;
5074}
5075
Jamie Madill5b772312018-03-08 20:28:32 -05005076bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005077 GLuint program,
5078 GLsizei maxcount,
5079 GLsizei *count,
5080 GLuint *shaders)
5081{
5082 if (maxcount < 0)
5083 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005084 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005085 return false;
5086 }
5087
5088 Program *programObject = GetValidProgram(context, program);
5089
5090 if (!programObject)
5091 {
5092 return false;
5093 }
5094
5095 return true;
5096}
5097
Jamie Madill5b772312018-03-08 20:28:32 -05005098bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005099{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005100 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5101 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005102 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005103 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005104 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005105 return false;
5106 }
5107
Jamie Madillc1d770e2017-04-13 17:31:24 -04005108 Program *programObject = GetValidProgram(context, program);
5109
5110 if (!programObject)
5111 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005112 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005113 return false;
5114 }
5115
5116 if (!programObject->isLinked())
5117 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005118 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005119 return false;
5120 }
5121
5122 return true;
5123}
5124
Jamie Madill5b772312018-03-08 20:28:32 -05005125bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005126{
5127 GLenum nativeType;
5128 unsigned int numParams = 0;
5129 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5130}
5131
Jamie Madill5b772312018-03-08 20:28:32 -05005132bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005133{
5134 return true;
5135}
5136
Jamie Madill5b772312018-03-08 20:28:32 -05005137bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005138{
5139 GLenum nativeType;
5140 unsigned int numParams = 0;
5141 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5142}
5143
Jamie Madill5b772312018-03-08 20:28:32 -05005144bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005145{
5146 GLenum nativeType;
5147 unsigned int numParams = 0;
5148 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5149}
5150
Jamie Madill5b772312018-03-08 20:28:32 -05005151bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005152 GLuint program,
5153 GLsizei bufsize,
5154 GLsizei *length,
5155 GLchar *infolog)
5156{
5157 if (bufsize < 0)
5158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005159 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005160 return false;
5161 }
5162
5163 Program *programObject = GetValidProgram(context, program);
5164 if (!programObject)
5165 {
5166 return false;
5167 }
5168
5169 return true;
5170}
5171
Jamie Madill5b772312018-03-08 20:28:32 -05005172bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005173 GLuint shader,
5174 GLsizei bufsize,
5175 GLsizei *length,
5176 GLchar *infolog)
5177{
5178 if (bufsize < 0)
5179 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005180 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005181 return false;
5182 }
5183
5184 Shader *shaderObject = GetValidShader(context, shader);
5185 if (!shaderObject)
5186 {
5187 return false;
5188 }
5189
5190 return true;
5191}
5192
Jamie Madill5b772312018-03-08 20:28:32 -05005193bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005194 GLenum shadertype,
5195 GLenum precisiontype,
5196 GLint *range,
5197 GLint *precision)
5198{
5199 switch (shadertype)
5200 {
5201 case GL_VERTEX_SHADER:
5202 case GL_FRAGMENT_SHADER:
5203 break;
5204 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005205 context->handleError(InvalidOperation()
5206 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005207 return false;
5208 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005209 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005210 return false;
5211 }
5212
5213 switch (precisiontype)
5214 {
5215 case GL_LOW_FLOAT:
5216 case GL_MEDIUM_FLOAT:
5217 case GL_HIGH_FLOAT:
5218 case GL_LOW_INT:
5219 case GL_MEDIUM_INT:
5220 case GL_HIGH_INT:
5221 break;
5222
5223 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005224 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005225 return false;
5226 }
5227
5228 return true;
5229}
5230
Jamie Madill5b772312018-03-08 20:28:32 -05005231bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005232 GLuint shader,
5233 GLsizei bufsize,
5234 GLsizei *length,
5235 GLchar *source)
5236{
5237 if (bufsize < 0)
5238 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005239 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005240 return false;
5241 }
5242
5243 Shader *shaderObject = GetValidShader(context, shader);
5244 if (!shaderObject)
5245 {
5246 return false;
5247 }
5248
5249 return true;
5250}
5251
Jamie Madill5b772312018-03-08 20:28:32 -05005252bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005253{
5254 if (strstr(name, "gl_") == name)
5255 {
5256 return false;
5257 }
5258
Geoff Langfc32e8b2017-05-31 14:16:59 -04005259 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5260 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005261 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005262 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005263 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005264 return false;
5265 }
5266
Jamie Madillc1d770e2017-04-13 17:31:24 -04005267 Program *programObject = GetValidProgram(context, program);
5268
5269 if (!programObject)
5270 {
5271 return false;
5272 }
5273
5274 if (!programObject->isLinked())
5275 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005276 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005277 return false;
5278 }
5279
5280 return true;
5281}
5282
Jamie Madill5b772312018-03-08 20:28:32 -05005283bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005284{
5285 switch (mode)
5286 {
5287 case GL_FASTEST:
5288 case GL_NICEST:
5289 case GL_DONT_CARE:
5290 break;
5291
5292 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005293 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005294 return false;
5295 }
5296
5297 switch (target)
5298 {
5299 case GL_GENERATE_MIPMAP_HINT:
5300 break;
5301
Geoff Lange7bd2182017-06-16 16:13:13 -04005302 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5303 if (context->getClientVersion() < ES_3_0 &&
5304 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005305 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005306 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005307 return false;
5308 }
5309 break;
5310
5311 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005312 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005313 return false;
5314 }
5315
5316 return true;
5317}
5318
Jamie Madill5b772312018-03-08 20:28:32 -05005319bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005320{
5321 return true;
5322}
5323
Jamie Madill5b772312018-03-08 20:28:32 -05005324bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005325{
5326 return true;
5327}
5328
Jamie Madill5b772312018-03-08 20:28:32 -05005329bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005330{
5331 return true;
5332}
5333
Jamie Madill5b772312018-03-08 20:28:32 -05005334bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005335{
5336 return true;
5337}
5338
Jamie Madill5b772312018-03-08 20:28:32 -05005339bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005340{
5341 return true;
5342}
5343
Jamie Madill5b772312018-03-08 20:28:32 -05005344bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345{
5346 return true;
5347}
5348
Jamie Madill5b772312018-03-08 20:28:32 -05005349bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005350{
5351 if (context->getClientMajorVersion() < 3)
5352 {
5353 switch (pname)
5354 {
5355 case GL_UNPACK_IMAGE_HEIGHT:
5356 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005357 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005358 return false;
5359
5360 case GL_UNPACK_ROW_LENGTH:
5361 case GL_UNPACK_SKIP_ROWS:
5362 case GL_UNPACK_SKIP_PIXELS:
5363 if (!context->getExtensions().unpackSubimage)
5364 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005365 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005366 return false;
5367 }
5368 break;
5369
5370 case GL_PACK_ROW_LENGTH:
5371 case GL_PACK_SKIP_ROWS:
5372 case GL_PACK_SKIP_PIXELS:
5373 if (!context->getExtensions().packSubimage)
5374 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005375 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005376 return false;
5377 }
5378 break;
5379 }
5380 }
5381
5382 if (param < 0)
5383 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005384 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385 return false;
5386 }
5387
5388 switch (pname)
5389 {
5390 case GL_UNPACK_ALIGNMENT:
5391 if (param != 1 && param != 2 && param != 4 && param != 8)
5392 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005393 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005394 return false;
5395 }
5396 break;
5397
5398 case GL_PACK_ALIGNMENT:
5399 if (param != 1 && param != 2 && param != 4 && param != 8)
5400 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005401 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005402 return false;
5403 }
5404 break;
5405
5406 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005407 if (!context->getExtensions().packReverseRowOrder)
5408 {
5409 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5410 }
5411 break;
5412
Jamie Madillc1d770e2017-04-13 17:31:24 -04005413 case GL_UNPACK_ROW_LENGTH:
5414 case GL_UNPACK_IMAGE_HEIGHT:
5415 case GL_UNPACK_SKIP_IMAGES:
5416 case GL_UNPACK_SKIP_ROWS:
5417 case GL_UNPACK_SKIP_PIXELS:
5418 case GL_PACK_ROW_LENGTH:
5419 case GL_PACK_SKIP_ROWS:
5420 case GL_PACK_SKIP_PIXELS:
5421 break;
5422
5423 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005424 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005425 return false;
5426 }
5427
5428 return true;
5429}
5430
Jamie Madill5b772312018-03-08 20:28:32 -05005431bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005432{
5433 return true;
5434}
5435
Jamie Madill5b772312018-03-08 20:28:32 -05005436bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005437{
5438 return true;
5439}
5440
Jamie Madill5b772312018-03-08 20:28:32 -05005441bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005442{
5443 return true;
5444}
5445
Jamie Madill5b772312018-03-08 20:28:32 -05005446bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005447{
5448 if (width < 0 || height < 0)
5449 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005450 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005451 return false;
5452 }
5453
5454 return true;
5455}
5456
Jamie Madill5b772312018-03-08 20:28:32 -05005457bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005458 GLsizei n,
5459 const GLuint *shaders,
5460 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005461 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005462 GLsizei length)
5463{
5464 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5465 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5466 shaderBinaryFormats.end())
5467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005468 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005469 return false;
5470 }
5471
5472 return true;
5473}
5474
Jamie Madill5b772312018-03-08 20:28:32 -05005475bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005476 GLuint shader,
5477 GLsizei count,
5478 const GLchar *const *string,
5479 const GLint *length)
5480{
5481 if (count < 0)
5482 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005483 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005484 return false;
5485 }
5486
Geoff Langfc32e8b2017-05-31 14:16:59 -04005487 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5488 // shader-related entry points
5489 if (context->getExtensions().webglCompatibility)
5490 {
5491 for (GLsizei i = 0; i < count; i++)
5492 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005493 size_t len =
5494 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005495
5496 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005497 if (!IsValidESSLShaderSourceString(string[i], len,
5498 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005499 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005500 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005501 return false;
5502 }
5503 }
5504 }
5505
Jamie Madillc1d770e2017-04-13 17:31:24 -04005506 Shader *shaderObject = GetValidShader(context, shader);
5507 if (!shaderObject)
5508 {
5509 return false;
5510 }
5511
5512 return true;
5513}
5514
Jamie Madill5b772312018-03-08 20:28:32 -05005515bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005516{
5517 if (!IsValidStencilFunc(func))
5518 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005519 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005520 return false;
5521 }
5522
5523 return true;
5524}
5525
Jamie Madill5b772312018-03-08 20:28:32 -05005526bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005527{
5528 if (!IsValidStencilFace(face))
5529 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005530 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005531 return false;
5532 }
5533
5534 if (!IsValidStencilFunc(func))
5535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005536 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005537 return false;
5538 }
5539
5540 return true;
5541}
5542
Jamie Madill5b772312018-03-08 20:28:32 -05005543bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005544{
5545 return true;
5546}
5547
Jamie Madill5b772312018-03-08 20:28:32 -05005548bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005549{
5550 if (!IsValidStencilFace(face))
5551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005552 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005553 return false;
5554 }
5555
5556 return true;
5557}
5558
Jamie Madill5b772312018-03-08 20:28:32 -05005559bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005560{
5561 if (!IsValidStencilOp(fail))
5562 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005563 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005564 return false;
5565 }
5566
5567 if (!IsValidStencilOp(zfail))
5568 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005569 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005570 return false;
5571 }
5572
5573 if (!IsValidStencilOp(zpass))
5574 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005575 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005576 return false;
5577 }
5578
5579 return true;
5580}
5581
Jamie Madill5b772312018-03-08 20:28:32 -05005582bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005583 GLenum face,
5584 GLenum fail,
5585 GLenum zfail,
5586 GLenum zpass)
5587{
5588 if (!IsValidStencilFace(face))
5589 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005590 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005591 return false;
5592 }
5593
5594 return ValidateStencilOp(context, fail, zfail, zpass);
5595}
5596
Jamie Madill5b772312018-03-08 20:28:32 -05005597bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005598{
5599 return ValidateUniform(context, GL_FLOAT, location, 1);
5600}
5601
Jamie Madill5b772312018-03-08 20:28:32 -05005602bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005603{
5604 return ValidateUniform(context, GL_FLOAT, location, count);
5605}
5606
Jamie Madill5b772312018-03-08 20:28:32 -05005607bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005608{
5609 return ValidateUniform1iv(context, location, 1, &x);
5610}
5611
Jamie Madill5b772312018-03-08 20:28:32 -05005612bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005613{
5614 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5615}
5616
Jamie Madill5b772312018-03-08 20:28:32 -05005617bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005618{
5619 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5620}
5621
Jamie Madill5b772312018-03-08 20:28:32 -05005622bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005623{
5624 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5625}
5626
Jamie Madill5b772312018-03-08 20:28:32 -05005627bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005628{
5629 return ValidateUniform(context, GL_INT_VEC2, location, count);
5630}
5631
Jamie Madill5b772312018-03-08 20:28:32 -05005632bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005633{
5634 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5635}
5636
Jamie Madill5b772312018-03-08 20:28:32 -05005637bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005638{
5639 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5640}
5641
Jamie Madill5b772312018-03-08 20:28:32 -05005642bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005643{
5644 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5645}
5646
Jamie Madill5b772312018-03-08 20:28:32 -05005647bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005648{
5649 return ValidateUniform(context, GL_INT_VEC3, location, count);
5650}
5651
Jamie Madill5b772312018-03-08 20:28:32 -05005652bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005653{
5654 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5655}
5656
Jamie Madill5b772312018-03-08 20:28:32 -05005657bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005658{
5659 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5660}
5661
Jamie Madill5b772312018-03-08 20:28:32 -05005662bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005663{
5664 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5665}
5666
Jamie Madill5b772312018-03-08 20:28:32 -05005667bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005668{
5669 return ValidateUniform(context, GL_INT_VEC4, location, count);
5670}
5671
Jamie Madill5b772312018-03-08 20:28:32 -05005672bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005673 GLint location,
5674 GLsizei count,
5675 GLboolean transpose,
5676 const GLfloat *value)
5677{
5678 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5679}
5680
Jamie Madill5b772312018-03-08 20:28:32 -05005681bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005682 GLint location,
5683 GLsizei count,
5684 GLboolean transpose,
5685 const GLfloat *value)
5686{
5687 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5688}
5689
Jamie Madill5b772312018-03-08 20:28:32 -05005690bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005691 GLint location,
5692 GLsizei count,
5693 GLboolean transpose,
5694 const GLfloat *value)
5695{
5696 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5697}
5698
Jamie Madill5b772312018-03-08 20:28:32 -05005699bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005700{
5701 Program *programObject = GetValidProgram(context, program);
5702
5703 if (!programObject)
5704 {
5705 return false;
5706 }
5707
5708 return true;
5709}
5710
Jamie Madill5b772312018-03-08 20:28:32 -05005711bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005712{
5713 return ValidateVertexAttribIndex(context, index);
5714}
5715
Jamie Madill5b772312018-03-08 20:28:32 -05005716bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005717{
5718 return ValidateVertexAttribIndex(context, index);
5719}
5720
Jamie Madill5b772312018-03-08 20:28:32 -05005721bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005722{
5723 return ValidateVertexAttribIndex(context, index);
5724}
5725
Jamie Madill5b772312018-03-08 20:28:32 -05005726bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005727{
5728 return ValidateVertexAttribIndex(context, index);
5729}
5730
Jamie Madill5b772312018-03-08 20:28:32 -05005731bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005732{
5733 return ValidateVertexAttribIndex(context, index);
5734}
5735
Jamie Madill5b772312018-03-08 20:28:32 -05005736bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005737{
5738 return ValidateVertexAttribIndex(context, index);
5739}
5740
Jamie Madill5b772312018-03-08 20:28:32 -05005741bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005742 GLuint index,
5743 GLfloat x,
5744 GLfloat y,
5745 GLfloat z,
5746 GLfloat w)
5747{
5748 return ValidateVertexAttribIndex(context, index);
5749}
5750
Jamie Madill5b772312018-03-08 20:28:32 -05005751bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005752{
5753 return ValidateVertexAttribIndex(context, index);
5754}
5755
Jamie Madill5b772312018-03-08 20:28:32 -05005756bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005757{
5758 if (width < 0 || height < 0)
5759 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005760 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005761 return false;
5762 }
5763
5764 return true;
5765}
5766
Jamie Madill493f9572018-05-24 19:52:15 -04005767bool ValidateDrawArrays(Context *context, PrimitiveMode mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005768{
5769 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5770}
5771
Jamie Madill5b772312018-03-08 20:28:32 -05005772bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005773 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005774 GLsizei count,
5775 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005776 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005777{
5778 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5779}
5780
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005781bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005782 GLenum target,
5783 GLenum attachment,
5784 GLenum pname,
5785 GLint *params)
5786{
5787 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5788 nullptr);
5789}
5790
Jamie Madill5b772312018-03-08 20:28:32 -05005791bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005792{
5793 return ValidateGetProgramivBase(context, program, pname, nullptr);
5794}
5795
Jamie Madill5b772312018-03-08 20:28:32 -05005796bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005797 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005798 GLint level,
5799 GLenum internalformat,
5800 GLint x,
5801 GLint y,
5802 GLsizei width,
5803 GLsizei height,
5804 GLint border)
5805{
5806 if (context->getClientMajorVersion() < 3)
5807 {
5808 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5809 0, x, y, width, height, border);
5810 }
5811
5812 ASSERT(context->getClientMajorVersion() == 3);
5813 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5814 0, x, y, width, height, border);
5815}
5816
5817bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005818 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005819 GLint level,
5820 GLint xoffset,
5821 GLint yoffset,
5822 GLint x,
5823 GLint y,
5824 GLsizei width,
5825 GLsizei height)
5826{
5827 if (context->getClientMajorVersion() < 3)
5828 {
5829 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5830 yoffset, x, y, width, height, 0);
5831 }
5832
5833 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5834 yoffset, 0, x, y, width, height, 0);
5835}
5836
5837bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5838{
5839 return ValidateGenOrDelete(context, n);
5840}
5841
5842bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5843{
5844 return ValidateGenOrDelete(context, n);
5845}
5846
5847bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5848{
5849 return ValidateGenOrDelete(context, n);
5850}
5851
5852bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5853{
5854 return ValidateGenOrDelete(context, n);
5855}
5856
5857bool ValidateDisable(Context *context, GLenum cap)
5858{
5859 if (!ValidCap(context, cap, false))
5860 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005861 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005862 return false;
5863 }
5864
5865 return true;
5866}
5867
5868bool ValidateEnable(Context *context, GLenum cap)
5869{
5870 if (!ValidCap(context, cap, false))
5871 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005872 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005873 return false;
5874 }
5875
5876 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5877 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5878 {
5879 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005880 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005881
5882 // We also output an error message to the debugger window if tracing is active, so that
5883 // developers can see the error message.
5884 ERR() << errorMessage;
5885 return false;
5886 }
5887
5888 return true;
5889}
5890
5891bool ValidateFramebufferRenderbuffer(Context *context,
5892 GLenum target,
5893 GLenum attachment,
5894 GLenum renderbuffertarget,
5895 GLuint renderbuffer)
5896{
Geoff Lange8afa902017-09-27 15:00:43 -04005897 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005898 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005899 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5900 return false;
5901 }
5902
5903 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5904 {
5905 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005906 return false;
5907 }
5908
5909 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5910 renderbuffertarget, renderbuffer);
5911}
5912
5913bool ValidateFramebufferTexture2D(Context *context,
5914 GLenum target,
5915 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005916 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005917 GLuint texture,
5918 GLint level)
5919{
5920 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5921 // extension
5922 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5923 level != 0)
5924 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005925 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005926 return false;
5927 }
5928
5929 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5930 {
5931 return false;
5932 }
5933
5934 if (texture != 0)
5935 {
5936 gl::Texture *tex = context->getTexture(texture);
5937 ASSERT(tex);
5938
5939 const gl::Caps &caps = context->getCaps();
5940
5941 switch (textarget)
5942 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005943 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005944 {
5945 if (level > gl::log2(caps.max2DTextureSize))
5946 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005947 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005948 return false;
5949 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005950 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005951 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005952 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005953 return false;
5954 }
5955 }
5956 break;
5957
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005958 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005959 {
5960 if (level != 0)
5961 {
5962 context->handleError(InvalidValue());
5963 return false;
5964 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005965 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005966 {
5967 context->handleError(InvalidOperation()
5968 << "Textarget must match the texture target type.");
5969 return false;
5970 }
5971 }
5972 break;
5973
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005974 case TextureTarget::CubeMapNegativeX:
5975 case TextureTarget::CubeMapNegativeY:
5976 case TextureTarget::CubeMapNegativeZ:
5977 case TextureTarget::CubeMapPositiveX:
5978 case TextureTarget::CubeMapPositiveY:
5979 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005980 {
5981 if (level > gl::log2(caps.maxCubeMapTextureSize))
5982 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005983 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005984 return false;
5985 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005986 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04005987 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005988 context->handleError(InvalidOperation()
5989 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005990 return false;
5991 }
5992 }
5993 break;
5994
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005995 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04005996 {
5997 if (context->getClientVersion() < ES_3_1)
5998 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005999 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006000 return false;
6001 }
6002
6003 if (level != 0)
6004 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006005 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 return false;
6007 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006008 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006009 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006010 context->handleError(InvalidOperation()
6011 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 return false;
6013 }
6014 }
6015 break;
6016
6017 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006018 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006019 return false;
6020 }
6021
6022 const Format &format = tex->getFormat(textarget, level);
6023 if (format.info->compressed)
6024 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006025 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006026 return false;
6027 }
6028 }
6029
6030 return true;
6031}
6032
6033bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6034{
6035 return ValidateGenOrDelete(context, n);
6036}
6037
6038bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6039{
6040 return ValidateGenOrDelete(context, n);
6041}
6042
6043bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6044{
6045 return ValidateGenOrDelete(context, n);
6046}
6047
6048bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6049{
6050 return ValidateGenOrDelete(context, n);
6051}
6052
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006053bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006054{
6055 if (!ValidTextureTarget(context, target))
6056 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006057 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 return false;
6059 }
6060
6061 Texture *texture = context->getTargetTexture(target);
6062
6063 if (texture == nullptr)
6064 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006065 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006066 return false;
6067 }
6068
6069 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6070
6071 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6072 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6073 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006075 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006076 return false;
6077 }
6078
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006079 TextureTarget baseTarget = (target == TextureType::CubeMap)
6080 ? TextureTarget::CubeMapPositiveX
6081 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006082 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6083 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6084 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006085 {
6086 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6087 return false;
6088 }
6089
Geoff Lang536eca12017-09-13 11:23:35 -04006090 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6091 bool formatUnsized = !format.sized;
6092 bool formatColorRenderableAndFilterable =
6093 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6094 format.renderSupport(context->getClientVersion(), context->getExtensions());
6095 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006096 {
Geoff Lang536eca12017-09-13 11:23:35 -04006097 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006098 return false;
6099 }
6100
Geoff Lang536eca12017-09-13 11:23:35 -04006101 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6102 // generation
6103 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6104 {
6105 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6106 return false;
6107 }
6108
6109 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
Geoff Lange24032a2018-03-28 15:41:46 -04006110 // not. Differentiate the ES3 format from the extension format by checking if the format is
6111 // sized, GL_EXT_sRGB does not add any sized formats.
6112 bool supportsSRGBMipmapGeneration = context->getExtensions().webglCompatibility;
6113 if (!supportsSRGBMipmapGeneration && !format.sized && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006114 {
Geoff Lang536eca12017-09-13 11:23:35 -04006115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006116 return false;
6117 }
6118
6119 // Non-power of 2 ES2 check
6120 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6121 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6122 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6123 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006124 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6125 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006126 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006127 return false;
6128 }
6129
6130 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006131 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006132 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006133 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006134 return false;
6135 }
6136
6137 return true;
6138}
6139
Jamie Madill5b772312018-03-08 20:28:32 -05006140bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006141 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006142 GLenum pname,
6143 GLint *params)
6144{
6145 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6146}
6147
6148bool ValidateGetRenderbufferParameteriv(Context *context,
6149 GLenum target,
6150 GLenum pname,
6151 GLint *params)
6152{
6153 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6154}
6155
6156bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6157{
6158 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6159}
6160
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006161bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006162{
6163 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6164}
6165
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006166bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006167{
6168 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6169}
6170
6171bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6172{
6173 return ValidateGetUniformBase(context, program, location);
6174}
6175
6176bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6177{
6178 return ValidateGetUniformBase(context, program, location);
6179}
6180
6181bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6182{
6183 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6184}
6185
6186bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6187{
6188 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6189}
6190
6191bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6192{
6193 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6194}
6195
6196bool ValidateIsEnabled(Context *context, GLenum cap)
6197{
6198 if (!ValidCap(context, cap, true))
6199 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006201 return false;
6202 }
6203
6204 return true;
6205}
6206
6207bool ValidateLinkProgram(Context *context, GLuint program)
6208{
6209 if (context->hasActiveTransformFeedback(program))
6210 {
6211 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006212 context->handleError(InvalidOperation() << "Cannot link program while program is "
6213 "associated with an active transform "
6214 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006215 return false;
6216 }
6217
6218 Program *programObject = GetValidProgram(context, program);
6219 if (!programObject)
6220 {
6221 return false;
6222 }
6223
6224 return true;
6225}
6226
Jamie Madill4928b7c2017-06-20 12:57:39 -04006227bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006228 GLint x,
6229 GLint y,
6230 GLsizei width,
6231 GLsizei height,
6232 GLenum format,
6233 GLenum type,
6234 void *pixels)
6235{
6236 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6237 nullptr, pixels);
6238}
6239
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006240bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006241{
6242 return ValidateTexParameterBase(context, target, pname, -1, &param);
6243}
6244
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006245bool ValidateTexParameterfv(Context *context,
6246 TextureType target,
6247 GLenum pname,
6248 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006249{
6250 return ValidateTexParameterBase(context, target, pname, -1, params);
6251}
6252
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006253bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006254{
6255 return ValidateTexParameterBase(context, target, pname, -1, &param);
6256}
6257
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006258bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006259{
6260 return ValidateTexParameterBase(context, target, pname, -1, params);
6261}
6262
6263bool ValidateUseProgram(Context *context, GLuint program)
6264{
6265 if (program != 0)
6266 {
6267 Program *programObject = context->getProgram(program);
6268 if (!programObject)
6269 {
6270 // ES 3.1.0 section 7.3 page 72
6271 if (context->getShader(program))
6272 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006273 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006274 return false;
6275 }
6276 else
6277 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006278 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006279 return false;
6280 }
6281 }
6282 if (!programObject->isLinked())
6283 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006284 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006285 return false;
6286 }
6287 }
6288 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6289 {
6290 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006291 context
6292 ->handleError(InvalidOperation()
6293 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006294 return false;
6295 }
6296
6297 return true;
6298}
6299
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006300bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6301{
6302 if (!context->getExtensions().fence)
6303 {
6304 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6305 return false;
6306 }
6307
6308 if (n < 0)
6309 {
6310 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6311 return false;
6312 }
6313
6314 return true;
6315}
6316
6317bool ValidateFinishFenceNV(Context *context, GLuint fence)
6318{
6319 if (!context->getExtensions().fence)
6320 {
6321 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6322 return false;
6323 }
6324
6325 FenceNV *fenceObject = context->getFenceNV(fence);
6326
6327 if (fenceObject == nullptr)
6328 {
6329 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6330 return false;
6331 }
6332
6333 if (!fenceObject->isSet())
6334 {
6335 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6336 return false;
6337 }
6338
6339 return true;
6340}
6341
6342bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6343{
6344 if (!context->getExtensions().fence)
6345 {
6346 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6347 return false;
6348 }
6349
6350 if (n < 0)
6351 {
6352 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6353 return false;
6354 }
6355
6356 return true;
6357}
6358
6359bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6360{
6361 if (!context->getExtensions().fence)
6362 {
6363 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6364 return false;
6365 }
6366
6367 FenceNV *fenceObject = context->getFenceNV(fence);
6368
6369 if (fenceObject == nullptr)
6370 {
6371 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6372 return false;
6373 }
6374
6375 if (!fenceObject->isSet())
6376 {
6377 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6378 return false;
6379 }
6380
6381 switch (pname)
6382 {
6383 case GL_FENCE_STATUS_NV:
6384 case GL_FENCE_CONDITION_NV:
6385 break;
6386
6387 default:
6388 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6389 return false;
6390 }
6391
6392 return true;
6393}
6394
6395bool ValidateGetGraphicsResetStatusEXT(Context *context)
6396{
6397 if (!context->getExtensions().robustness)
6398 {
6399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6400 return false;
6401 }
6402
6403 return true;
6404}
6405
6406bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6407 GLuint shader,
6408 GLsizei bufsize,
6409 GLsizei *length,
6410 GLchar *source)
6411{
6412 if (!context->getExtensions().translatedShaderSource)
6413 {
6414 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6415 return false;
6416 }
6417
6418 if (bufsize < 0)
6419 {
6420 context->handleError(InvalidValue());
6421 return false;
6422 }
6423
6424 Shader *shaderObject = context->getShader(shader);
6425
6426 if (!shaderObject)
6427 {
6428 context->handleError(InvalidOperation());
6429 return false;
6430 }
6431
6432 return true;
6433}
6434
6435bool ValidateIsFenceNV(Context *context, GLuint fence)
6436{
6437 if (!context->getExtensions().fence)
6438 {
6439 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6440 return false;
6441 }
6442
6443 return true;
6444}
6445
Jamie Madill007530e2017-12-28 14:27:04 -05006446bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6447{
6448 if (!context->getExtensions().fence)
6449 {
6450 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6451 return false;
6452 }
6453
6454 if (condition != GL_ALL_COMPLETED_NV)
6455 {
6456 context->handleError(InvalidEnum());
6457 return false;
6458 }
6459
6460 FenceNV *fenceObject = context->getFenceNV(fence);
6461
6462 if (fenceObject == nullptr)
6463 {
6464 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6465 return false;
6466 }
6467
6468 return true;
6469}
6470
6471bool ValidateTestFenceNV(Context *context, GLuint fence)
6472{
6473 if (!context->getExtensions().fence)
6474 {
6475 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6476 return false;
6477 }
6478
6479 FenceNV *fenceObject = context->getFenceNV(fence);
6480
6481 if (fenceObject == nullptr)
6482 {
6483 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6484 return false;
6485 }
6486
6487 if (fenceObject->isSet() != GL_TRUE)
6488 {
6489 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6490 return false;
6491 }
6492
6493 return true;
6494}
6495
6496bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006497 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006498 GLsizei levels,
6499 GLenum internalformat,
6500 GLsizei width,
6501 GLsizei height)
6502{
6503 if (!context->getExtensions().textureStorage)
6504 {
6505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6506 return false;
6507 }
6508
6509 if (context->getClientMajorVersion() < 3)
6510 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006511 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006512 height);
6513 }
6514
6515 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006516 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006517 1);
6518}
6519
6520bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6521{
6522 if (!context->getExtensions().instancedArrays)
6523 {
6524 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6525 return false;
6526 }
6527
6528 if (index >= MAX_VERTEX_ATTRIBS)
6529 {
6530 context->handleError(InvalidValue());
6531 return false;
6532 }
6533
6534 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6535 {
6536 if (index == 0 && divisor != 0)
6537 {
6538 const char *errorMessage =
6539 "The current context doesn't support setting a non-zero divisor on the "
6540 "attribute with index zero. "
6541 "Please reorder the attributes in your vertex shader so that attribute zero "
6542 "can have a zero divisor.";
6543 context->handleError(InvalidOperation() << errorMessage);
6544
6545 // We also output an error message to the debugger window if tracing is active, so
6546 // that developers can see the error message.
6547 ERR() << errorMessage;
6548 return false;
6549 }
6550 }
6551
6552 return true;
6553}
6554
6555bool ValidateTexImage3DOES(Context *context,
6556 GLenum target,
6557 GLint level,
6558 GLenum internalformat,
6559 GLsizei width,
6560 GLsizei height,
6561 GLsizei depth,
6562 GLint border,
6563 GLenum format,
6564 GLenum type,
6565 const void *pixels)
6566{
6567 UNIMPLEMENTED(); // FIXME
6568 return false;
6569}
6570
6571bool ValidatePopGroupMarkerEXT(Context *context)
6572{
6573 if (!context->getExtensions().debugMarker)
6574 {
6575 // The debug marker calls should not set error state
6576 // However, it seems reasonable to set an error state if the extension is not enabled
6577 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6578 return false;
6579 }
6580
6581 return true;
6582}
6583
Jamie Madillfa920eb2018-01-04 11:45:50 -05006584bool ValidateTexStorage1DEXT(Context *context,
6585 GLenum target,
6586 GLsizei levels,
6587 GLenum internalformat,
6588 GLsizei width)
6589{
6590 UNIMPLEMENTED();
6591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6592 return false;
6593}
6594
6595bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006596 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006597 GLsizei levels,
6598 GLenum internalformat,
6599 GLsizei width,
6600 GLsizei height,
6601 GLsizei depth)
6602{
6603 if (!context->getExtensions().textureStorage)
6604 {
6605 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6606 return false;
6607 }
6608
6609 if (context->getClientMajorVersion() < 3)
6610 {
6611 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6612 return false;
6613 }
6614
6615 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6616 depth);
6617}
6618
Jamie Madillc29968b2016-01-20 11:17:23 -05006619} // namespace gl