blob: 46d304915dd5a33400937c1b660956890c8d186e [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
78 if (context->hasPath(pathName) && !context->hasPathData(pathName))
79 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madillbe849e42017-05-02 15:49:00 -0400458bool ValidateES2CopyTexImageParameters(ValidationContext *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
795 default:
796 return false;
797 }
798}
799
Geoff Langfc32e8b2017-05-31 14:16:59 -0400800// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
801// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400802bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400803{
804 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400805 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
806 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400807 {
808 return true;
809 }
810
811 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
812 if (c >= 9 && c <= 13)
813 {
814 return true;
815 }
816
817 return false;
818}
819
Geoff Langcab92ee2017-07-19 17:32:07 -0400820bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400821{
Geoff Langa71a98e2017-06-19 15:15:00 -0400822 for (size_t i = 0; i < len; i++)
823 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400824 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400825 {
826 return false;
827 }
828 }
829
830 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400831}
832
Geoff Langcab92ee2017-07-19 17:32:07 -0400833bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
834{
835 enum class ParseState
836 {
837 // Have not seen an ASCII non-whitespace character yet on
838 // this line. Possible that we might see a preprocessor
839 // directive.
840 BEGINING_OF_LINE,
841
842 // Have seen at least one ASCII non-whitespace character
843 // on this line.
844 MIDDLE_OF_LINE,
845
846 // Handling a preprocessor directive. Passes through all
847 // characters up to the end of the line. Disables comment
848 // processing.
849 IN_PREPROCESSOR_DIRECTIVE,
850
851 // Handling a single-line comment. The comment text is
852 // replaced with a single space.
853 IN_SINGLE_LINE_COMMENT,
854
855 // Handling a multi-line comment. Newlines are passed
856 // through to preserve line numbers.
857 IN_MULTI_LINE_COMMENT
858 };
859
860 ParseState state = ParseState::BEGINING_OF_LINE;
861 size_t pos = 0;
862
863 while (pos < len)
864 {
865 char c = str[pos];
866 char next = pos + 1 < len ? str[pos + 1] : 0;
867
868 // Check for newlines
869 if (c == '\n' || c == '\r')
870 {
871 if (state != ParseState::IN_MULTI_LINE_COMMENT)
872 {
873 state = ParseState::BEGINING_OF_LINE;
874 }
875
876 pos++;
877 continue;
878 }
879
880 switch (state)
881 {
882 case ParseState::BEGINING_OF_LINE:
883 if (c == ' ')
884 {
885 // Maintain the BEGINING_OF_LINE state until a non-space is seen
886 pos++;
887 }
888 else if (c == '#')
889 {
890 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
891 pos++;
892 }
893 else
894 {
895 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
896 state = ParseState::MIDDLE_OF_LINE;
897 }
898 break;
899
900 case ParseState::MIDDLE_OF_LINE:
901 if (c == '/' && next == '/')
902 {
903 state = ParseState::IN_SINGLE_LINE_COMMENT;
904 pos++;
905 }
906 else if (c == '/' && next == '*')
907 {
908 state = ParseState::IN_MULTI_LINE_COMMENT;
909 pos++;
910 }
911 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
912 {
913 // Skip line continuation characters
914 }
915 else if (!IsValidESSLCharacter(c))
916 {
917 return false;
918 }
919 pos++;
920 break;
921
922 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700923 // Line-continuation characters may not be permitted.
924 // Otherwise, just pass it through. Do not parse comments in this state.
925 if (!lineContinuationAllowed && c == '\\')
926 {
927 return false;
928 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400929 pos++;
930 break;
931
932 case ParseState::IN_SINGLE_LINE_COMMENT:
933 // Line-continuation characters are processed before comment processing.
934 // Advance string if a new line character is immediately behind
935 // line-continuation character.
936 if (c == '\\' && (next == '\n' || next == '\r'))
937 {
938 pos++;
939 }
940 pos++;
941 break;
942
943 case ParseState::IN_MULTI_LINE_COMMENT:
944 if (c == '*' && next == '/')
945 {
946 state = ParseState::MIDDLE_OF_LINE;
947 pos++;
948 }
949 pos++;
950 break;
951 }
952 }
953
954 return true;
955}
956
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700957bool ValidateWebGLNamePrefix(ValidationContext *context, const GLchar *name)
958{
959 ASSERT(context->isWebGL());
960
961 // WebGL 1.0 [Section 6.16] GLSL Constructs
962 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
963 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
964 {
965 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
966 return false;
967 }
968
969 return true;
970}
971
972bool ValidateWebGLNameLength(ValidationContext *context, size_t length)
973{
974 ASSERT(context->isWebGL());
975
976 if (context->isWebGL1() && length > 256)
977 {
978 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
979 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
980 // locations.
981 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
982
983 return false;
984 }
985 else if (length > 1024)
986 {
987 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
988 // uniform and attribute locations.
989 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
990 return false;
991 }
992
993 return true;
994}
995
Jamie Madill007530e2017-12-28 14:27:04 -0500996bool ValidateMatrixMode(Context *context, GLenum matrixMode)
997{
998 if (!context->getExtensions().pathRendering)
999 {
1000 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1001 return false;
1002 }
1003
1004 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1005 {
1006 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1007 return false;
1008 }
1009 return true;
1010}
Jamie Madillc29968b2016-01-20 11:17:23 -05001011} // anonymous namespace
1012
Geoff Langff5b2d52016-09-07 11:32:23 -04001013bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001014 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001015 GLint level,
1016 GLenum internalformat,
1017 bool isCompressed,
1018 bool isSubImage,
1019 GLint xoffset,
1020 GLint yoffset,
1021 GLsizei width,
1022 GLsizei height,
1023 GLint border,
1024 GLenum format,
1025 GLenum type,
1026 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001027 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001028{
Jamie Madill6f38f822014-06-06 17:12:20 -04001029 if (!ValidTexture2DDestinationTarget(context, target))
1030 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001031 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001032 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001033 }
1034
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001035 TextureType texType = TextureTargetToType(target);
1036 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001037 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001038 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001039 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001040 }
1041
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001042 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001043 {
1044 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1045 return false;
1046 }
1047
1048 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001049 std::numeric_limits<GLsizei>::max() - yoffset < height)
1050 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001051 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001052 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001053 }
1054
Geoff Lang6e898aa2017-06-02 11:17:26 -04001055 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1056 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1057 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1058 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1059 // case.
1060 bool nonEqualFormatsAllowed =
1061 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1062 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1063
1064 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001065 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001066 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001067 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001068 }
1069
Geoff Langaae65a42014-05-26 12:43:44 -04001070 const gl::Caps &caps = context->getCaps();
1071
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001072 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001073 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001074 case TextureType::_2D:
1075 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1076 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1077 {
1078 context->handleError(InvalidValue());
1079 return false;
1080 }
1081 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001082
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001083 case TextureType::Rectangle:
1084 ASSERT(level == 0);
1085 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1086 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1087 {
1088 context->handleError(InvalidValue());
1089 return false;
1090 }
1091 if (isCompressed)
1092 {
1093 context->handleError(InvalidEnum()
1094 << "Rectangle texture cannot have a compressed format.");
1095 return false;
1096 }
1097 break;
1098
1099 case TextureType::CubeMap:
1100 if (!isSubImage && width != height)
1101 {
1102 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1103 return false;
1104 }
1105
1106 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1107 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1108 {
1109 context->handleError(InvalidValue());
1110 return false;
1111 }
1112 break;
1113
1114 default:
1115 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001116 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001117 }
1118
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001119 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001120 if (!texture)
1121 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001122 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001123 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001124 }
1125
Geoff Langa9be0dc2014-12-17 12:34:40 -05001126 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001127 {
Geoff Langca271392017-04-05 12:30:00 -04001128 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1129 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001131 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001132 return false;
1133 }
1134
Geoff Langa9be0dc2014-12-17 12:34:40 -05001135 if (format != GL_NONE)
1136 {
Geoff Langca271392017-04-05 12:30:00 -04001137 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1138 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001139 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001140 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001141 return false;
1142 }
1143 }
1144
1145 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1146 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001148 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001149 return false;
1150 }
Geoff Langfb052642017-10-24 13:42:09 -04001151
1152 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001153 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001154 {
1155 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1156 return false;
1157 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001158 }
1159 else
1160 {
Geoff Lang69cce582015-09-17 13:20:36 -04001161 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001163 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001164 return false;
1165 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001166 }
1167
1168 // Verify zero border
1169 if (border != 0)
1170 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001171 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001172 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001173 }
1174
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001175 if (isCompressed)
1176 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001177 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001178 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1179 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001180 switch (actualInternalFormat)
1181 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001182 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1183 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1184 if (!context->getExtensions().textureCompressionDXT1)
1185 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001186 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001187 return false;
1188 }
1189 break;
1190 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001191 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001192 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001193 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001194 return false;
1195 }
1196 break;
1197 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1198 if (!context->getExtensions().textureCompressionDXT5)
1199 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001201 return false;
1202 }
1203 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001204 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1205 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1206 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1207 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1208 if (!context->getExtensions().textureCompressionS3TCsRGB)
1209 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001210 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001211 return false;
1212 }
1213 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001214 case GL_ETC1_RGB8_OES:
1215 if (!context->getExtensions().compressedETC1RGB8Texture)
1216 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001217 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001218 return false;
1219 }
Geoff Lang86f81162017-10-30 15:10:45 -04001220 if (isSubImage)
1221 {
1222 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1223 return false;
1224 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001225 break;
1226 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001227 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1228 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1229 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1230 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001231 if (!context->getExtensions().lossyETCDecode)
1232 {
Geoff Lang86f81162017-10-30 15:10:45 -04001233 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001234 return false;
1235 }
1236 break;
1237 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001238 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001239 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001240 }
Geoff Lang966c9402017-04-18 12:38:27 -04001241
1242 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001243 {
Geoff Lang966c9402017-04-18 12:38:27 -04001244 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1245 height, texture->getWidth(target, level),
1246 texture->getHeight(target, level)))
1247 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001248 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001249 return false;
1250 }
1251
1252 if (format != actualInternalFormat)
1253 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001254 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001255 return false;
1256 }
1257 }
1258 else
1259 {
1260 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1261 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001262 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001263 return false;
1264 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001265 }
1266 }
1267 else
1268 {
1269 // validate <type> by itself (used as secondary key below)
1270 switch (type)
1271 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001272 case GL_UNSIGNED_BYTE:
1273 case GL_UNSIGNED_SHORT_5_6_5:
1274 case GL_UNSIGNED_SHORT_4_4_4_4:
1275 case GL_UNSIGNED_SHORT_5_5_5_1:
1276 case GL_UNSIGNED_SHORT:
1277 case GL_UNSIGNED_INT:
1278 case GL_UNSIGNED_INT_24_8_OES:
1279 case GL_HALF_FLOAT_OES:
1280 case GL_FLOAT:
1281 break;
1282 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001283 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001284 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001285 }
1286
1287 // validate <format> + <type> combinations
1288 // - invalid <format> -> sets INVALID_ENUM
1289 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1290 switch (format)
1291 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001292 case GL_ALPHA:
1293 case GL_LUMINANCE:
1294 case GL_LUMINANCE_ALPHA:
1295 switch (type)
1296 {
1297 case GL_UNSIGNED_BYTE:
1298 case GL_FLOAT:
1299 case GL_HALF_FLOAT_OES:
1300 break;
1301 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001302 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 return false;
1304 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001305 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001306 case GL_RED:
1307 case GL_RG:
1308 if (!context->getExtensions().textureRG)
1309 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001310 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001311 return false;
1312 }
1313 switch (type)
1314 {
1315 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001316 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001317 case GL_FLOAT:
1318 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001319 if (!context->getExtensions().textureFloat)
1320 {
1321 context->handleError(InvalidEnum());
1322 return false;
1323 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001324 break;
1325 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001326 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001327 return false;
1328 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001330 case GL_RGB:
1331 switch (type)
1332 {
1333 case GL_UNSIGNED_BYTE:
1334 case GL_UNSIGNED_SHORT_5_6_5:
1335 case GL_FLOAT:
1336 case GL_HALF_FLOAT_OES:
1337 break;
1338 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001339 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001340 return false;
1341 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001342 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001343 case GL_RGBA:
1344 switch (type)
1345 {
1346 case GL_UNSIGNED_BYTE:
1347 case GL_UNSIGNED_SHORT_4_4_4_4:
1348 case GL_UNSIGNED_SHORT_5_5_5_1:
1349 case GL_FLOAT:
1350 case GL_HALF_FLOAT_OES:
1351 break;
1352 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001354 return false;
1355 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001356 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001357 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001358 if (!context->getExtensions().textureFormatBGRA8888)
1359 {
1360 context->handleError(InvalidEnum());
1361 return false;
1362 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001363 switch (type)
1364 {
1365 case GL_UNSIGNED_BYTE:
1366 break;
1367 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 return false;
1370 }
1371 break;
1372 case GL_SRGB_EXT:
1373 case GL_SRGB_ALPHA_EXT:
1374 if (!context->getExtensions().sRGB)
1375 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001376 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001377 return false;
1378 }
1379 switch (type)
1380 {
1381 case GL_UNSIGNED_BYTE:
1382 break;
1383 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001384 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001385 return false;
1386 }
1387 break;
1388 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1389 // handled below
1390 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1391 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1392 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1393 break;
1394 case GL_DEPTH_COMPONENT:
1395 switch (type)
1396 {
1397 case GL_UNSIGNED_SHORT:
1398 case GL_UNSIGNED_INT:
1399 break;
1400 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001401 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001402 return false;
1403 }
1404 break;
1405 case GL_DEPTH_STENCIL_OES:
1406 switch (type)
1407 {
1408 case GL_UNSIGNED_INT_24_8_OES:
1409 break;
1410 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001411 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001412 return false;
1413 }
1414 break;
1415 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001416 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001417 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001418 }
1419
1420 switch (format)
1421 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001422 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1423 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1424 if (context->getExtensions().textureCompressionDXT1)
1425 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001426 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001427 return false;
1428 }
1429 else
1430 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001431 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001432 return false;
1433 }
1434 break;
1435 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1436 if (context->getExtensions().textureCompressionDXT3)
1437 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001438 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001439 return false;
1440 }
1441 else
1442 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001443 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001444 return false;
1445 }
1446 break;
1447 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1448 if (context->getExtensions().textureCompressionDXT5)
1449 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001450 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 return false;
1452 }
1453 else
1454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001455 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001456 return false;
1457 }
1458 break;
1459 case GL_ETC1_RGB8_OES:
1460 if (context->getExtensions().compressedETC1RGB8Texture)
1461 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001462 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001463 return false;
1464 }
1465 else
1466 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001467 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 return false;
1469 }
1470 break;
1471 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001472 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1473 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1474 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1475 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001476 if (context->getExtensions().lossyETCDecode)
1477 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001478 context->handleError(InvalidOperation()
1479 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001480 return false;
1481 }
1482 else
1483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001484 context->handleError(InvalidEnum()
1485 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001486 return false;
1487 }
1488 break;
1489 case GL_DEPTH_COMPONENT:
1490 case GL_DEPTH_STENCIL_OES:
1491 if (!context->getExtensions().depthTextures)
1492 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001493 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001494 return false;
1495 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001496 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001498 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001499 return false;
1500 }
1501 // OES_depth_texture supports loading depth data and multiple levels,
1502 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001503 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001504 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1506 return false;
1507 }
1508 if (level != 0)
1509 {
1510 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001511 return false;
1512 }
1513 break;
1514 default:
1515 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001516 }
1517
Geoff Lang6e898aa2017-06-02 11:17:26 -04001518 if (!isSubImage)
1519 {
1520 switch (internalformat)
1521 {
1522 case GL_RGBA32F:
1523 if (!context->getExtensions().colorBufferFloatRGBA)
1524 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001525 context->handleError(InvalidValue()
1526 << "Sized GL_RGBA32F internal format requires "
1527 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001528 return false;
1529 }
1530 if (type != GL_FLOAT)
1531 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001532 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001533 return false;
1534 }
1535 if (format != GL_RGBA)
1536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001537 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001538 return false;
1539 }
1540 break;
1541
1542 case GL_RGB32F:
1543 if (!context->getExtensions().colorBufferFloatRGB)
1544 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001545 context->handleError(InvalidValue()
1546 << "Sized GL_RGB32F internal format requires "
1547 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001548 return false;
1549 }
1550 if (type != GL_FLOAT)
1551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001552 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001553 return false;
1554 }
1555 if (format != GL_RGB)
1556 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001557 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001558 return false;
1559 }
1560 break;
1561
1562 default:
1563 break;
1564 }
1565 }
1566
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001567 if (type == GL_FLOAT)
1568 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001569 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001570 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001571 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001572 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001573 }
1574 }
1575 else if (type == GL_HALF_FLOAT_OES)
1576 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001577 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001578 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001579 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001580 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001581 }
1582 }
1583 }
1584
Geoff Langdbcced82017-06-06 15:55:54 -04001585 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001586 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001587 imageSize))
1588 {
1589 return false;
1590 }
1591
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001592 return true;
1593}
1594
He Yunchaoced53ae2016-11-29 15:00:51 +08001595bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001596 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001597 GLsizei levels,
1598 GLenum internalformat,
1599 GLsizei width,
1600 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001601{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001602 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1603 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001604 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001605 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001606 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001607 }
1608
1609 if (width < 1 || height < 1 || levels < 1)
1610 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001611 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001612 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001613 }
1614
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001615 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001616 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001617 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001618 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001619 }
1620
1621 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1622 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001623 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001624 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001625 }
1626
Geoff Langca271392017-04-05 12:30:00 -04001627 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001628 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001629 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001630 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001631 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001632 }
1633
Geoff Langaae65a42014-05-26 12:43:44 -04001634 const gl::Caps &caps = context->getCaps();
1635
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 switch (target)
1637 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001638 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001639 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1640 static_cast<GLuint>(height) > caps.max2DTextureSize)
1641 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001642 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001643 return false;
1644 }
1645 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001646 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001647 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1648 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1649 {
1650 context->handleError(InvalidValue());
1651 return false;
1652 }
1653 if (formatInfo.compressed)
1654 {
1655 context->handleError(InvalidEnum()
1656 << "Rectangle texture cannot have a compressed format.");
1657 return false;
1658 }
1659 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001660 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001661 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1662 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1663 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001664 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001665 return false;
1666 }
1667 break;
1668 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001669 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001670 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001671 }
1672
Geoff Langc0b9ef42014-07-02 10:02:37 -04001673 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001674 {
1675 if (!gl::isPow2(width) || !gl::isPow2(height))
1676 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001677 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001678 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001679 }
1680 }
1681
1682 switch (internalformat)
1683 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001684 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1685 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1686 if (!context->getExtensions().textureCompressionDXT1)
1687 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001688 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001689 return false;
1690 }
1691 break;
1692 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1693 if (!context->getExtensions().textureCompressionDXT3)
1694 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001695 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001696 return false;
1697 }
1698 break;
1699 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1700 if (!context->getExtensions().textureCompressionDXT5)
1701 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001702 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001703 return false;
1704 }
1705 break;
1706 case GL_ETC1_RGB8_OES:
1707 if (!context->getExtensions().compressedETC1RGB8Texture)
1708 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001709 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001710 return false;
1711 }
1712 break;
1713 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001714 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1715 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1716 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1717 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001718 if (!context->getExtensions().lossyETCDecode)
1719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001720 context->handleError(InvalidEnum()
1721 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001722 return false;
1723 }
1724 break;
1725 case GL_RGBA32F_EXT:
1726 case GL_RGB32F_EXT:
1727 case GL_ALPHA32F_EXT:
1728 case GL_LUMINANCE32F_EXT:
1729 case GL_LUMINANCE_ALPHA32F_EXT:
1730 if (!context->getExtensions().textureFloat)
1731 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001732 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001733 return false;
1734 }
1735 break;
1736 case GL_RGBA16F_EXT:
1737 case GL_RGB16F_EXT:
1738 case GL_ALPHA16F_EXT:
1739 case GL_LUMINANCE16F_EXT:
1740 case GL_LUMINANCE_ALPHA16F_EXT:
1741 if (!context->getExtensions().textureHalfFloat)
1742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001743 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001744 return false;
1745 }
1746 break;
1747 case GL_R8_EXT:
1748 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001749 if (!context->getExtensions().textureRG)
1750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001751 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001752 return false;
1753 }
1754 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001755 case GL_R16F_EXT:
1756 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001757 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001759 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001760 return false;
1761 }
1762 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001763 case GL_R32F_EXT:
1764 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001765 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001767 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001768 return false;
1769 }
1770 break;
1771 case GL_DEPTH_COMPONENT16:
1772 case GL_DEPTH_COMPONENT32_OES:
1773 case GL_DEPTH24_STENCIL8_OES:
1774 if (!context->getExtensions().depthTextures)
1775 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001776 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001777 return false;
1778 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001779 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001781 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001782 return false;
1783 }
1784 // ANGLE_depth_texture only supports 1-level textures
1785 if (levels != 1)
1786 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001787 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001788 return false;
1789 }
1790 break;
1791 default:
1792 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001793 }
1794
Geoff Lang691e58c2014-12-19 17:03:25 -05001795 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001796 if (!texture || texture->id() == 0)
1797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001798 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001799 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001800 }
1801
Geoff Lang69cce582015-09-17 13:20:36 -04001802 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001803 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001804 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001805 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001806 }
1807
1808 return true;
1809}
1810
He Yunchaoced53ae2016-11-29 15:00:51 +08001811bool ValidateDiscardFramebufferEXT(Context *context,
1812 GLenum target,
1813 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001814 const GLenum *attachments)
1815{
Jamie Madillc29968b2016-01-20 11:17:23 -05001816 if (!context->getExtensions().discardFramebuffer)
1817 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001818 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001819 return false;
1820 }
1821
Austin Kinross08332632015-05-05 13:35:47 -07001822 bool defaultFramebuffer = false;
1823
1824 switch (target)
1825 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001826 case GL_FRAMEBUFFER:
1827 defaultFramebuffer =
1828 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1829 break;
1830 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001831 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001832 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001833 }
1834
He Yunchaoced53ae2016-11-29 15:00:51 +08001835 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1836 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001837}
1838
Austin Kinrossbc781f32015-10-26 09:27:38 -07001839bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1840{
1841 if (!context->getExtensions().vertexArrayObject)
1842 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001843 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001844 return false;
1845 }
1846
1847 return ValidateBindVertexArrayBase(context, array);
1848}
1849
Jamie Madilld7576732017-08-26 18:49:50 -04001850bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001851{
1852 if (!context->getExtensions().vertexArrayObject)
1853 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001854 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001855 return false;
1856 }
1857
Olli Etuaho41997e72016-03-10 13:38:39 +02001858 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001859}
1860
Jamie Madilld7576732017-08-26 18:49:50 -04001861bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001862{
1863 if (!context->getExtensions().vertexArrayObject)
1864 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001865 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001866 return false;
1867 }
1868
Olli Etuaho41997e72016-03-10 13:38:39 +02001869 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870}
1871
Jamie Madilld7576732017-08-26 18:49:50 -04001872bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001873{
1874 if (!context->getExtensions().vertexArrayObject)
1875 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001876 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001877 return false;
1878 }
1879
1880 return true;
1881}
Geoff Langc5629752015-12-07 16:29:04 -05001882
1883bool ValidateProgramBinaryOES(Context *context,
1884 GLuint program,
1885 GLenum binaryFormat,
1886 const void *binary,
1887 GLint length)
1888{
1889 if (!context->getExtensions().getProgramBinary)
1890 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001891 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001892 return false;
1893 }
1894
1895 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1896}
1897
1898bool ValidateGetProgramBinaryOES(Context *context,
1899 GLuint program,
1900 GLsizei bufSize,
1901 GLsizei *length,
1902 GLenum *binaryFormat,
1903 void *binary)
1904{
1905 if (!context->getExtensions().getProgramBinary)
1906 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001907 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001908 return false;
1909 }
1910
1911 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1912}
Geoff Lange102fee2015-12-10 11:23:30 -05001913
Geoff Lang70d0f492015-12-10 17:45:46 -05001914static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1915{
1916 switch (source)
1917 {
1918 case GL_DEBUG_SOURCE_API:
1919 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1920 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1921 case GL_DEBUG_SOURCE_OTHER:
1922 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1923 return !mustBeThirdPartyOrApplication;
1924
1925 case GL_DEBUG_SOURCE_THIRD_PARTY:
1926 case GL_DEBUG_SOURCE_APPLICATION:
1927 return true;
1928
1929 default:
1930 return false;
1931 }
1932}
1933
1934static bool ValidDebugType(GLenum type)
1935{
1936 switch (type)
1937 {
1938 case GL_DEBUG_TYPE_ERROR:
1939 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1940 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1941 case GL_DEBUG_TYPE_PERFORMANCE:
1942 case GL_DEBUG_TYPE_PORTABILITY:
1943 case GL_DEBUG_TYPE_OTHER:
1944 case GL_DEBUG_TYPE_MARKER:
1945 case GL_DEBUG_TYPE_PUSH_GROUP:
1946 case GL_DEBUG_TYPE_POP_GROUP:
1947 return true;
1948
1949 default:
1950 return false;
1951 }
1952}
1953
1954static bool ValidDebugSeverity(GLenum severity)
1955{
1956 switch (severity)
1957 {
1958 case GL_DEBUG_SEVERITY_HIGH:
1959 case GL_DEBUG_SEVERITY_MEDIUM:
1960 case GL_DEBUG_SEVERITY_LOW:
1961 case GL_DEBUG_SEVERITY_NOTIFICATION:
1962 return true;
1963
1964 default:
1965 return false;
1966 }
1967}
1968
Geoff Lange102fee2015-12-10 11:23:30 -05001969bool ValidateDebugMessageControlKHR(Context *context,
1970 GLenum source,
1971 GLenum type,
1972 GLenum severity,
1973 GLsizei count,
1974 const GLuint *ids,
1975 GLboolean enabled)
1976{
1977 if (!context->getExtensions().debug)
1978 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001979 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001980 return false;
1981 }
1982
Geoff Lang70d0f492015-12-10 17:45:46 -05001983 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1984 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001986 return false;
1987 }
1988
1989 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1990 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001991 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001992 return false;
1993 }
1994
1995 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1996 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001997 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001998 return false;
1999 }
2000
2001 if (count > 0)
2002 {
2003 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2004 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002005 context->handleError(
2006 InvalidOperation()
2007 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002008 return false;
2009 }
2010
2011 if (severity != GL_DONT_CARE)
2012 {
Jamie Madill437fa652016-05-03 15:13:24 -04002013 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002014 InvalidOperation()
2015 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002016 return false;
2017 }
2018 }
2019
Geoff Lange102fee2015-12-10 11:23:30 -05002020 return true;
2021}
2022
2023bool ValidateDebugMessageInsertKHR(Context *context,
2024 GLenum source,
2025 GLenum type,
2026 GLuint id,
2027 GLenum severity,
2028 GLsizei length,
2029 const GLchar *buf)
2030{
2031 if (!context->getExtensions().debug)
2032 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002033 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002034 return false;
2035 }
2036
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002037 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002038 {
2039 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2040 // not generate an error.
2041 return false;
2042 }
2043
2044 if (!ValidDebugSeverity(severity))
2045 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002046 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002047 return false;
2048 }
2049
2050 if (!ValidDebugType(type))
2051 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002052 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002053 return false;
2054 }
2055
2056 if (!ValidDebugSource(source, true))
2057 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002058 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002059 return false;
2060 }
2061
2062 size_t messageLength = (length < 0) ? strlen(buf) : length;
2063 if (messageLength > context->getExtensions().maxDebugMessageLength)
2064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002065 context->handleError(InvalidValue()
2066 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002067 return false;
2068 }
2069
Geoff Lange102fee2015-12-10 11:23:30 -05002070 return true;
2071}
2072
2073bool ValidateDebugMessageCallbackKHR(Context *context,
2074 GLDEBUGPROCKHR callback,
2075 const void *userParam)
2076{
2077 if (!context->getExtensions().debug)
2078 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002079 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002080 return false;
2081 }
2082
Geoff Lange102fee2015-12-10 11:23:30 -05002083 return true;
2084}
2085
2086bool ValidateGetDebugMessageLogKHR(Context *context,
2087 GLuint count,
2088 GLsizei bufSize,
2089 GLenum *sources,
2090 GLenum *types,
2091 GLuint *ids,
2092 GLenum *severities,
2093 GLsizei *lengths,
2094 GLchar *messageLog)
2095{
2096 if (!context->getExtensions().debug)
2097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002098 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002099 return false;
2100 }
2101
Geoff Lang70d0f492015-12-10 17:45:46 -05002102 if (bufSize < 0 && messageLog != nullptr)
2103 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002104 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002105 return false;
2106 }
2107
Geoff Lange102fee2015-12-10 11:23:30 -05002108 return true;
2109}
2110
2111bool ValidatePushDebugGroupKHR(Context *context,
2112 GLenum source,
2113 GLuint id,
2114 GLsizei length,
2115 const GLchar *message)
2116{
2117 if (!context->getExtensions().debug)
2118 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002119 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002120 return false;
2121 }
2122
Geoff Lang70d0f492015-12-10 17:45:46 -05002123 if (!ValidDebugSource(source, true))
2124 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002125 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 return false;
2127 }
2128
2129 size_t messageLength = (length < 0) ? strlen(message) : length;
2130 if (messageLength > context->getExtensions().maxDebugMessageLength)
2131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002132 context->handleError(InvalidValue()
2133 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002134 return false;
2135 }
2136
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002137 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002138 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002140 context
2141 ->handleError(StackOverflow()
2142 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002143 return false;
2144 }
2145
Geoff Lange102fee2015-12-10 11:23:30 -05002146 return true;
2147}
2148
2149bool ValidatePopDebugGroupKHR(Context *context)
2150{
2151 if (!context->getExtensions().debug)
2152 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002153 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002154 return false;
2155 }
2156
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002157 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002158 if (currentStackSize <= 1)
2159 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002160 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002161 return false;
2162 }
2163
2164 return true;
2165}
2166
2167static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2168{
2169 switch (identifier)
2170 {
2171 case GL_BUFFER:
2172 if (context->getBuffer(name) == nullptr)
2173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002174 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002175 return false;
2176 }
2177 return true;
2178
2179 case GL_SHADER:
2180 if (context->getShader(name) == nullptr)
2181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002182 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002183 return false;
2184 }
2185 return true;
2186
2187 case GL_PROGRAM:
2188 if (context->getProgram(name) == nullptr)
2189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002190 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002191 return false;
2192 }
2193 return true;
2194
2195 case GL_VERTEX_ARRAY:
2196 if (context->getVertexArray(name) == nullptr)
2197 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002198 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 return false;
2200 }
2201 return true;
2202
2203 case GL_QUERY:
2204 if (context->getQuery(name) == nullptr)
2205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002206 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002207 return false;
2208 }
2209 return true;
2210
2211 case GL_TRANSFORM_FEEDBACK:
2212 if (context->getTransformFeedback(name) == nullptr)
2213 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002214 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002215 return false;
2216 }
2217 return true;
2218
2219 case GL_SAMPLER:
2220 if (context->getSampler(name) == nullptr)
2221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002222 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002223 return false;
2224 }
2225 return true;
2226
2227 case GL_TEXTURE:
2228 if (context->getTexture(name) == nullptr)
2229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002230 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 return false;
2232 }
2233 return true;
2234
2235 case GL_RENDERBUFFER:
2236 if (context->getRenderbuffer(name) == nullptr)
2237 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002238 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002239 return false;
2240 }
2241 return true;
2242
2243 case GL_FRAMEBUFFER:
2244 if (context->getFramebuffer(name) == nullptr)
2245 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002246 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002247 return false;
2248 }
2249 return true;
2250
2251 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002252 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002253 return false;
2254 }
Geoff Lange102fee2015-12-10 11:23:30 -05002255}
2256
Martin Radev9d901792016-07-15 15:58:58 +03002257static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2258{
2259 size_t labelLength = 0;
2260
2261 if (length < 0)
2262 {
2263 if (label != nullptr)
2264 {
2265 labelLength = strlen(label);
2266 }
2267 }
2268 else
2269 {
2270 labelLength = static_cast<size_t>(length);
2271 }
2272
2273 if (labelLength > context->getExtensions().maxLabelLength)
2274 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002275 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002276 return false;
2277 }
2278
2279 return true;
2280}
2281
Geoff Lange102fee2015-12-10 11:23:30 -05002282bool ValidateObjectLabelKHR(Context *context,
2283 GLenum identifier,
2284 GLuint name,
2285 GLsizei length,
2286 const GLchar *label)
2287{
2288 if (!context->getExtensions().debug)
2289 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002290 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002291 return false;
2292 }
2293
Geoff Lang70d0f492015-12-10 17:45:46 -05002294 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2295 {
2296 return false;
2297 }
2298
Martin Radev9d901792016-07-15 15:58:58 +03002299 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002300 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002301 return false;
2302 }
2303
Geoff Lange102fee2015-12-10 11:23:30 -05002304 return true;
2305}
2306
2307bool ValidateGetObjectLabelKHR(Context *context,
2308 GLenum identifier,
2309 GLuint name,
2310 GLsizei bufSize,
2311 GLsizei *length,
2312 GLchar *label)
2313{
2314 if (!context->getExtensions().debug)
2315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002317 return false;
2318 }
2319
Geoff Lang70d0f492015-12-10 17:45:46 -05002320 if (bufSize < 0)
2321 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002322 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002323 return false;
2324 }
2325
2326 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2327 {
2328 return false;
2329 }
2330
Martin Radev9d901792016-07-15 15:58:58 +03002331 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002332}
2333
2334static bool ValidateObjectPtrName(Context *context, const void *ptr)
2335{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002336 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002337 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002338 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002339 return false;
2340 }
2341
Geoff Lange102fee2015-12-10 11:23:30 -05002342 return true;
2343}
2344
2345bool ValidateObjectPtrLabelKHR(Context *context,
2346 const void *ptr,
2347 GLsizei length,
2348 const GLchar *label)
2349{
2350 if (!context->getExtensions().debug)
2351 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002352 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002353 return false;
2354 }
2355
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 if (!ValidateObjectPtrName(context, ptr))
2357 {
2358 return false;
2359 }
2360
Martin Radev9d901792016-07-15 15:58:58 +03002361 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002362 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002363 return false;
2364 }
2365
Geoff Lange102fee2015-12-10 11:23:30 -05002366 return true;
2367}
2368
2369bool ValidateGetObjectPtrLabelKHR(Context *context,
2370 const void *ptr,
2371 GLsizei bufSize,
2372 GLsizei *length,
2373 GLchar *label)
2374{
2375 if (!context->getExtensions().debug)
2376 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002377 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002378 return false;
2379 }
2380
Geoff Lang70d0f492015-12-10 17:45:46 -05002381 if (bufSize < 0)
2382 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002383 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002384 return false;
2385 }
2386
2387 if (!ValidateObjectPtrName(context, ptr))
2388 {
2389 return false;
2390 }
2391
Martin Radev9d901792016-07-15 15:58:58 +03002392 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002393}
2394
2395bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2396{
2397 if (!context->getExtensions().debug)
2398 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002400 return false;
2401 }
2402
Geoff Lang70d0f492015-12-10 17:45:46 -05002403 // TODO: represent this in Context::getQueryParameterInfo.
2404 switch (pname)
2405 {
2406 case GL_DEBUG_CALLBACK_FUNCTION:
2407 case GL_DEBUG_CALLBACK_USER_PARAM:
2408 break;
2409
2410 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002411 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002412 return false;
2413 }
2414
Geoff Lange102fee2015-12-10 11:23:30 -05002415 return true;
2416}
Jamie Madillc29968b2016-01-20 11:17:23 -05002417
2418bool ValidateBlitFramebufferANGLE(Context *context,
2419 GLint srcX0,
2420 GLint srcY0,
2421 GLint srcX1,
2422 GLint srcY1,
2423 GLint dstX0,
2424 GLint dstY0,
2425 GLint dstX1,
2426 GLint dstY1,
2427 GLbitfield mask,
2428 GLenum filter)
2429{
2430 if (!context->getExtensions().framebufferBlit)
2431 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002432 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002433 return false;
2434 }
2435
2436 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2437 {
2438 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002439 context->handleError(InvalidOperation() << "Scaling and flipping in "
2440 "BlitFramebufferANGLE not supported by this "
2441 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002442 return false;
2443 }
2444
2445 if (filter == GL_LINEAR)
2446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002447 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002448 return false;
2449 }
2450
Jamie Madill51f40ec2016-06-15 14:06:00 -04002451 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2452 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002453
2454 if (mask & GL_COLOR_BUFFER_BIT)
2455 {
2456 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2457 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2458
2459 if (readColorAttachment && drawColorAttachment)
2460 {
2461 if (!(readColorAttachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002462 readColorAttachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002463 readColorAttachment->type() != GL_RENDERBUFFER &&
2464 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002466 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002467 return false;
2468 }
2469
Geoff Langa15472a2015-08-11 11:48:03 -04002470 for (size_t drawbufferIdx = 0;
2471 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002472 {
Geoff Langa15472a2015-08-11 11:48:03 -04002473 const FramebufferAttachment *attachment =
2474 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2475 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002476 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002477 if (!(attachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002478 attachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002479 attachment->type() != GL_RENDERBUFFER &&
2480 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002482 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 return false;
2484 }
2485
2486 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002487 if (!Format::EquivalentForBlit(attachment->getFormat(),
2488 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002490 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 return false;
2492 }
2493 }
2494 }
2495
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002496 if (readFramebuffer->getSamples(context) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002497 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2498 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2499 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002500 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002501 return false;
2502 }
2503 }
2504 }
2505
2506 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2507 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2508 for (size_t i = 0; i < 2; i++)
2509 {
2510 if (mask & masks[i])
2511 {
2512 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002513 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002514 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002515 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002516
2517 if (readBuffer && drawBuffer)
2518 {
2519 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2520 dstX0, dstY0, dstX1, dstY1))
2521 {
2522 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002523 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2524 "stencil blits are supported by "
2525 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002526 return false;
2527 }
2528
2529 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2530 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002531 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002532 return false;
2533 }
2534 }
2535 }
2536 }
2537
2538 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2539 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002540}
Jamie Madillc29968b2016-01-20 11:17:23 -05002541
2542bool ValidateClear(ValidationContext *context, GLbitfield mask)
2543{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002544 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002545 if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002546 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002547 context->handleError(InvalidFramebufferOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002548 return false;
2549 }
2550
2551 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002553 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002554 return false;
2555 }
2556
Geoff Lang76e65652017-03-27 14:58:02 -04002557 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2558 {
2559 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2560 GL_SIGNED_NORMALIZED};
2561
Corentin Wallez59c41592017-07-11 13:19:54 -04002562 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002563 drawBufferIdx++)
2564 {
2565 if (!ValidateWebGLFramebufferAttachmentClearType(
2566 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2567 {
2568 return false;
2569 }
2570 }
2571 }
2572
Jamie Madillc29968b2016-01-20 11:17:23 -05002573 return true;
2574}
2575
2576bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
2577{
2578 if (!context->getExtensions().drawBuffers)
2579 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002580 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002581 return false;
2582 }
2583
2584 return ValidateDrawBuffersBase(context, n, bufs);
2585}
2586
Jamie Madill73a84962016-02-12 09:27:23 -05002587bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002588 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002589 GLint level,
2590 GLint internalformat,
2591 GLsizei width,
2592 GLsizei height,
2593 GLint border,
2594 GLenum format,
2595 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002596 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002597{
Martin Radev1be913c2016-07-11 17:59:16 +03002598 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002599 {
2600 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002601 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002602 }
2603
Martin Radev1be913c2016-07-11 17:59:16 +03002604 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002605 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002606 0, 0, width, height, 1, border, format, type, -1,
2607 pixels);
2608}
2609
2610bool ValidateTexImage2DRobust(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002611 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04002612 GLint level,
2613 GLint internalformat,
2614 GLsizei width,
2615 GLsizei height,
2616 GLint border,
2617 GLenum format,
2618 GLenum type,
2619 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002620 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002621{
2622 if (!ValidateRobustEntryPoint(context, bufSize))
2623 {
2624 return false;
2625 }
2626
2627 if (context->getClientMajorVersion() < 3)
2628 {
2629 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2630 0, 0, width, height, border, format, type, bufSize,
2631 pixels);
2632 }
2633
2634 ASSERT(context->getClientMajorVersion() >= 3);
2635 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2636 0, 0, width, height, 1, border, format, type, bufSize,
2637 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002638}
2639
2640bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002641 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002642 GLint level,
2643 GLint xoffset,
2644 GLint yoffset,
2645 GLsizei width,
2646 GLsizei height,
2647 GLenum format,
2648 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002649 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002650{
2651
Martin Radev1be913c2016-07-11 17:59:16 +03002652 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002653 {
2654 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002655 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002656 }
2657
Martin Radev1be913c2016-07-11 17:59:16 +03002658 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002659 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002660 yoffset, 0, width, height, 1, 0, format, type, -1,
2661 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002662}
2663
Geoff Langc52f6f12016-10-14 10:18:00 -04002664bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002665 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002666 GLint level,
2667 GLint xoffset,
2668 GLint yoffset,
2669 GLsizei width,
2670 GLsizei height,
2671 GLenum format,
2672 GLenum type,
2673 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002674 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002675{
2676 if (!ValidateRobustEntryPoint(context, bufSize))
2677 {
2678 return false;
2679 }
2680
2681 if (context->getClientMajorVersion() < 3)
2682 {
2683 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2684 yoffset, width, height, 0, format, type, bufSize,
2685 pixels);
2686 }
2687
2688 ASSERT(context->getClientMajorVersion() >= 3);
2689 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2690 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2691 pixels);
2692}
2693
Jamie Madill73a84962016-02-12 09:27:23 -05002694bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002695 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002696 GLint level,
2697 GLenum internalformat,
2698 GLsizei width,
2699 GLsizei height,
2700 GLint border,
2701 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002702 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002703{
Martin Radev1be913c2016-07-11 17:59:16 +03002704 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002705 {
2706 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002707 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002708 {
2709 return false;
2710 }
2711 }
2712 else
2713 {
Martin Radev1be913c2016-07-11 17:59:16 +03002714 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002715 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002716 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002717 data))
2718 {
2719 return false;
2720 }
2721 }
2722
Geoff Langca271392017-04-05 12:30:00 -04002723 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002724 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002725 if (blockSizeOrErr.isError())
2726 {
2727 context->handleError(blockSizeOrErr.getError());
2728 return false;
2729 }
2730
2731 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002732 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002733 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002734 return false;
2735 }
2736
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002737 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002738 {
2739 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2740 return false;
2741 }
2742
Jamie Madill73a84962016-02-12 09:27:23 -05002743 return true;
2744}
2745
Corentin Wallezb2931602017-04-11 15:58:57 -04002746bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002747 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002748 GLint level,
2749 GLenum internalformat,
2750 GLsizei width,
2751 GLsizei height,
2752 GLint border,
2753 GLsizei imageSize,
2754 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002755 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002756{
2757 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2758 {
2759 return false;
2760 }
2761
2762 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2763 border, imageSize, data);
2764}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002765
Corentin Wallezb2931602017-04-11 15:58:57 -04002766bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002767 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002768 GLint level,
2769 GLint xoffset,
2770 GLint yoffset,
2771 GLsizei width,
2772 GLsizei height,
2773 GLenum format,
2774 GLsizei imageSize,
2775 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002776 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002777{
2778 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2779 {
2780 return false;
2781 }
2782
2783 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2784 format, imageSize, data);
2785}
2786
Jamie Madill73a84962016-02-12 09:27:23 -05002787bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002788 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002789 GLint level,
2790 GLint xoffset,
2791 GLint yoffset,
2792 GLsizei width,
2793 GLsizei height,
2794 GLenum format,
2795 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002796 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002797{
Martin Radev1be913c2016-07-11 17:59:16 +03002798 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002799 {
2800 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002801 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002802 {
2803 return false;
2804 }
2805 }
2806 else
2807 {
Martin Radev1be913c2016-07-11 17:59:16 +03002808 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002809 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002810 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002811 data))
2812 {
2813 return false;
2814 }
2815 }
2816
Geoff Langca271392017-04-05 12:30:00 -04002817 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002818 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002819 if (blockSizeOrErr.isError())
2820 {
2821 context->handleError(blockSizeOrErr.getError());
2822 return false;
2823 }
2824
2825 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002826 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002827 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002828 return false;
2829 }
2830
2831 return true;
2832}
2833
Corentin Wallez336129f2017-10-17 15:55:40 -04002834bool ValidateGetBufferPointervOES(Context *context,
2835 BufferBinding target,
2836 GLenum pname,
2837 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002838{
Geoff Lang496c02d2016-10-20 11:38:11 -07002839 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002840}
2841
Corentin Wallez336129f2017-10-17 15:55:40 -04002842bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002843{
2844 if (!context->getExtensions().mapBuffer)
2845 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002846 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002847 return false;
2848 }
2849
Corentin Walleze4477002017-12-01 14:39:58 -05002850 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002851 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002852 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002853 return false;
2854 }
2855
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002856 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002857
2858 if (buffer == nullptr)
2859 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002860 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002861 return false;
2862 }
2863
2864 if (access != GL_WRITE_ONLY_OES)
2865 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002866 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002867 return false;
2868 }
2869
2870 if (buffer->isMapped())
2871 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002872 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002873 return false;
2874 }
2875
Geoff Lang79f71042017-08-14 16:43:43 -04002876 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002877}
2878
Corentin Wallez336129f2017-10-17 15:55:40 -04002879bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002880{
2881 if (!context->getExtensions().mapBuffer)
2882 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002883 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002884 return false;
2885 }
2886
2887 return ValidateUnmapBufferBase(context, target);
2888}
2889
2890bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002891 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002892 GLintptr offset,
2893 GLsizeiptr length,
2894 GLbitfield access)
2895{
2896 if (!context->getExtensions().mapBufferRange)
2897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002898 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002899 return false;
2900 }
2901
2902 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2903}
2904
Corentin Wallez336129f2017-10-17 15:55:40 -04002905bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002906{
2907 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2908 ASSERT(buffer != nullptr);
2909
2910 // Check if this buffer is currently being used as a transform feedback output buffer
2911 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2912 if (transformFeedback != nullptr && transformFeedback->isActive())
2913 {
2914 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2915 {
2916 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2917 if (transformFeedbackBuffer.get() == buffer)
2918 {
2919 context->handleError(InvalidOperation()
2920 << "Buffer is currently bound for transform feedback.");
2921 return false;
2922 }
2923 }
2924 }
2925
James Darpiniane8a93c62018-01-04 18:02:24 -08002926 if (context->getExtensions().webglCompatibility &&
2927 buffer->isBoundForTransformFeedbackAndOtherUse())
2928 {
2929 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2930 return false;
2931 }
2932
Geoff Lang79f71042017-08-14 16:43:43 -04002933 return true;
2934}
2935
Olli Etuaho4f667482016-03-30 15:56:35 +03002936bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002937 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002938 GLintptr offset,
2939 GLsizeiptr length)
2940{
2941 if (!context->getExtensions().mapBufferRange)
2942 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002943 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002944 return false;
2945 }
2946
2947 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2948}
2949
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002950bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002951{
2952 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002953 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002954 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002955 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002956 return false;
2957 }
2958
Geoff Langf41a7152016-09-19 15:11:17 -04002959 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2960 !context->isTextureGenerated(texture))
2961 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002962 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002963 return false;
2964 }
2965
Ian Ewell54f87462016-03-10 13:47:21 -05002966 switch (target)
2967 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002968 case TextureType::_2D:
2969 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002970 break;
2971
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002972 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002973 if (!context->getExtensions().textureRectangle)
2974 {
2975 context->handleError(InvalidEnum()
2976 << "Context does not support GL_ANGLE_texture_rectangle");
2977 return false;
2978 }
2979 break;
2980
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002981 case TextureType::_3D:
2982 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002983 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002984 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002986 return false;
2987 }
2988 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002989
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002990 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04002991 if (context->getClientVersion() < Version(3, 1))
2992 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002993 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002994 return false;
2995 }
Geoff Lang3b573612016-10-31 14:08:10 -04002996 break;
2997
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002998 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04002999 if (!context->getExtensions().eglImageExternal &&
3000 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003001 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003002 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003003 return false;
3004 }
3005 break;
3006 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003007 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003008 return false;
3009 }
3010
3011 return true;
3012}
3013
Geoff Langd8605522016-04-13 10:19:12 -04003014bool ValidateBindUniformLocationCHROMIUM(Context *context,
3015 GLuint program,
3016 GLint location,
3017 const GLchar *name)
3018{
3019 if (!context->getExtensions().bindUniformLocation)
3020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003021 context->handleError(InvalidOperation()
3022 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003023 return false;
3024 }
3025
3026 Program *programObject = GetValidProgram(context, program);
3027 if (!programObject)
3028 {
3029 return false;
3030 }
3031
3032 if (location < 0)
3033 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003034 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003035 return false;
3036 }
3037
3038 const Caps &caps = context->getCaps();
3039 if (static_cast<size_t>(location) >=
3040 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003042 context->handleError(InvalidValue() << "Location must be less than "
3043 "(MAX_VERTEX_UNIFORM_VECTORS + "
3044 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003045 return false;
3046 }
3047
Geoff Langfc32e8b2017-05-31 14:16:59 -04003048 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3049 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003050 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003051 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003052 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003053 return false;
3054 }
3055
Geoff Langd8605522016-04-13 10:19:12 -04003056 if (strncmp(name, "gl_", 3) == 0)
3057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003058 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003059 return false;
3060 }
3061
3062 return true;
3063}
3064
Jamie Madille2e406c2016-06-02 13:04:10 -04003065bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003066{
3067 if (!context->getExtensions().framebufferMixedSamples)
3068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003069 context->handleError(InvalidOperation()
3070 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003071 return false;
3072 }
3073 switch (components)
3074 {
3075 case GL_RGB:
3076 case GL_RGBA:
3077 case GL_ALPHA:
3078 case GL_NONE:
3079 break;
3080 default:
3081 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003082 InvalidEnum()
3083 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003084 return false;
3085 }
3086
3087 return true;
3088}
3089
Sami Väisänene45e53b2016-05-25 10:36:04 +03003090// CHROMIUM_path_rendering
3091
Jamie Madill007530e2017-12-28 14:27:04 -05003092bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003093{
Jamie Madill007530e2017-12-28 14:27:04 -05003094 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003095 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003096 return false;
3097 }
Jamie Madill007530e2017-12-28 14:27:04 -05003098
Sami Väisänene45e53b2016-05-25 10:36:04 +03003099 if (matrix == nullptr)
3100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003101 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003102 return false;
3103 }
Jamie Madill007530e2017-12-28 14:27:04 -05003104
Sami Väisänene45e53b2016-05-25 10:36:04 +03003105 return true;
3106}
3107
Jamie Madill007530e2017-12-28 14:27:04 -05003108bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003109{
Jamie Madill007530e2017-12-28 14:27:04 -05003110 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111}
3112
Jamie Madill007530e2017-12-28 14:27:04 -05003113bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003114{
3115 if (!context->getExtensions().pathRendering)
3116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003117 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003118 return false;
3119 }
3120
3121 // range = 0 is undefined in NV_path_rendering.
3122 // we add stricter semantic check here and require a non zero positive range.
3123 if (range <= 0)
3124 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003125 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003126 return false;
3127 }
3128
3129 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3130 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003131 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003132 return false;
3133 }
3134
3135 return true;
3136}
3137
Jamie Madill007530e2017-12-28 14:27:04 -05003138bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003139{
3140 if (!context->getExtensions().pathRendering)
3141 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003142 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003143 return false;
3144 }
3145
3146 // range = 0 is undefined in NV_path_rendering.
3147 // we add stricter semantic check here and require a non zero positive range.
3148 if (range <= 0)
3149 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003150 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003151 return false;
3152 }
3153
3154 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3155 checkedRange += range;
3156
3157 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003160 return false;
3161 }
3162 return true;
3163}
3164
Jamie Madill007530e2017-12-28 14:27:04 -05003165bool ValidatePathCommandsCHROMIUM(Context *context,
3166 GLuint path,
3167 GLsizei numCommands,
3168 const GLubyte *commands,
3169 GLsizei numCoords,
3170 GLenum coordType,
3171 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003172{
3173 if (!context->getExtensions().pathRendering)
3174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003175 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003176 return false;
3177 }
3178 if (!context->hasPath(path))
3179 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003180 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181 return false;
3182 }
3183
3184 if (numCommands < 0)
3185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003186 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003187 return false;
3188 }
3189 else if (numCommands > 0)
3190 {
3191 if (!commands)
3192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003193 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003194 return false;
3195 }
3196 }
3197
3198 if (numCoords < 0)
3199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003200 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003201 return false;
3202 }
3203 else if (numCoords > 0)
3204 {
3205 if (!coords)
3206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003207 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003208 return false;
3209 }
3210 }
3211
3212 std::uint32_t coordTypeSize = 0;
3213 switch (coordType)
3214 {
3215 case GL_BYTE:
3216 coordTypeSize = sizeof(GLbyte);
3217 break;
3218
3219 case GL_UNSIGNED_BYTE:
3220 coordTypeSize = sizeof(GLubyte);
3221 break;
3222
3223 case GL_SHORT:
3224 coordTypeSize = sizeof(GLshort);
3225 break;
3226
3227 case GL_UNSIGNED_SHORT:
3228 coordTypeSize = sizeof(GLushort);
3229 break;
3230
3231 case GL_FLOAT:
3232 coordTypeSize = sizeof(GLfloat);
3233 break;
3234
3235 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003236 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003237 return false;
3238 }
3239
3240 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3241 checkedSize += (coordTypeSize * numCoords);
3242 if (!checkedSize.IsValid())
3243 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003244 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003245 return false;
3246 }
3247
3248 // early return skips command data validation when it doesn't exist.
3249 if (!commands)
3250 return true;
3251
3252 GLsizei expectedNumCoords = 0;
3253 for (GLsizei i = 0; i < numCommands; ++i)
3254 {
3255 switch (commands[i])
3256 {
3257 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3258 break;
3259 case GL_MOVE_TO_CHROMIUM:
3260 case GL_LINE_TO_CHROMIUM:
3261 expectedNumCoords += 2;
3262 break;
3263 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3264 expectedNumCoords += 4;
3265 break;
3266 case GL_CUBIC_CURVE_TO_CHROMIUM:
3267 expectedNumCoords += 6;
3268 break;
3269 case GL_CONIC_CURVE_TO_CHROMIUM:
3270 expectedNumCoords += 5;
3271 break;
3272 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003273 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003274 return false;
3275 }
3276 }
3277 if (expectedNumCoords != numCoords)
3278 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003279 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280 return false;
3281 }
3282
3283 return true;
3284}
3285
Jamie Madill007530e2017-12-28 14:27:04 -05003286bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003287{
3288 if (!context->getExtensions().pathRendering)
3289 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003290 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003291 return false;
3292 }
3293 if (!context->hasPath(path))
3294 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003296 return false;
3297 }
3298
3299 switch (pname)
3300 {
3301 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3302 if (value < 0.0f)
3303 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003304 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003305 return false;
3306 }
3307 break;
3308 case GL_PATH_END_CAPS_CHROMIUM:
3309 switch (static_cast<GLenum>(value))
3310 {
3311 case GL_FLAT_CHROMIUM:
3312 case GL_SQUARE_CHROMIUM:
3313 case GL_ROUND_CHROMIUM:
3314 break;
3315 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003316 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317 return false;
3318 }
3319 break;
3320 case GL_PATH_JOIN_STYLE_CHROMIUM:
3321 switch (static_cast<GLenum>(value))
3322 {
3323 case GL_MITER_REVERT_CHROMIUM:
3324 case GL_BEVEL_CHROMIUM:
3325 case GL_ROUND_CHROMIUM:
3326 break;
3327 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003328 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003329 return false;
3330 }
Nico Weber41b072b2018-02-09 10:01:32 -05003331 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003332 case GL_PATH_MITER_LIMIT_CHROMIUM:
3333 if (value < 0.0f)
3334 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003335 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003336 return false;
3337 }
3338 break;
3339
3340 case GL_PATH_STROKE_BOUND_CHROMIUM:
3341 // no errors, only clamping.
3342 break;
3343
3344 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003345 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003346 return false;
3347 }
3348 return true;
3349}
3350
Jamie Madill007530e2017-12-28 14:27:04 -05003351bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3352{
3353 // TODO(jmadill): Use proper clamping cast.
3354 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3355}
3356
3357bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003358{
3359 if (!context->getExtensions().pathRendering)
3360 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003361 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003362 return false;
3363 }
3364
3365 if (!context->hasPath(path))
3366 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003367 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003368 return false;
3369 }
3370 if (!value)
3371 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003372 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003373 return false;
3374 }
3375
3376 switch (pname)
3377 {
3378 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3379 case GL_PATH_END_CAPS_CHROMIUM:
3380 case GL_PATH_JOIN_STYLE_CHROMIUM:
3381 case GL_PATH_MITER_LIMIT_CHROMIUM:
3382 case GL_PATH_STROKE_BOUND_CHROMIUM:
3383 break;
3384
3385 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003386 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003387 return false;
3388 }
3389
3390 return true;
3391}
3392
Jamie Madill007530e2017-12-28 14:27:04 -05003393bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3394{
3395 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3396 reinterpret_cast<GLfloat *>(value));
3397}
3398
3399bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003400{
3401 if (!context->getExtensions().pathRendering)
3402 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003403 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003404 return false;
3405 }
3406
3407 switch (func)
3408 {
3409 case GL_NEVER:
3410 case GL_ALWAYS:
3411 case GL_LESS:
3412 case GL_LEQUAL:
3413 case GL_EQUAL:
3414 case GL_GEQUAL:
3415 case GL_GREATER:
3416 case GL_NOTEQUAL:
3417 break;
3418 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003419 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003420 return false;
3421 }
3422
3423 return true;
3424}
3425
3426// Note that the spec specifies that for the path drawing commands
3427// if the path object is not an existing path object the command
3428// does nothing and no error is generated.
3429// However if the path object exists but has not been specified any
3430// commands then an error is generated.
3431
Jamie Madill007530e2017-12-28 14:27:04 -05003432bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003433{
3434 if (!context->getExtensions().pathRendering)
3435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003436 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003437 return false;
3438 }
3439 if (context->hasPath(path) && !context->hasPathData(path))
3440 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003441 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003442 return false;
3443 }
3444
3445 switch (fillMode)
3446 {
3447 case GL_COUNT_UP_CHROMIUM:
3448 case GL_COUNT_DOWN_CHROMIUM:
3449 break;
3450 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003451 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003452 return false;
3453 }
3454
3455 if (!isPow2(mask + 1))
3456 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003457 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458 return false;
3459 }
3460
3461 return true;
3462}
3463
Jamie Madill007530e2017-12-28 14:27:04 -05003464bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003465{
3466 if (!context->getExtensions().pathRendering)
3467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003468 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003469 return false;
3470 }
3471 if (context->hasPath(path) && !context->hasPathData(path))
3472 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003473 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474 return false;
3475 }
3476
3477 return true;
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 }
3487 if (context->hasPath(path) && !context->hasPathData(path))
3488 {
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
Jamie Madill007530e2017-12-28 14:27:04 -05003525bool ValidateIsPathCHROMIUM(Context *context)
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
Martin Radev4c4c8e72016-08-04 12:25:34 +03004160bool ValidateCreateShader(Context *context, GLenum type)
4161{
4162 switch (type)
4163 {
4164 case GL_VERTEX_SHADER:
4165 case GL_FRAGMENT_SHADER:
4166 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004167
Martin Radev4c4c8e72016-08-04 12:25:34 +03004168 case GL_COMPUTE_SHADER:
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 Shao89be29a2017-11-06 14:36:45 +08004176 case GL_GEOMETRY_SHADER_EXT:
4177 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
4191bool ValidateBufferData(ValidationContext *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
4252bool ValidateBufferSubData(ValidationContext *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 Madillef300b12016-10-07 15:12:09 -04004332bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4333{
4334 if (texture < GL_TEXTURE0 ||
4335 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4336 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004337 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004338 return false;
4339 }
4340
4341 return true;
4342}
4343
4344bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4345{
4346 Program *programObject = GetValidProgram(context, program);
4347 if (!programObject)
4348 {
4349 return false;
4350 }
4351
4352 Shader *shaderObject = GetValidShader(context, shader);
4353 if (!shaderObject)
4354 {
4355 return false;
4356 }
4357
4358 switch (shaderObject->getType())
4359 {
4360 case GL_VERTEX_SHADER:
4361 {
4362 if (programObject->getAttachedVertexShader())
4363 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004365 return false;
4366 }
4367 break;
4368 }
4369 case GL_FRAGMENT_SHADER:
4370 {
4371 if (programObject->getAttachedFragmentShader())
4372 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004373 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004374 return false;
4375 }
4376 break;
4377 }
4378 case GL_COMPUTE_SHADER:
4379 {
4380 if (programObject->getAttachedComputeShader())
4381 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004383 return false;
4384 }
4385 break;
4386 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004387 case GL_GEOMETRY_SHADER_EXT:
4388 {
4389 if (programObject->getAttachedGeometryShader())
4390 {
4391 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4392 return false;
4393 }
4394 break;
4395 }
Jamie Madillef300b12016-10-07 15:12:09 -04004396 default:
4397 UNREACHABLE();
4398 break;
4399 }
4400
4401 return true;
4402}
4403
Jamie Madill01a80ee2016-11-07 12:06:18 -05004404bool ValidateBindAttribLocation(ValidationContext *context,
4405 GLuint program,
4406 GLuint index,
4407 const GLchar *name)
4408{
4409 if (index >= MAX_VERTEX_ATTRIBS)
4410 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004411 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004412 return false;
4413 }
4414
4415 if (strncmp(name, "gl_", 3) == 0)
4416 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004417 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004418 return false;
4419 }
4420
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004421 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004422 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004423 const size_t length = strlen(name);
4424
4425 if (!IsValidESSLString(name, length))
4426 {
4427 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4428 // for shader-related entry points
4429 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4430 return false;
4431 }
4432
4433 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4434 {
4435 return false;
4436 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004437 }
4438
Jamie Madill01a80ee2016-11-07 12:06:18 -05004439 return GetValidProgram(context, program) != nullptr;
4440}
4441
Corentin Wallez336129f2017-10-17 15:55:40 -04004442bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004443{
Corentin Walleze4477002017-12-01 14:39:58 -05004444 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004445 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004446 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004447 return false;
4448 }
4449
4450 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4451 !context->isBufferGenerated(buffer))
4452 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004453 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004454 return false;
4455 }
4456
4457 return true;
4458}
4459
4460bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4461{
Geoff Lange8afa902017-09-27 15:00:43 -04004462 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004463 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004464 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004465 return false;
4466 }
4467
4468 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4469 !context->isFramebufferGenerated(framebuffer))
4470 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004471 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004472 return false;
4473 }
4474
4475 return true;
4476}
4477
4478bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4479{
4480 if (target != GL_RENDERBUFFER)
4481 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004482 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004483 return false;
4484 }
4485
4486 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4487 !context->isRenderbufferGenerated(renderbuffer))
4488 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004489 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004490 return false;
4491 }
4492
4493 return true;
4494}
4495
Geoff Lang50cac572017-09-26 17:37:43 -04004496static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004497{
4498 switch (mode)
4499 {
4500 case GL_FUNC_ADD:
4501 case GL_FUNC_SUBTRACT:
4502 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004503 return true;
4504
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004505 case GL_MIN:
4506 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004507 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004508
4509 default:
4510 return false;
4511 }
4512}
4513
Jamie Madillc1d770e2017-04-13 17:31:24 -04004514bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004515 GLfloat red,
4516 GLfloat green,
4517 GLfloat blue,
4518 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004519{
4520 return true;
4521}
4522
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004523bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4524{
Geoff Lang50cac572017-09-26 17:37:43 -04004525 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004526 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004527 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004528 return false;
4529 }
4530
4531 return true;
4532}
4533
4534bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4535{
Geoff Lang50cac572017-09-26 17:37:43 -04004536 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004537 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004538 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004539 return false;
4540 }
4541
Geoff Lang50cac572017-09-26 17:37:43 -04004542 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004543 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004544 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004545 return false;
4546 }
4547
4548 return true;
4549}
4550
4551bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4552{
4553 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4554}
4555
4556static bool ValidSrcBlendFunc(GLenum srcBlend)
4557{
4558 switch (srcBlend)
4559 {
4560 case GL_ZERO:
4561 case GL_ONE:
4562 case GL_SRC_COLOR:
4563 case GL_ONE_MINUS_SRC_COLOR:
4564 case GL_DST_COLOR:
4565 case GL_ONE_MINUS_DST_COLOR:
4566 case GL_SRC_ALPHA:
4567 case GL_ONE_MINUS_SRC_ALPHA:
4568 case GL_DST_ALPHA:
4569 case GL_ONE_MINUS_DST_ALPHA:
4570 case GL_CONSTANT_COLOR:
4571 case GL_ONE_MINUS_CONSTANT_COLOR:
4572 case GL_CONSTANT_ALPHA:
4573 case GL_ONE_MINUS_CONSTANT_ALPHA:
4574 case GL_SRC_ALPHA_SATURATE:
4575 return true;
4576
4577 default:
4578 return false;
4579 }
4580}
4581
4582static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4583{
4584 switch (dstBlend)
4585 {
4586 case GL_ZERO:
4587 case GL_ONE:
4588 case GL_SRC_COLOR:
4589 case GL_ONE_MINUS_SRC_COLOR:
4590 case GL_DST_COLOR:
4591 case GL_ONE_MINUS_DST_COLOR:
4592 case GL_SRC_ALPHA:
4593 case GL_ONE_MINUS_SRC_ALPHA:
4594 case GL_DST_ALPHA:
4595 case GL_ONE_MINUS_DST_ALPHA:
4596 case GL_CONSTANT_COLOR:
4597 case GL_ONE_MINUS_CONSTANT_COLOR:
4598 case GL_CONSTANT_ALPHA:
4599 case GL_ONE_MINUS_CONSTANT_ALPHA:
4600 return true;
4601
4602 case GL_SRC_ALPHA_SATURATE:
4603 return (contextMajorVersion >= 3);
4604
4605 default:
4606 return false;
4607 }
4608}
4609
4610bool ValidateBlendFuncSeparate(ValidationContext *context,
4611 GLenum srcRGB,
4612 GLenum dstRGB,
4613 GLenum srcAlpha,
4614 GLenum dstAlpha)
4615{
4616 if (!ValidSrcBlendFunc(srcRGB))
4617 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004618 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004619 return false;
4620 }
4621
4622 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4623 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004624 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004625 return false;
4626 }
4627
4628 if (!ValidSrcBlendFunc(srcAlpha))
4629 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004630 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004631 return false;
4632 }
4633
4634 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4635 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004636 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004637 return false;
4638 }
4639
Frank Henigman146e8a12017-03-02 23:22:37 -05004640 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4641 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004642 {
4643 bool constantColorUsed =
4644 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4645 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4646
4647 bool constantAlphaUsed =
4648 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4649 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4650
4651 if (constantColorUsed && constantAlphaUsed)
4652 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004653 const char *msg;
4654 if (context->getExtensions().webglCompatibility)
4655 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004656 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004657 }
4658 else
4659 {
4660 msg =
4661 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4662 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4663 "implementation.";
4664 ERR() << msg;
4665 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004666 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004667 return false;
4668 }
4669 }
4670
4671 return true;
4672}
4673
Geoff Langc339c4e2016-11-29 10:37:36 -05004674bool ValidateGetString(Context *context, GLenum name)
4675{
4676 switch (name)
4677 {
4678 case GL_VENDOR:
4679 case GL_RENDERER:
4680 case GL_VERSION:
4681 case GL_SHADING_LANGUAGE_VERSION:
4682 case GL_EXTENSIONS:
4683 break;
4684
4685 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4686 if (!context->getExtensions().requestExtension)
4687 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004688 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004689 return false;
4690 }
4691 break;
4692
4693 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004694 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004695 return false;
4696 }
4697
4698 return true;
4699}
4700
Geoff Lang47c48082016-12-07 15:38:13 -05004701bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4702{
4703 if (width <= 0.0f || isNaN(width))
4704 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004705 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004706 return false;
4707 }
4708
4709 return true;
4710}
4711
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004712bool ValidateVertexAttribPointer(ValidationContext *context,
4713 GLuint index,
4714 GLint size,
4715 GLenum type,
4716 GLboolean normalized,
4717 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004718 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004719{
Shao80957d92017-02-20 21:25:59 +08004720 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004721 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004722 return false;
4723 }
4724
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004725 if (stride < 0)
4726 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004727 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004728 return false;
4729 }
4730
Shao80957d92017-02-20 21:25:59 +08004731 const Caps &caps = context->getCaps();
4732 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004733 {
Shao80957d92017-02-20 21:25:59 +08004734 if (stride > caps.maxVertexAttribStride)
4735 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004736 context->handleError(InvalidValue()
4737 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004738 return false;
4739 }
4740
4741 if (index >= caps.maxVertexAttribBindings)
4742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004743 context->handleError(InvalidValue()
4744 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004745 return false;
4746 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004747 }
4748
4749 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4750 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4751 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4752 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004753 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4754 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004755 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4756 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004757 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004758 context
4759 ->handleError(InvalidOperation()
4760 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004761 return false;
4762 }
4763
4764 if (context->getExtensions().webglCompatibility)
4765 {
4766 // WebGL 1.0 [Section 6.14] Fixed point support
4767 // The WebGL API does not support the GL_FIXED data type.
4768 if (type == GL_FIXED)
4769 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004770 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004771 return false;
4772 }
4773
Geoff Lang2d62ab72017-03-23 16:54:40 -04004774 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004775 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004776 return false;
4777 }
4778 }
4779
4780 return true;
4781}
4782
Jamie Madill876429b2017-04-20 15:46:24 -04004783bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004784{
4785 if (context->getExtensions().webglCompatibility && zNear > zFar)
4786 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004787 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004788 return false;
4789 }
4790
4791 return true;
4792}
4793
Jamie Madille8fb6402017-02-14 17:56:40 -05004794bool ValidateRenderbufferStorage(ValidationContext *context,
4795 GLenum target,
4796 GLenum internalformat,
4797 GLsizei width,
4798 GLsizei height)
4799{
4800 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4801 height);
4802}
4803
4804bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4805 GLenum target,
4806 GLsizei samples,
4807 GLenum internalformat,
4808 GLsizei width,
4809 GLsizei height)
4810{
4811 if (!context->getExtensions().framebufferMultisample)
4812 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004813 context->handleError(InvalidOperation()
4814 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004815 return false;
4816 }
4817
4818 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4819 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4820 // generated.
4821 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4822 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004823 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004824 return false;
4825 }
4826
4827 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4828 // the specified storage. This is different than ES 3.0 in which a sample number higher
4829 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4830 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4831 if (context->getClientMajorVersion() >= 3)
4832 {
4833 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4834 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4835 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004836 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004837 return false;
4838 }
4839 }
4840
4841 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4842 width, height);
4843}
4844
Jamie Madillc1d770e2017-04-13 17:31:24 -04004845bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4846{
Geoff Lange8afa902017-09-27 15:00:43 -04004847 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004848 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004849 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004850 return false;
4851 }
4852
4853 return true;
4854}
4855
4856bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004857 GLfloat red,
4858 GLfloat green,
4859 GLfloat blue,
4860 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004861{
4862 return true;
4863}
4864
Jamie Madill876429b2017-04-20 15:46:24 -04004865bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004866{
4867 return true;
4868}
4869
4870bool ValidateClearStencil(ValidationContext *context, GLint s)
4871{
4872 return true;
4873}
4874
4875bool ValidateColorMask(ValidationContext *context,
4876 GLboolean red,
4877 GLboolean green,
4878 GLboolean blue,
4879 GLboolean alpha)
4880{
4881 return true;
4882}
4883
4884bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4885{
4886 return true;
4887}
4888
4889bool ValidateCreateProgram(ValidationContext *context)
4890{
4891 return true;
4892}
4893
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004894bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004895{
4896 switch (mode)
4897 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004898 case CullFaceMode::Front:
4899 case CullFaceMode::Back:
4900 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004901 break;
4902
4903 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004904 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004905 return false;
4906 }
4907
4908 return true;
4909}
4910
4911bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4912{
4913 if (program == 0)
4914 {
4915 return false;
4916 }
4917
4918 if (!context->getProgram(program))
4919 {
4920 if (context->getShader(program))
4921 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004922 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004923 return false;
4924 }
4925 else
4926 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004927 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004928 return false;
4929 }
4930 }
4931
4932 return true;
4933}
4934
4935bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4936{
4937 if (shader == 0)
4938 {
4939 return false;
4940 }
4941
4942 if (!context->getShader(shader))
4943 {
4944 if (context->getProgram(shader))
4945 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004946 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004947 return false;
4948 }
4949 else
4950 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004951 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004952 return false;
4953 }
4954 }
4955
4956 return true;
4957}
4958
4959bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4960{
4961 switch (func)
4962 {
4963 case GL_NEVER:
4964 case GL_ALWAYS:
4965 case GL_LESS:
4966 case GL_LEQUAL:
4967 case GL_EQUAL:
4968 case GL_GREATER:
4969 case GL_GEQUAL:
4970 case GL_NOTEQUAL:
4971 break;
4972
4973 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004974 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004975 return false;
4976 }
4977
4978 return true;
4979}
4980
4981bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4982{
4983 return true;
4984}
4985
4986bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4987{
4988 Program *programObject = GetValidProgram(context, program);
4989 if (!programObject)
4990 {
4991 return false;
4992 }
4993
4994 Shader *shaderObject = GetValidShader(context, shader);
4995 if (!shaderObject)
4996 {
4997 return false;
4998 }
4999
5000 const Shader *attachedShader = nullptr;
5001
5002 switch (shaderObject->getType())
5003 {
5004 case GL_VERTEX_SHADER:
5005 {
5006 attachedShader = programObject->getAttachedVertexShader();
5007 break;
5008 }
5009 case GL_FRAGMENT_SHADER:
5010 {
5011 attachedShader = programObject->getAttachedFragmentShader();
5012 break;
5013 }
5014 case GL_COMPUTE_SHADER:
5015 {
5016 attachedShader = programObject->getAttachedComputeShader();
5017 break;
5018 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08005019 case GL_GEOMETRY_SHADER_EXT:
5020 {
5021 attachedShader = programObject->getAttachedGeometryShader();
5022 break;
5023 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04005024 default:
5025 UNREACHABLE();
5026 return false;
5027 }
5028
5029 if (attachedShader != shaderObject)
5030 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005031 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005032 return false;
5033 }
5034
5035 return true;
5036}
5037
5038bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
5039{
5040 if (index >= MAX_VERTEX_ATTRIBS)
5041 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005042 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005043 return false;
5044 }
5045
5046 return true;
5047}
5048
5049bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
5050{
5051 if (index >= MAX_VERTEX_ATTRIBS)
5052 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005053 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005054 return false;
5055 }
5056
5057 return true;
5058}
5059
5060bool ValidateFinish(ValidationContext *context)
5061{
5062 return true;
5063}
5064
5065bool ValidateFlush(ValidationContext *context)
5066{
5067 return true;
5068}
5069
5070bool ValidateFrontFace(ValidationContext *context, GLenum mode)
5071{
5072 switch (mode)
5073 {
5074 case GL_CW:
5075 case GL_CCW:
5076 break;
5077 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005078 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005079 return false;
5080 }
5081
5082 return true;
5083}
5084
5085bool ValidateGetActiveAttrib(ValidationContext *context,
5086 GLuint program,
5087 GLuint index,
5088 GLsizei bufsize,
5089 GLsizei *length,
5090 GLint *size,
5091 GLenum *type,
5092 GLchar *name)
5093{
5094 if (bufsize < 0)
5095 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005096 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005097 return false;
5098 }
5099
5100 Program *programObject = GetValidProgram(context, program);
5101
5102 if (!programObject)
5103 {
5104 return false;
5105 }
5106
5107 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5108 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005109 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110 return false;
5111 }
5112
5113 return true;
5114}
5115
5116bool ValidateGetActiveUniform(ValidationContext *context,
5117 GLuint program,
5118 GLuint index,
5119 GLsizei bufsize,
5120 GLsizei *length,
5121 GLint *size,
5122 GLenum *type,
5123 GLchar *name)
5124{
5125 if (bufsize < 0)
5126 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005127 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005128 return false;
5129 }
5130
5131 Program *programObject = GetValidProgram(context, program);
5132
5133 if (!programObject)
5134 {
5135 return false;
5136 }
5137
5138 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5139 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005140 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005141 return false;
5142 }
5143
5144 return true;
5145}
5146
5147bool ValidateGetAttachedShaders(ValidationContext *context,
5148 GLuint program,
5149 GLsizei maxcount,
5150 GLsizei *count,
5151 GLuint *shaders)
5152{
5153 if (maxcount < 0)
5154 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005155 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005156 return false;
5157 }
5158
5159 Program *programObject = GetValidProgram(context, program);
5160
5161 if (!programObject)
5162 {
5163 return false;
5164 }
5165
5166 return true;
5167}
5168
5169bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5170{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005171 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5172 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005173 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005174 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005175 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005176 return false;
5177 }
5178
Jamie Madillc1d770e2017-04-13 17:31:24 -04005179 Program *programObject = GetValidProgram(context, program);
5180
5181 if (!programObject)
5182 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005183 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005184 return false;
5185 }
5186
5187 if (!programObject->isLinked())
5188 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005189 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005190 return false;
5191 }
5192
5193 return true;
5194}
5195
5196bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5197{
5198 GLenum nativeType;
5199 unsigned int numParams = 0;
5200 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5201}
5202
5203bool ValidateGetError(ValidationContext *context)
5204{
5205 return true;
5206}
5207
5208bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5209{
5210 GLenum nativeType;
5211 unsigned int numParams = 0;
5212 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5213}
5214
5215bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5216{
5217 GLenum nativeType;
5218 unsigned int numParams = 0;
5219 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5220}
5221
5222bool ValidateGetProgramInfoLog(ValidationContext *context,
5223 GLuint program,
5224 GLsizei bufsize,
5225 GLsizei *length,
5226 GLchar *infolog)
5227{
5228 if (bufsize < 0)
5229 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005230 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005231 return false;
5232 }
5233
5234 Program *programObject = GetValidProgram(context, program);
5235 if (!programObject)
5236 {
5237 return false;
5238 }
5239
5240 return true;
5241}
5242
5243bool ValidateGetShaderInfoLog(ValidationContext *context,
5244 GLuint shader,
5245 GLsizei bufsize,
5246 GLsizei *length,
5247 GLchar *infolog)
5248{
5249 if (bufsize < 0)
5250 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005251 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005252 return false;
5253 }
5254
5255 Shader *shaderObject = GetValidShader(context, shader);
5256 if (!shaderObject)
5257 {
5258 return false;
5259 }
5260
5261 return true;
5262}
5263
5264bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5265 GLenum shadertype,
5266 GLenum precisiontype,
5267 GLint *range,
5268 GLint *precision)
5269{
5270 switch (shadertype)
5271 {
5272 case GL_VERTEX_SHADER:
5273 case GL_FRAGMENT_SHADER:
5274 break;
5275 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005276 context->handleError(InvalidOperation()
5277 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005278 return false;
5279 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005280 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005281 return false;
5282 }
5283
5284 switch (precisiontype)
5285 {
5286 case GL_LOW_FLOAT:
5287 case GL_MEDIUM_FLOAT:
5288 case GL_HIGH_FLOAT:
5289 case GL_LOW_INT:
5290 case GL_MEDIUM_INT:
5291 case GL_HIGH_INT:
5292 break;
5293
5294 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005295 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005296 return false;
5297 }
5298
5299 return true;
5300}
5301
5302bool ValidateGetShaderSource(ValidationContext *context,
5303 GLuint shader,
5304 GLsizei bufsize,
5305 GLsizei *length,
5306 GLchar *source)
5307{
5308 if (bufsize < 0)
5309 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005310 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005311 return false;
5312 }
5313
5314 Shader *shaderObject = GetValidShader(context, shader);
5315 if (!shaderObject)
5316 {
5317 return false;
5318 }
5319
5320 return true;
5321}
5322
5323bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5324{
5325 if (strstr(name, "gl_") == name)
5326 {
5327 return false;
5328 }
5329
Geoff Langfc32e8b2017-05-31 14:16:59 -04005330 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5331 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005332 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005333 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005334 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005335 return false;
5336 }
5337
Jamie Madillc1d770e2017-04-13 17:31:24 -04005338 Program *programObject = GetValidProgram(context, program);
5339
5340 if (!programObject)
5341 {
5342 return false;
5343 }
5344
5345 if (!programObject->isLinked())
5346 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005347 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005348 return false;
5349 }
5350
5351 return true;
5352}
5353
5354bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5355{
5356 switch (mode)
5357 {
5358 case GL_FASTEST:
5359 case GL_NICEST:
5360 case GL_DONT_CARE:
5361 break;
5362
5363 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005364 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005365 return false;
5366 }
5367
5368 switch (target)
5369 {
5370 case GL_GENERATE_MIPMAP_HINT:
5371 break;
5372
Geoff Lange7bd2182017-06-16 16:13:13 -04005373 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5374 if (context->getClientVersion() < ES_3_0 &&
5375 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005376 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005377 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378 return false;
5379 }
5380 break;
5381
5382 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005383 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005384 return false;
5385 }
5386
5387 return true;
5388}
5389
5390bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5391{
5392 return true;
5393}
5394
5395bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5396{
5397 return true;
5398}
5399
5400bool ValidateIsProgram(ValidationContext *context, GLuint program)
5401{
5402 return true;
5403}
5404
5405bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5406{
5407 return true;
5408}
5409
5410bool ValidateIsShader(ValidationContext *context, GLuint shader)
5411{
5412 return true;
5413}
5414
5415bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5416{
5417 return true;
5418}
5419
5420bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5421{
5422 if (context->getClientMajorVersion() < 3)
5423 {
5424 switch (pname)
5425 {
5426 case GL_UNPACK_IMAGE_HEIGHT:
5427 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005428 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005429 return false;
5430
5431 case GL_UNPACK_ROW_LENGTH:
5432 case GL_UNPACK_SKIP_ROWS:
5433 case GL_UNPACK_SKIP_PIXELS:
5434 if (!context->getExtensions().unpackSubimage)
5435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005436 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005437 return false;
5438 }
5439 break;
5440
5441 case GL_PACK_ROW_LENGTH:
5442 case GL_PACK_SKIP_ROWS:
5443 case GL_PACK_SKIP_PIXELS:
5444 if (!context->getExtensions().packSubimage)
5445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005446 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005447 return false;
5448 }
5449 break;
5450 }
5451 }
5452
5453 if (param < 0)
5454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005455 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005456 return false;
5457 }
5458
5459 switch (pname)
5460 {
5461 case GL_UNPACK_ALIGNMENT:
5462 if (param != 1 && param != 2 && param != 4 && param != 8)
5463 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005464 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005465 return false;
5466 }
5467 break;
5468
5469 case GL_PACK_ALIGNMENT:
5470 if (param != 1 && param != 2 && param != 4 && param != 8)
5471 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005472 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005473 return false;
5474 }
5475 break;
5476
5477 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005478 if (!context->getExtensions().packReverseRowOrder)
5479 {
5480 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5481 }
5482 break;
5483
Jamie Madillc1d770e2017-04-13 17:31:24 -04005484 case GL_UNPACK_ROW_LENGTH:
5485 case GL_UNPACK_IMAGE_HEIGHT:
5486 case GL_UNPACK_SKIP_IMAGES:
5487 case GL_UNPACK_SKIP_ROWS:
5488 case GL_UNPACK_SKIP_PIXELS:
5489 case GL_PACK_ROW_LENGTH:
5490 case GL_PACK_SKIP_ROWS:
5491 case GL_PACK_SKIP_PIXELS:
5492 break;
5493
5494 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005495 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005496 return false;
5497 }
5498
5499 return true;
5500}
5501
5502bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5503{
5504 return true;
5505}
5506
5507bool ValidateReleaseShaderCompiler(ValidationContext *context)
5508{
5509 return true;
5510}
5511
Jamie Madill876429b2017-04-20 15:46:24 -04005512bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005513{
5514 return true;
5515}
5516
5517bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5518{
5519 if (width < 0 || height < 0)
5520 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005521 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005522 return false;
5523 }
5524
5525 return true;
5526}
5527
5528bool ValidateShaderBinary(ValidationContext *context,
5529 GLsizei n,
5530 const GLuint *shaders,
5531 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005532 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005533 GLsizei length)
5534{
5535 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5536 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5537 shaderBinaryFormats.end())
5538 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005539 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005540 return false;
5541 }
5542
5543 return true;
5544}
5545
5546bool ValidateShaderSource(ValidationContext *context,
5547 GLuint shader,
5548 GLsizei count,
5549 const GLchar *const *string,
5550 const GLint *length)
5551{
5552 if (count < 0)
5553 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005554 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005555 return false;
5556 }
5557
Geoff Langfc32e8b2017-05-31 14:16:59 -04005558 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5559 // shader-related entry points
5560 if (context->getExtensions().webglCompatibility)
5561 {
5562 for (GLsizei i = 0; i < count; i++)
5563 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005564 size_t len =
5565 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005566
5567 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005568 if (!IsValidESSLShaderSourceString(string[i], len,
5569 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005570 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005571 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005572 return false;
5573 }
5574 }
5575 }
5576
Jamie Madillc1d770e2017-04-13 17:31:24 -04005577 Shader *shaderObject = GetValidShader(context, shader);
5578 if (!shaderObject)
5579 {
5580 return false;
5581 }
5582
5583 return true;
5584}
5585
5586bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5587{
5588 if (!IsValidStencilFunc(func))
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 true;
5595}
5596
5597bool ValidateStencilFuncSeparate(ValidationContext *context,
5598 GLenum face,
5599 GLenum func,
5600 GLint ref,
5601 GLuint mask)
5602{
5603 if (!IsValidStencilFace(face))
5604 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005605 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005606 return false;
5607 }
5608
5609 if (!IsValidStencilFunc(func))
5610 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005611 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005612 return false;
5613 }
5614
5615 return true;
5616}
5617
5618bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5619{
5620 return true;
5621}
5622
5623bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5624{
5625 if (!IsValidStencilFace(face))
5626 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005627 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005628 return false;
5629 }
5630
5631 return true;
5632}
5633
5634bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5635{
5636 if (!IsValidStencilOp(fail))
5637 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005638 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005639 return false;
5640 }
5641
5642 if (!IsValidStencilOp(zfail))
5643 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005644 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005645 return false;
5646 }
5647
5648 if (!IsValidStencilOp(zpass))
5649 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005650 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005651 return false;
5652 }
5653
5654 return true;
5655}
5656
5657bool ValidateStencilOpSeparate(ValidationContext *context,
5658 GLenum face,
5659 GLenum fail,
5660 GLenum zfail,
5661 GLenum zpass)
5662{
5663 if (!IsValidStencilFace(face))
5664 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005665 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005666 return false;
5667 }
5668
5669 return ValidateStencilOp(context, fail, zfail, zpass);
5670}
5671
5672bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5673{
5674 return ValidateUniform(context, GL_FLOAT, location, 1);
5675}
5676
5677bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5678{
5679 return ValidateUniform(context, GL_FLOAT, location, count);
5680}
5681
Jamie Madillbe849e42017-05-02 15:49:00 -04005682bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5683{
5684 return ValidateUniform1iv(context, location, 1, &x);
5685}
5686
Jamie Madillc1d770e2017-04-13 17:31:24 -04005687bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5688{
5689 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5690}
5691
5692bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5693{
5694 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5695}
5696
5697bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5698{
5699 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5700}
5701
5702bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5703{
5704 return ValidateUniform(context, GL_INT_VEC2, location, count);
5705}
5706
5707bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5708{
5709 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5710}
5711
5712bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5713{
5714 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5715}
5716
5717bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5718{
5719 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5720}
5721
5722bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5723{
5724 return ValidateUniform(context, GL_INT_VEC3, location, count);
5725}
5726
5727bool ValidateUniform4f(ValidationContext *context,
5728 GLint location,
5729 GLfloat x,
5730 GLfloat y,
5731 GLfloat z,
5732 GLfloat w)
5733{
5734 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5735}
5736
5737bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5738{
5739 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5740}
5741
5742bool ValidateUniform4i(ValidationContext *context,
5743 GLint location,
5744 GLint x,
5745 GLint y,
5746 GLint z,
5747 GLint w)
5748{
5749 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5750}
5751
5752bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5753{
5754 return ValidateUniform(context, GL_INT_VEC4, location, count);
5755}
5756
5757bool ValidateUniformMatrix2fv(ValidationContext *context,
5758 GLint location,
5759 GLsizei count,
5760 GLboolean transpose,
5761 const GLfloat *value)
5762{
5763 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5764}
5765
5766bool ValidateUniformMatrix3fv(ValidationContext *context,
5767 GLint location,
5768 GLsizei count,
5769 GLboolean transpose,
5770 const GLfloat *value)
5771{
5772 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5773}
5774
5775bool ValidateUniformMatrix4fv(ValidationContext *context,
5776 GLint location,
5777 GLsizei count,
5778 GLboolean transpose,
5779 const GLfloat *value)
5780{
5781 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5782}
5783
5784bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5785{
5786 Program *programObject = GetValidProgram(context, program);
5787
5788 if (!programObject)
5789 {
5790 return false;
5791 }
5792
5793 return true;
5794}
5795
Jamie Madillc1d770e2017-04-13 17:31:24 -04005796bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5797{
5798 return ValidateVertexAttribIndex(context, index);
5799}
5800
5801bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5802{
5803 return ValidateVertexAttribIndex(context, index);
5804}
5805
5806bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5807{
5808 return ValidateVertexAttribIndex(context, index);
5809}
5810
5811bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5812{
5813 return ValidateVertexAttribIndex(context, index);
5814}
5815
5816bool ValidateVertexAttrib3f(ValidationContext *context,
5817 GLuint index,
5818 GLfloat x,
5819 GLfloat y,
5820 GLfloat z)
5821{
5822 return ValidateVertexAttribIndex(context, index);
5823}
5824
5825bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5826{
5827 return ValidateVertexAttribIndex(context, index);
5828}
5829
5830bool ValidateVertexAttrib4f(ValidationContext *context,
5831 GLuint index,
5832 GLfloat x,
5833 GLfloat y,
5834 GLfloat z,
5835 GLfloat w)
5836{
5837 return ValidateVertexAttribIndex(context, index);
5838}
5839
5840bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5841{
5842 return ValidateVertexAttribIndex(context, index);
5843}
5844
5845bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5846{
5847 if (width < 0 || height < 0)
5848 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005849 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005850 return false;
5851 }
5852
5853 return true;
5854}
5855
5856bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5857{
5858 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5859}
5860
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005861bool ValidateDrawElements(ValidationContext *context,
5862 GLenum mode,
5863 GLsizei count,
5864 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005865 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005866{
5867 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5868}
5869
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005870bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005871 GLenum target,
5872 GLenum attachment,
5873 GLenum pname,
5874 GLint *params)
5875{
5876 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5877 nullptr);
5878}
5879
5880bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5881{
5882 return ValidateGetProgramivBase(context, program, pname, nullptr);
5883}
5884
5885bool ValidateCopyTexImage2D(ValidationContext *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005886 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005887 GLint level,
5888 GLenum internalformat,
5889 GLint x,
5890 GLint y,
5891 GLsizei width,
5892 GLsizei height,
5893 GLint border)
5894{
5895 if (context->getClientMajorVersion() < 3)
5896 {
5897 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5898 0, x, y, width, height, border);
5899 }
5900
5901 ASSERT(context->getClientMajorVersion() == 3);
5902 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5903 0, x, y, width, height, border);
5904}
5905
5906bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005907 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005908 GLint level,
5909 GLint xoffset,
5910 GLint yoffset,
5911 GLint x,
5912 GLint y,
5913 GLsizei width,
5914 GLsizei height)
5915{
5916 if (context->getClientMajorVersion() < 3)
5917 {
5918 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5919 yoffset, x, y, width, height, 0);
5920 }
5921
5922 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5923 yoffset, 0, x, y, width, height, 0);
5924}
5925
5926bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5927{
5928 return ValidateGenOrDelete(context, n);
5929}
5930
5931bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5932{
5933 return ValidateGenOrDelete(context, n);
5934}
5935
5936bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5937{
5938 return ValidateGenOrDelete(context, n);
5939}
5940
5941bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5942{
5943 return ValidateGenOrDelete(context, n);
5944}
5945
5946bool ValidateDisable(Context *context, GLenum cap)
5947{
5948 if (!ValidCap(context, cap, false))
5949 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005950 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005951 return false;
5952 }
5953
5954 return true;
5955}
5956
5957bool ValidateEnable(Context *context, GLenum cap)
5958{
5959 if (!ValidCap(context, cap, false))
5960 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005961 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005962 return false;
5963 }
5964
5965 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5966 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5967 {
5968 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005969 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005970
5971 // We also output an error message to the debugger window if tracing is active, so that
5972 // developers can see the error message.
5973 ERR() << errorMessage;
5974 return false;
5975 }
5976
5977 return true;
5978}
5979
5980bool ValidateFramebufferRenderbuffer(Context *context,
5981 GLenum target,
5982 GLenum attachment,
5983 GLenum renderbuffertarget,
5984 GLuint renderbuffer)
5985{
Geoff Lange8afa902017-09-27 15:00:43 -04005986 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005987 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005988 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5989 return false;
5990 }
5991
5992 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5993 {
5994 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005995 return false;
5996 }
5997
5998 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5999 renderbuffertarget, renderbuffer);
6000}
6001
6002bool ValidateFramebufferTexture2D(Context *context,
6003 GLenum target,
6004 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006005 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 GLuint texture,
6007 GLint level)
6008{
6009 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
6010 // extension
6011 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
6012 level != 0)
6013 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006014 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006015 return false;
6016 }
6017
6018 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6019 {
6020 return false;
6021 }
6022
6023 if (texture != 0)
6024 {
6025 gl::Texture *tex = context->getTexture(texture);
6026 ASSERT(tex);
6027
6028 const gl::Caps &caps = context->getCaps();
6029
6030 switch (textarget)
6031 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006032 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006033 {
6034 if (level > gl::log2(caps.max2DTextureSize))
6035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006036 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 return false;
6038 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006039 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006040 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006041 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 return false;
6043 }
6044 }
6045 break;
6046
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006047 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006048 {
6049 if (level != 0)
6050 {
6051 context->handleError(InvalidValue());
6052 return false;
6053 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006054 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006055 {
6056 context->handleError(InvalidOperation()
6057 << "Textarget must match the texture target type.");
6058 return false;
6059 }
6060 }
6061 break;
6062
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006063 case TextureTarget::CubeMapNegativeX:
6064 case TextureTarget::CubeMapNegativeY:
6065 case TextureTarget::CubeMapNegativeZ:
6066 case TextureTarget::CubeMapPositiveX:
6067 case TextureTarget::CubeMapPositiveY:
6068 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006069 {
6070 if (level > gl::log2(caps.maxCubeMapTextureSize))
6071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006072 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006073 return false;
6074 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006075 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006076 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006077 context->handleError(InvalidOperation()
6078 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006079 return false;
6080 }
6081 }
6082 break;
6083
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006084 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006085 {
6086 if (context->getClientVersion() < ES_3_1)
6087 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006088 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006089 return false;
6090 }
6091
6092 if (level != 0)
6093 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006094 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006095 return false;
6096 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006097 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006098 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006099 context->handleError(InvalidOperation()
6100 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006101 return false;
6102 }
6103 }
6104 break;
6105
6106 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006107 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006108 return false;
6109 }
6110
6111 const Format &format = tex->getFormat(textarget, level);
6112 if (format.info->compressed)
6113 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006114 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006115 return false;
6116 }
6117 }
6118
6119 return true;
6120}
6121
6122bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6123{
6124 return ValidateGenOrDelete(context, n);
6125}
6126
6127bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6128{
6129 return ValidateGenOrDelete(context, n);
6130}
6131
6132bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6133{
6134 return ValidateGenOrDelete(context, n);
6135}
6136
6137bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6138{
6139 return ValidateGenOrDelete(context, n);
6140}
6141
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006142bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006143{
6144 if (!ValidTextureTarget(context, target))
6145 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006146 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006147 return false;
6148 }
6149
6150 Texture *texture = context->getTargetTexture(target);
6151
6152 if (texture == nullptr)
6153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006155 return false;
6156 }
6157
6158 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6159
6160 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6161 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6162 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006164 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006165 return false;
6166 }
6167
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006168 TextureTarget baseTarget = (target == TextureType::CubeMap)
6169 ? TextureTarget::CubeMapPositiveX
6170 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006171 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6172 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6173 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006174 {
6175 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6176 return false;
6177 }
6178
Geoff Lang536eca12017-09-13 11:23:35 -04006179 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6180 bool formatUnsized = !format.sized;
6181 bool formatColorRenderableAndFilterable =
6182 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6183 format.renderSupport(context->getClientVersion(), context->getExtensions());
6184 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006185 {
Geoff Lang536eca12017-09-13 11:23:35 -04006186 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006187 return false;
6188 }
6189
Geoff Lang536eca12017-09-13 11:23:35 -04006190 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6191 // generation
6192 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6193 {
6194 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6195 return false;
6196 }
6197
6198 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6199 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006200 bool supportsSRGBMipmapGeneration =
6201 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006202 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006203 {
Geoff Lang536eca12017-09-13 11:23:35 -04006204 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006205 return false;
6206 }
6207
6208 // Non-power of 2 ES2 check
6209 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6210 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6211 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6212 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006213 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6214 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006215 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006216 return false;
6217 }
6218
6219 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006220 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006221 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006222 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006223 return false;
6224 }
6225
6226 return true;
6227}
6228
6229bool ValidateGetBufferParameteriv(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006230 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006231 GLenum pname,
6232 GLint *params)
6233{
6234 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6235}
6236
6237bool ValidateGetRenderbufferParameteriv(Context *context,
6238 GLenum target,
6239 GLenum pname,
6240 GLint *params)
6241{
6242 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6243}
6244
6245bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6246{
6247 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6248}
6249
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006250bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006251{
6252 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6253}
6254
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006255bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006256{
6257 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6258}
6259
6260bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6261{
6262 return ValidateGetUniformBase(context, program, location);
6263}
6264
6265bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6266{
6267 return ValidateGetUniformBase(context, program, location);
6268}
6269
6270bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6271{
6272 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6273}
6274
6275bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6276{
6277 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6278}
6279
6280bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6281{
6282 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6283}
6284
6285bool ValidateIsEnabled(Context *context, GLenum cap)
6286{
6287 if (!ValidCap(context, cap, true))
6288 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006289 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006290 return false;
6291 }
6292
6293 return true;
6294}
6295
6296bool ValidateLinkProgram(Context *context, GLuint program)
6297{
6298 if (context->hasActiveTransformFeedback(program))
6299 {
6300 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006301 context->handleError(InvalidOperation() << "Cannot link program while program is "
6302 "associated with an active transform "
6303 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006304 return false;
6305 }
6306
6307 Program *programObject = GetValidProgram(context, program);
6308 if (!programObject)
6309 {
6310 return false;
6311 }
6312
6313 return true;
6314}
6315
Jamie Madill4928b7c2017-06-20 12:57:39 -04006316bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006317 GLint x,
6318 GLint y,
6319 GLsizei width,
6320 GLsizei height,
6321 GLenum format,
6322 GLenum type,
6323 void *pixels)
6324{
6325 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6326 nullptr, pixels);
6327}
6328
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006329bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006330{
6331 return ValidateTexParameterBase(context, target, pname, -1, &param);
6332}
6333
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006334bool ValidateTexParameterfv(Context *context,
6335 TextureType target,
6336 GLenum pname,
6337 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006338{
6339 return ValidateTexParameterBase(context, target, pname, -1, params);
6340}
6341
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006342bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006343{
6344 return ValidateTexParameterBase(context, target, pname, -1, &param);
6345}
6346
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006347bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006348{
6349 return ValidateTexParameterBase(context, target, pname, -1, params);
6350}
6351
6352bool ValidateUseProgram(Context *context, GLuint program)
6353{
6354 if (program != 0)
6355 {
6356 Program *programObject = context->getProgram(program);
6357 if (!programObject)
6358 {
6359 // ES 3.1.0 section 7.3 page 72
6360 if (context->getShader(program))
6361 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006362 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006363 return false;
6364 }
6365 else
6366 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006367 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006368 return false;
6369 }
6370 }
6371 if (!programObject->isLinked())
6372 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006373 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006374 return false;
6375 }
6376 }
6377 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6378 {
6379 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006380 context
6381 ->handleError(InvalidOperation()
6382 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006383 return false;
6384 }
6385
6386 return true;
6387}
6388
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006389bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6390{
6391 if (!context->getExtensions().fence)
6392 {
6393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6394 return false;
6395 }
6396
6397 if (n < 0)
6398 {
6399 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6400 return false;
6401 }
6402
6403 return true;
6404}
6405
6406bool ValidateFinishFenceNV(Context *context, GLuint fence)
6407{
6408 if (!context->getExtensions().fence)
6409 {
6410 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6411 return false;
6412 }
6413
6414 FenceNV *fenceObject = context->getFenceNV(fence);
6415
6416 if (fenceObject == nullptr)
6417 {
6418 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6419 return false;
6420 }
6421
6422 if (!fenceObject->isSet())
6423 {
6424 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6425 return false;
6426 }
6427
6428 return true;
6429}
6430
6431bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6432{
6433 if (!context->getExtensions().fence)
6434 {
6435 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6436 return false;
6437 }
6438
6439 if (n < 0)
6440 {
6441 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6442 return false;
6443 }
6444
6445 return true;
6446}
6447
6448bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6449{
6450 if (!context->getExtensions().fence)
6451 {
6452 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6453 return false;
6454 }
6455
6456 FenceNV *fenceObject = context->getFenceNV(fence);
6457
6458 if (fenceObject == nullptr)
6459 {
6460 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6461 return false;
6462 }
6463
6464 if (!fenceObject->isSet())
6465 {
6466 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6467 return false;
6468 }
6469
6470 switch (pname)
6471 {
6472 case GL_FENCE_STATUS_NV:
6473 case GL_FENCE_CONDITION_NV:
6474 break;
6475
6476 default:
6477 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6478 return false;
6479 }
6480
6481 return true;
6482}
6483
6484bool ValidateGetGraphicsResetStatusEXT(Context *context)
6485{
6486 if (!context->getExtensions().robustness)
6487 {
6488 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6489 return false;
6490 }
6491
6492 return true;
6493}
6494
6495bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6496 GLuint shader,
6497 GLsizei bufsize,
6498 GLsizei *length,
6499 GLchar *source)
6500{
6501 if (!context->getExtensions().translatedShaderSource)
6502 {
6503 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6504 return false;
6505 }
6506
6507 if (bufsize < 0)
6508 {
6509 context->handleError(InvalidValue());
6510 return false;
6511 }
6512
6513 Shader *shaderObject = context->getShader(shader);
6514
6515 if (!shaderObject)
6516 {
6517 context->handleError(InvalidOperation());
6518 return false;
6519 }
6520
6521 return true;
6522}
6523
6524bool ValidateIsFenceNV(Context *context, GLuint fence)
6525{
6526 if (!context->getExtensions().fence)
6527 {
6528 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6529 return false;
6530 }
6531
6532 return true;
6533}
6534
Jamie Madill007530e2017-12-28 14:27:04 -05006535bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6536{
6537 if (!context->getExtensions().fence)
6538 {
6539 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6540 return false;
6541 }
6542
6543 if (condition != GL_ALL_COMPLETED_NV)
6544 {
6545 context->handleError(InvalidEnum());
6546 return false;
6547 }
6548
6549 FenceNV *fenceObject = context->getFenceNV(fence);
6550
6551 if (fenceObject == nullptr)
6552 {
6553 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6554 return false;
6555 }
6556
6557 return true;
6558}
6559
6560bool ValidateTestFenceNV(Context *context, GLuint fence)
6561{
6562 if (!context->getExtensions().fence)
6563 {
6564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6565 return false;
6566 }
6567
6568 FenceNV *fenceObject = context->getFenceNV(fence);
6569
6570 if (fenceObject == nullptr)
6571 {
6572 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6573 return false;
6574 }
6575
6576 if (fenceObject->isSet() != GL_TRUE)
6577 {
6578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6579 return false;
6580 }
6581
6582 return true;
6583}
6584
6585bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006586 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006587 GLsizei levels,
6588 GLenum internalformat,
6589 GLsizei width,
6590 GLsizei height)
6591{
6592 if (!context->getExtensions().textureStorage)
6593 {
6594 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6595 return false;
6596 }
6597
6598 if (context->getClientMajorVersion() < 3)
6599 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006600 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006601 height);
6602 }
6603
6604 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006605 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006606 1);
6607}
6608
6609bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6610{
6611 if (!context->getExtensions().instancedArrays)
6612 {
6613 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6614 return false;
6615 }
6616
6617 if (index >= MAX_VERTEX_ATTRIBS)
6618 {
6619 context->handleError(InvalidValue());
6620 return false;
6621 }
6622
6623 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6624 {
6625 if (index == 0 && divisor != 0)
6626 {
6627 const char *errorMessage =
6628 "The current context doesn't support setting a non-zero divisor on the "
6629 "attribute with index zero. "
6630 "Please reorder the attributes in your vertex shader so that attribute zero "
6631 "can have a zero divisor.";
6632 context->handleError(InvalidOperation() << errorMessage);
6633
6634 // We also output an error message to the debugger window if tracing is active, so
6635 // that developers can see the error message.
6636 ERR() << errorMessage;
6637 return false;
6638 }
6639 }
6640
6641 return true;
6642}
6643
6644bool ValidateTexImage3DOES(Context *context,
6645 GLenum target,
6646 GLint level,
6647 GLenum internalformat,
6648 GLsizei width,
6649 GLsizei height,
6650 GLsizei depth,
6651 GLint border,
6652 GLenum format,
6653 GLenum type,
6654 const void *pixels)
6655{
6656 UNIMPLEMENTED(); // FIXME
6657 return false;
6658}
6659
6660bool ValidatePopGroupMarkerEXT(Context *context)
6661{
6662 if (!context->getExtensions().debugMarker)
6663 {
6664 // The debug marker calls should not set error state
6665 // However, it seems reasonable to set an error state if the extension is not enabled
6666 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6667 return false;
6668 }
6669
6670 return true;
6671}
6672
Jamie Madillfa920eb2018-01-04 11:45:50 -05006673bool ValidateTexStorage1DEXT(Context *context,
6674 GLenum target,
6675 GLsizei levels,
6676 GLenum internalformat,
6677 GLsizei width)
6678{
6679 UNIMPLEMENTED();
6680 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6681 return false;
6682}
6683
6684bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006685 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006686 GLsizei levels,
6687 GLenum internalformat,
6688 GLsizei width,
6689 GLsizei height,
6690 GLsizei depth)
6691{
6692 if (!context->getExtensions().textureStorage)
6693 {
6694 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6695 return false;
6696 }
6697
6698 if (context->getClientMajorVersion() < 3)
6699 {
6700 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6701 return false;
6702 }
6703
6704 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6705 depth);
6706}
6707
Jamie Madillc29968b2016-01-20 11:17:23 -05006708} // namespace gl