blob: 3d3c593ba2edc5bfc4fd19e68c12fcc80777c1d6 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
78 if (context->hasPath(pathName) && !context->hasPathData(pathName))
79 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madill5b772312018-03-08 20:28:32 -0500458bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700795 // GLES1 emulation: GLES1-specific caps
796 case GL_ALPHA_TEST:
797 return context->getClientVersion() < Version(2, 0);
798
Jamie Madillbe849e42017-05-02 15:49:00 -0400799 default:
800 return false;
801 }
802}
803
Geoff Langfc32e8b2017-05-31 14:16:59 -0400804// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
805// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400806bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400807{
808 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400809 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
810 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400811 {
812 return true;
813 }
814
815 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
816 if (c >= 9 && c <= 13)
817 {
818 return true;
819 }
820
821 return false;
822}
823
Geoff Langcab92ee2017-07-19 17:32:07 -0400824bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400825{
Geoff Langa71a98e2017-06-19 15:15:00 -0400826 for (size_t i = 0; i < len; i++)
827 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400828 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400829 {
830 return false;
831 }
832 }
833
834 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400835}
836
Geoff Langcab92ee2017-07-19 17:32:07 -0400837bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
838{
839 enum class ParseState
840 {
841 // Have not seen an ASCII non-whitespace character yet on
842 // this line. Possible that we might see a preprocessor
843 // directive.
844 BEGINING_OF_LINE,
845
846 // Have seen at least one ASCII non-whitespace character
847 // on this line.
848 MIDDLE_OF_LINE,
849
850 // Handling a preprocessor directive. Passes through all
851 // characters up to the end of the line. Disables comment
852 // processing.
853 IN_PREPROCESSOR_DIRECTIVE,
854
855 // Handling a single-line comment. The comment text is
856 // replaced with a single space.
857 IN_SINGLE_LINE_COMMENT,
858
859 // Handling a multi-line comment. Newlines are passed
860 // through to preserve line numbers.
861 IN_MULTI_LINE_COMMENT
862 };
863
864 ParseState state = ParseState::BEGINING_OF_LINE;
865 size_t pos = 0;
866
867 while (pos < len)
868 {
869 char c = str[pos];
870 char next = pos + 1 < len ? str[pos + 1] : 0;
871
872 // Check for newlines
873 if (c == '\n' || c == '\r')
874 {
875 if (state != ParseState::IN_MULTI_LINE_COMMENT)
876 {
877 state = ParseState::BEGINING_OF_LINE;
878 }
879
880 pos++;
881 continue;
882 }
883
884 switch (state)
885 {
886 case ParseState::BEGINING_OF_LINE:
887 if (c == ' ')
888 {
889 // Maintain the BEGINING_OF_LINE state until a non-space is seen
890 pos++;
891 }
892 else if (c == '#')
893 {
894 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
895 pos++;
896 }
897 else
898 {
899 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
900 state = ParseState::MIDDLE_OF_LINE;
901 }
902 break;
903
904 case ParseState::MIDDLE_OF_LINE:
905 if (c == '/' && next == '/')
906 {
907 state = ParseState::IN_SINGLE_LINE_COMMENT;
908 pos++;
909 }
910 else if (c == '/' && next == '*')
911 {
912 state = ParseState::IN_MULTI_LINE_COMMENT;
913 pos++;
914 }
915 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
916 {
917 // Skip line continuation characters
918 }
919 else if (!IsValidESSLCharacter(c))
920 {
921 return false;
922 }
923 pos++;
924 break;
925
926 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700927 // Line-continuation characters may not be permitted.
928 // Otherwise, just pass it through. Do not parse comments in this state.
929 if (!lineContinuationAllowed && c == '\\')
930 {
931 return false;
932 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400933 pos++;
934 break;
935
936 case ParseState::IN_SINGLE_LINE_COMMENT:
937 // Line-continuation characters are processed before comment processing.
938 // Advance string if a new line character is immediately behind
939 // line-continuation character.
940 if (c == '\\' && (next == '\n' || next == '\r'))
941 {
942 pos++;
943 }
944 pos++;
945 break;
946
947 case ParseState::IN_MULTI_LINE_COMMENT:
948 if (c == '*' && next == '/')
949 {
950 state = ParseState::MIDDLE_OF_LINE;
951 pos++;
952 }
953 pos++;
954 break;
955 }
956 }
957
958 return true;
959}
960
Jamie Madill5b772312018-03-08 20:28:32 -0500961bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700962{
963 ASSERT(context->isWebGL());
964
965 // WebGL 1.0 [Section 6.16] GLSL Constructs
966 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
967 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
968 {
969 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
970 return false;
971 }
972
973 return true;
974}
975
Jamie Madill5b772312018-03-08 20:28:32 -0500976bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700977{
978 ASSERT(context->isWebGL());
979
980 if (context->isWebGL1() && length > 256)
981 {
982 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
983 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
984 // locations.
985 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
986
987 return false;
988 }
989 else if (length > 1024)
990 {
991 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
992 // uniform and attribute locations.
993 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
994 return false;
995 }
996
997 return true;
998}
999
Jamie Madill007530e2017-12-28 14:27:04 -05001000bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1001{
1002 if (!context->getExtensions().pathRendering)
1003 {
1004 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1005 return false;
1006 }
1007
1008 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1009 {
1010 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1011 return false;
1012 }
1013 return true;
1014}
Jamie Madillc29968b2016-01-20 11:17:23 -05001015} // anonymous namespace
1016
Geoff Langff5b2d52016-09-07 11:32:23 -04001017bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001018 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001019 GLint level,
1020 GLenum internalformat,
1021 bool isCompressed,
1022 bool isSubImage,
1023 GLint xoffset,
1024 GLint yoffset,
1025 GLsizei width,
1026 GLsizei height,
1027 GLint border,
1028 GLenum format,
1029 GLenum type,
1030 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001031 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001032{
Jamie Madill6f38f822014-06-06 17:12:20 -04001033 if (!ValidTexture2DDestinationTarget(context, target))
1034 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001035 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001036 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001037 }
1038
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001039 TextureType texType = TextureTargetToType(target);
1040 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001042 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001043 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001044 }
1045
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001046 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001047 {
1048 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1049 return false;
1050 }
1051
1052 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001053 std::numeric_limits<GLsizei>::max() - yoffset < height)
1054 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001055 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001056 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001057 }
1058
Geoff Lang6e898aa2017-06-02 11:17:26 -04001059 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1060 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1061 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1062 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1063 // case.
1064 bool nonEqualFormatsAllowed =
1065 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1066 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1067
1068 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001069 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001070 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001071 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001072 }
1073
Geoff Langaae65a42014-05-26 12:43:44 -04001074 const gl::Caps &caps = context->getCaps();
1075
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001076 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001077 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001078 case TextureType::_2D:
1079 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1080 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1081 {
1082 context->handleError(InvalidValue());
1083 return false;
1084 }
1085 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001086
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001087 case TextureType::Rectangle:
1088 ASSERT(level == 0);
1089 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1090 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1091 {
1092 context->handleError(InvalidValue());
1093 return false;
1094 }
1095 if (isCompressed)
1096 {
1097 context->handleError(InvalidEnum()
1098 << "Rectangle texture cannot have a compressed format.");
1099 return false;
1100 }
1101 break;
1102
1103 case TextureType::CubeMap:
1104 if (!isSubImage && width != height)
1105 {
1106 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1107 return false;
1108 }
1109
1110 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1111 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1112 {
1113 context->handleError(InvalidValue());
1114 return false;
1115 }
1116 break;
1117
1118 default:
1119 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001120 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001121 }
1122
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001123 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001124 if (!texture)
1125 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001126 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001127 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001128 }
1129
Geoff Langa9be0dc2014-12-17 12:34:40 -05001130 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001131 {
Geoff Langca271392017-04-05 12:30:00 -04001132 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1133 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001135 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001136 return false;
1137 }
1138
Geoff Langa9be0dc2014-12-17 12:34:40 -05001139 if (format != GL_NONE)
1140 {
Geoff Langca271392017-04-05 12:30:00 -04001141 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1142 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001143 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001145 return false;
1146 }
1147 }
1148
1149 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1150 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1151 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001152 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001153 return false;
1154 }
Geoff Langfb052642017-10-24 13:42:09 -04001155
1156 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001157 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001158 {
1159 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1160 return false;
1161 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001162 }
1163 else
1164 {
Geoff Lang69cce582015-09-17 13:20:36 -04001165 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001166 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001167 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001168 return false;
1169 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001170 }
1171
1172 // Verify zero border
1173 if (border != 0)
1174 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001175 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001176 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001177 }
1178
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001179 if (isCompressed)
1180 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001181 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001182 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1183 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184 switch (actualInternalFormat)
1185 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001186 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1187 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1188 if (!context->getExtensions().textureCompressionDXT1)
1189 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001190 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001191 return false;
1192 }
1193 break;
1194 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001195 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001196 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001197 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001198 return false;
1199 }
1200 break;
1201 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1202 if (!context->getExtensions().textureCompressionDXT5)
1203 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001204 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001205 return false;
1206 }
1207 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001208 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1209 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1210 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1211 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1212 if (!context->getExtensions().textureCompressionS3TCsRGB)
1213 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001214 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001215 return false;
1216 }
1217 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001218 case GL_ETC1_RGB8_OES:
1219 if (!context->getExtensions().compressedETC1RGB8Texture)
1220 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001221 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001222 return false;
1223 }
Geoff Lang86f81162017-10-30 15:10:45 -04001224 if (isSubImage)
1225 {
1226 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1227 return false;
1228 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001229 break;
1230 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001231 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1232 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1233 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1234 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001235 if (!context->getExtensions().lossyETCDecode)
1236 {
Geoff Lang86f81162017-10-30 15:10:45 -04001237 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001238 return false;
1239 }
1240 break;
1241 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001242 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001243 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001244 }
Geoff Lang966c9402017-04-18 12:38:27 -04001245
1246 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001247 {
Geoff Lang966c9402017-04-18 12:38:27 -04001248 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1249 height, texture->getWidth(target, level),
1250 texture->getHeight(target, level)))
1251 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001252 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001253 return false;
1254 }
1255
1256 if (format != actualInternalFormat)
1257 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001258 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001259 return false;
1260 }
1261 }
1262 else
1263 {
1264 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1265 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001266 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001267 return false;
1268 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001269 }
1270 }
1271 else
1272 {
1273 // validate <type> by itself (used as secondary key below)
1274 switch (type)
1275 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001276 case GL_UNSIGNED_BYTE:
1277 case GL_UNSIGNED_SHORT_5_6_5:
1278 case GL_UNSIGNED_SHORT_4_4_4_4:
1279 case GL_UNSIGNED_SHORT_5_5_5_1:
1280 case GL_UNSIGNED_SHORT:
1281 case GL_UNSIGNED_INT:
1282 case GL_UNSIGNED_INT_24_8_OES:
1283 case GL_HALF_FLOAT_OES:
1284 case GL_FLOAT:
1285 break;
1286 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001287 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001288 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001289 }
1290
1291 // validate <format> + <type> combinations
1292 // - invalid <format> -> sets INVALID_ENUM
1293 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1294 switch (format)
1295 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001296 case GL_ALPHA:
1297 case GL_LUMINANCE:
1298 case GL_LUMINANCE_ALPHA:
1299 switch (type)
1300 {
1301 case GL_UNSIGNED_BYTE:
1302 case GL_FLOAT:
1303 case GL_HALF_FLOAT_OES:
1304 break;
1305 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001306 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001307 return false;
1308 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001309 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001310 case GL_RED:
1311 case GL_RG:
1312 if (!context->getExtensions().textureRG)
1313 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001314 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001315 return false;
1316 }
1317 switch (type)
1318 {
1319 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001320 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001321 case GL_FLOAT:
1322 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001323 if (!context->getExtensions().textureFloat)
1324 {
1325 context->handleError(InvalidEnum());
1326 return false;
1327 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001328 break;
1329 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001330 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001331 return false;
1332 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001333 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001334 case GL_RGB:
1335 switch (type)
1336 {
1337 case GL_UNSIGNED_BYTE:
1338 case GL_UNSIGNED_SHORT_5_6_5:
1339 case GL_FLOAT:
1340 case GL_HALF_FLOAT_OES:
1341 break;
1342 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001343 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001344 return false;
1345 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001346 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001347 case GL_RGBA:
1348 switch (type)
1349 {
1350 case GL_UNSIGNED_BYTE:
1351 case GL_UNSIGNED_SHORT_4_4_4_4:
1352 case GL_UNSIGNED_SHORT_5_5_5_1:
1353 case GL_FLOAT:
1354 case GL_HALF_FLOAT_OES:
1355 break;
1356 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001358 return false;
1359 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001360 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001361 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001362 if (!context->getExtensions().textureFormatBGRA8888)
1363 {
1364 context->handleError(InvalidEnum());
1365 return false;
1366 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001367 switch (type)
1368 {
1369 case GL_UNSIGNED_BYTE:
1370 break;
1371 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001372 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001373 return false;
1374 }
1375 break;
1376 case GL_SRGB_EXT:
1377 case GL_SRGB_ALPHA_EXT:
1378 if (!context->getExtensions().sRGB)
1379 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001380 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001381 return false;
1382 }
1383 switch (type)
1384 {
1385 case GL_UNSIGNED_BYTE:
1386 break;
1387 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001389 return false;
1390 }
1391 break;
1392 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1393 // handled below
1394 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1395 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1396 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1397 break;
1398 case GL_DEPTH_COMPONENT:
1399 switch (type)
1400 {
1401 case GL_UNSIGNED_SHORT:
1402 case GL_UNSIGNED_INT:
1403 break;
1404 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001405 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001406 return false;
1407 }
1408 break;
1409 case GL_DEPTH_STENCIL_OES:
1410 switch (type)
1411 {
1412 case GL_UNSIGNED_INT_24_8_OES:
1413 break;
1414 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001415 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001416 return false;
1417 }
1418 break;
1419 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001420 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001421 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001422 }
1423
1424 switch (format)
1425 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001426 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1427 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1428 if (context->getExtensions().textureCompressionDXT1)
1429 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001430 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001431 return false;
1432 }
1433 else
1434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001435 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001436 return false;
1437 }
1438 break;
1439 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1440 if (context->getExtensions().textureCompressionDXT3)
1441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001442 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 else
1446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001447 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001448 return false;
1449 }
1450 break;
1451 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1452 if (context->getExtensions().textureCompressionDXT5)
1453 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001454 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001455 return false;
1456 }
1457 else
1458 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001459 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001460 return false;
1461 }
1462 break;
1463 case GL_ETC1_RGB8_OES:
1464 if (context->getExtensions().compressedETC1RGB8Texture)
1465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001466 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 return false;
1468 }
1469 else
1470 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001471 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001472 return false;
1473 }
1474 break;
1475 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001476 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1477 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1478 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1479 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001480 if (context->getExtensions().lossyETCDecode)
1481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001482 context->handleError(InvalidOperation()
1483 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001484 return false;
1485 }
1486 else
1487 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001488 context->handleError(InvalidEnum()
1489 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001490 return false;
1491 }
1492 break;
1493 case GL_DEPTH_COMPONENT:
1494 case GL_DEPTH_STENCIL_OES:
1495 if (!context->getExtensions().depthTextures)
1496 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001497 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001498 return false;
1499 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001500 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001501 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001502 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001503 return false;
1504 }
1505 // OES_depth_texture supports loading depth data and multiple levels,
1506 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001507 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001508 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001509 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1510 return false;
1511 }
1512 if (level != 0)
1513 {
1514 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001515 return false;
1516 }
1517 break;
1518 default:
1519 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001520 }
1521
Geoff Lang6e898aa2017-06-02 11:17:26 -04001522 if (!isSubImage)
1523 {
1524 switch (internalformat)
1525 {
1526 case GL_RGBA32F:
1527 if (!context->getExtensions().colorBufferFloatRGBA)
1528 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001529 context->handleError(InvalidValue()
1530 << "Sized GL_RGBA32F internal format requires "
1531 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001532 return false;
1533 }
1534 if (type != GL_FLOAT)
1535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001536 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001537 return false;
1538 }
1539 if (format != GL_RGBA)
1540 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001541 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001542 return false;
1543 }
1544 break;
1545
1546 case GL_RGB32F:
1547 if (!context->getExtensions().colorBufferFloatRGB)
1548 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001549 context->handleError(InvalidValue()
1550 << "Sized GL_RGB32F internal format requires "
1551 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001552 return false;
1553 }
1554 if (type != GL_FLOAT)
1555 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001556 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001557 return false;
1558 }
1559 if (format != GL_RGB)
1560 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001561 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001562 return false;
1563 }
1564 break;
1565
1566 default:
1567 break;
1568 }
1569 }
1570
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001571 if (type == GL_FLOAT)
1572 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001573 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001574 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001575 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001576 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001577 }
1578 }
1579 else if (type == GL_HALF_FLOAT_OES)
1580 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001581 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001582 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001583 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001584 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001585 }
1586 }
1587 }
1588
Geoff Langdbcced82017-06-06 15:55:54 -04001589 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001590 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001591 imageSize))
1592 {
1593 return false;
1594 }
1595
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001596 return true;
1597}
1598
He Yunchaoced53ae2016-11-29 15:00:51 +08001599bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001600 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001601 GLsizei levels,
1602 GLenum internalformat,
1603 GLsizei width,
1604 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001605{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001606 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1607 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001608 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001609 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001610 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001611 }
1612
1613 if (width < 1 || height < 1 || levels < 1)
1614 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001615 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001616 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001617 }
1618
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001619 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001620 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001621 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001622 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001623 }
1624
1625 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1626 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001627 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001628 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001629 }
1630
Geoff Langca271392017-04-05 12:30:00 -04001631 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001632 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001634 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001635 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 }
1637
Geoff Langaae65a42014-05-26 12:43:44 -04001638 const gl::Caps &caps = context->getCaps();
1639
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001640 switch (target)
1641 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001642 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001643 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1644 static_cast<GLuint>(height) > caps.max2DTextureSize)
1645 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001646 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001647 return false;
1648 }
1649 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001650 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001651 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1652 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1653 {
1654 context->handleError(InvalidValue());
1655 return false;
1656 }
1657 if (formatInfo.compressed)
1658 {
1659 context->handleError(InvalidEnum()
1660 << "Rectangle texture cannot have a compressed format.");
1661 return false;
1662 }
1663 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001664 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001665 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1666 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1667 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001668 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001669 return false;
1670 }
1671 break;
1672 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001673 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001674 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001675 }
1676
Geoff Langc0b9ef42014-07-02 10:02:37 -04001677 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001678 {
1679 if (!gl::isPow2(width) || !gl::isPow2(height))
1680 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001681 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001682 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001683 }
1684 }
1685
1686 switch (internalformat)
1687 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001688 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1689 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1690 if (!context->getExtensions().textureCompressionDXT1)
1691 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001692 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001693 return false;
1694 }
1695 break;
1696 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1697 if (!context->getExtensions().textureCompressionDXT3)
1698 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001699 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001700 return false;
1701 }
1702 break;
1703 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1704 if (!context->getExtensions().textureCompressionDXT5)
1705 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001706 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001707 return false;
1708 }
1709 break;
1710 case GL_ETC1_RGB8_OES:
1711 if (!context->getExtensions().compressedETC1RGB8Texture)
1712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001713 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001714 return false;
1715 }
1716 break;
1717 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001718 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1719 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1720 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1721 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001722 if (!context->getExtensions().lossyETCDecode)
1723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001724 context->handleError(InvalidEnum()
1725 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001726 return false;
1727 }
1728 break;
1729 case GL_RGBA32F_EXT:
1730 case GL_RGB32F_EXT:
1731 case GL_ALPHA32F_EXT:
1732 case GL_LUMINANCE32F_EXT:
1733 case GL_LUMINANCE_ALPHA32F_EXT:
1734 if (!context->getExtensions().textureFloat)
1735 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001736 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001737 return false;
1738 }
1739 break;
1740 case GL_RGBA16F_EXT:
1741 case GL_RGB16F_EXT:
1742 case GL_ALPHA16F_EXT:
1743 case GL_LUMINANCE16F_EXT:
1744 case GL_LUMINANCE_ALPHA16F_EXT:
1745 if (!context->getExtensions().textureHalfFloat)
1746 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001747 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001748 return false;
1749 }
1750 break;
1751 case GL_R8_EXT:
1752 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001753 if (!context->getExtensions().textureRG)
1754 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001755 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001756 return false;
1757 }
1758 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001759 case GL_R16F_EXT:
1760 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001761 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1762 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001763 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001764 return false;
1765 }
1766 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001767 case GL_R32F_EXT:
1768 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001769 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001770 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001771 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001772 return false;
1773 }
1774 break;
1775 case GL_DEPTH_COMPONENT16:
1776 case GL_DEPTH_COMPONENT32_OES:
1777 case GL_DEPTH24_STENCIL8_OES:
1778 if (!context->getExtensions().depthTextures)
1779 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001780 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001781 return false;
1782 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001783 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001785 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001786 return false;
1787 }
1788 // ANGLE_depth_texture only supports 1-level textures
1789 if (levels != 1)
1790 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001791 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001792 return false;
1793 }
1794 break;
1795 default:
1796 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001797 }
1798
Geoff Lang691e58c2014-12-19 17:03:25 -05001799 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001800 if (!texture || texture->id() == 0)
1801 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001802 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001803 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001804 }
1805
Geoff Lang69cce582015-09-17 13:20:36 -04001806 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001807 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001808 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001809 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001810 }
1811
1812 return true;
1813}
1814
He Yunchaoced53ae2016-11-29 15:00:51 +08001815bool ValidateDiscardFramebufferEXT(Context *context,
1816 GLenum target,
1817 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001818 const GLenum *attachments)
1819{
Jamie Madillc29968b2016-01-20 11:17:23 -05001820 if (!context->getExtensions().discardFramebuffer)
1821 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001822 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001823 return false;
1824 }
1825
Austin Kinross08332632015-05-05 13:35:47 -07001826 bool defaultFramebuffer = false;
1827
1828 switch (target)
1829 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001830 case GL_FRAMEBUFFER:
1831 defaultFramebuffer =
1832 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1833 break;
1834 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001835 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001836 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001837 }
1838
He Yunchaoced53ae2016-11-29 15:00:51 +08001839 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1840 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001841}
1842
Austin Kinrossbc781f32015-10-26 09:27:38 -07001843bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1844{
1845 if (!context->getExtensions().vertexArrayObject)
1846 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001847 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001848 return false;
1849 }
1850
1851 return ValidateBindVertexArrayBase(context, array);
1852}
1853
Jamie Madilld7576732017-08-26 18:49:50 -04001854bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001855{
1856 if (!context->getExtensions().vertexArrayObject)
1857 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001858 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001859 return false;
1860 }
1861
Olli Etuaho41997e72016-03-10 13:38:39 +02001862 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001863}
1864
Jamie Madilld7576732017-08-26 18:49:50 -04001865bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001866{
1867 if (!context->getExtensions().vertexArrayObject)
1868 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001869 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870 return false;
1871 }
1872
Olli Etuaho41997e72016-03-10 13:38:39 +02001873 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001874}
1875
Jamie Madilld7576732017-08-26 18:49:50 -04001876bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001877{
1878 if (!context->getExtensions().vertexArrayObject)
1879 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001880 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001881 return false;
1882 }
1883
1884 return true;
1885}
Geoff Langc5629752015-12-07 16:29:04 -05001886
1887bool ValidateProgramBinaryOES(Context *context,
1888 GLuint program,
1889 GLenum binaryFormat,
1890 const void *binary,
1891 GLint length)
1892{
1893 if (!context->getExtensions().getProgramBinary)
1894 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001895 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001896 return false;
1897 }
1898
1899 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1900}
1901
1902bool ValidateGetProgramBinaryOES(Context *context,
1903 GLuint program,
1904 GLsizei bufSize,
1905 GLsizei *length,
1906 GLenum *binaryFormat,
1907 void *binary)
1908{
1909 if (!context->getExtensions().getProgramBinary)
1910 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001911 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001912 return false;
1913 }
1914
1915 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1916}
Geoff Lange102fee2015-12-10 11:23:30 -05001917
Geoff Lang70d0f492015-12-10 17:45:46 -05001918static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1919{
1920 switch (source)
1921 {
1922 case GL_DEBUG_SOURCE_API:
1923 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1924 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1925 case GL_DEBUG_SOURCE_OTHER:
1926 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1927 return !mustBeThirdPartyOrApplication;
1928
1929 case GL_DEBUG_SOURCE_THIRD_PARTY:
1930 case GL_DEBUG_SOURCE_APPLICATION:
1931 return true;
1932
1933 default:
1934 return false;
1935 }
1936}
1937
1938static bool ValidDebugType(GLenum type)
1939{
1940 switch (type)
1941 {
1942 case GL_DEBUG_TYPE_ERROR:
1943 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1944 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1945 case GL_DEBUG_TYPE_PERFORMANCE:
1946 case GL_DEBUG_TYPE_PORTABILITY:
1947 case GL_DEBUG_TYPE_OTHER:
1948 case GL_DEBUG_TYPE_MARKER:
1949 case GL_DEBUG_TYPE_PUSH_GROUP:
1950 case GL_DEBUG_TYPE_POP_GROUP:
1951 return true;
1952
1953 default:
1954 return false;
1955 }
1956}
1957
1958static bool ValidDebugSeverity(GLenum severity)
1959{
1960 switch (severity)
1961 {
1962 case GL_DEBUG_SEVERITY_HIGH:
1963 case GL_DEBUG_SEVERITY_MEDIUM:
1964 case GL_DEBUG_SEVERITY_LOW:
1965 case GL_DEBUG_SEVERITY_NOTIFICATION:
1966 return true;
1967
1968 default:
1969 return false;
1970 }
1971}
1972
Geoff Lange102fee2015-12-10 11:23:30 -05001973bool ValidateDebugMessageControlKHR(Context *context,
1974 GLenum source,
1975 GLenum type,
1976 GLenum severity,
1977 GLsizei count,
1978 const GLuint *ids,
1979 GLboolean enabled)
1980{
1981 if (!context->getExtensions().debug)
1982 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001983 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001984 return false;
1985 }
1986
Geoff Lang70d0f492015-12-10 17:45:46 -05001987 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1988 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001989 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001990 return false;
1991 }
1992
1993 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1994 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001995 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001996 return false;
1997 }
1998
1999 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2000 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002001 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002002 return false;
2003 }
2004
2005 if (count > 0)
2006 {
2007 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2008 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002009 context->handleError(
2010 InvalidOperation()
2011 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002012 return false;
2013 }
2014
2015 if (severity != GL_DONT_CARE)
2016 {
Jamie Madill437fa652016-05-03 15:13:24 -04002017 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002018 InvalidOperation()
2019 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002020 return false;
2021 }
2022 }
2023
Geoff Lange102fee2015-12-10 11:23:30 -05002024 return true;
2025}
2026
2027bool ValidateDebugMessageInsertKHR(Context *context,
2028 GLenum source,
2029 GLenum type,
2030 GLuint id,
2031 GLenum severity,
2032 GLsizei length,
2033 const GLchar *buf)
2034{
2035 if (!context->getExtensions().debug)
2036 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002037 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002038 return false;
2039 }
2040
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002041 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002042 {
2043 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2044 // not generate an error.
2045 return false;
2046 }
2047
2048 if (!ValidDebugSeverity(severity))
2049 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002051 return false;
2052 }
2053
2054 if (!ValidDebugType(type))
2055 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002056 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002057 return false;
2058 }
2059
2060 if (!ValidDebugSource(source, true))
2061 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002062 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002063 return false;
2064 }
2065
2066 size_t messageLength = (length < 0) ? strlen(buf) : length;
2067 if (messageLength > context->getExtensions().maxDebugMessageLength)
2068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002069 context->handleError(InvalidValue()
2070 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002071 return false;
2072 }
2073
Geoff Lange102fee2015-12-10 11:23:30 -05002074 return true;
2075}
2076
2077bool ValidateDebugMessageCallbackKHR(Context *context,
2078 GLDEBUGPROCKHR callback,
2079 const void *userParam)
2080{
2081 if (!context->getExtensions().debug)
2082 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002083 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002084 return false;
2085 }
2086
Geoff Lange102fee2015-12-10 11:23:30 -05002087 return true;
2088}
2089
2090bool ValidateGetDebugMessageLogKHR(Context *context,
2091 GLuint count,
2092 GLsizei bufSize,
2093 GLenum *sources,
2094 GLenum *types,
2095 GLuint *ids,
2096 GLenum *severities,
2097 GLsizei *lengths,
2098 GLchar *messageLog)
2099{
2100 if (!context->getExtensions().debug)
2101 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002102 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002103 return false;
2104 }
2105
Geoff Lang70d0f492015-12-10 17:45:46 -05002106 if (bufSize < 0 && messageLog != nullptr)
2107 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002108 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002109 return false;
2110 }
2111
Geoff Lange102fee2015-12-10 11:23:30 -05002112 return true;
2113}
2114
2115bool ValidatePushDebugGroupKHR(Context *context,
2116 GLenum source,
2117 GLuint id,
2118 GLsizei length,
2119 const GLchar *message)
2120{
2121 if (!context->getExtensions().debug)
2122 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002123 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002124 return false;
2125 }
2126
Geoff Lang70d0f492015-12-10 17:45:46 -05002127 if (!ValidDebugSource(source, true))
2128 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002129 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002130 return false;
2131 }
2132
2133 size_t messageLength = (length < 0) ? strlen(message) : length;
2134 if (messageLength > context->getExtensions().maxDebugMessageLength)
2135 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002136 context->handleError(InvalidValue()
2137 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002138 return false;
2139 }
2140
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002141 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002142 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2143 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002144 context
2145 ->handleError(StackOverflow()
2146 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002147 return false;
2148 }
2149
Geoff Lange102fee2015-12-10 11:23:30 -05002150 return true;
2151}
2152
2153bool ValidatePopDebugGroupKHR(Context *context)
2154{
2155 if (!context->getExtensions().debug)
2156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002158 return false;
2159 }
2160
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002161 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002162 if (currentStackSize <= 1)
2163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002164 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002165 return false;
2166 }
2167
2168 return true;
2169}
2170
2171static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2172{
2173 switch (identifier)
2174 {
2175 case GL_BUFFER:
2176 if (context->getBuffer(name) == nullptr)
2177 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002178 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002179 return false;
2180 }
2181 return true;
2182
2183 case GL_SHADER:
2184 if (context->getShader(name) == nullptr)
2185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002186 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002187 return false;
2188 }
2189 return true;
2190
2191 case GL_PROGRAM:
2192 if (context->getProgram(name) == nullptr)
2193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002194 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002195 return false;
2196 }
2197 return true;
2198
2199 case GL_VERTEX_ARRAY:
2200 if (context->getVertexArray(name) == nullptr)
2201 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002202 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002203 return false;
2204 }
2205 return true;
2206
2207 case GL_QUERY:
2208 if (context->getQuery(name) == nullptr)
2209 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002210 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002211 return false;
2212 }
2213 return true;
2214
2215 case GL_TRANSFORM_FEEDBACK:
2216 if (context->getTransformFeedback(name) == nullptr)
2217 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002218 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002219 return false;
2220 }
2221 return true;
2222
2223 case GL_SAMPLER:
2224 if (context->getSampler(name) == nullptr)
2225 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002226 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002227 return false;
2228 }
2229 return true;
2230
2231 case GL_TEXTURE:
2232 if (context->getTexture(name) == nullptr)
2233 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002234 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002235 return false;
2236 }
2237 return true;
2238
2239 case GL_RENDERBUFFER:
2240 if (context->getRenderbuffer(name) == nullptr)
2241 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002242 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002243 return false;
2244 }
2245 return true;
2246
2247 case GL_FRAMEBUFFER:
2248 if (context->getFramebuffer(name) == nullptr)
2249 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002250 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002251 return false;
2252 }
2253 return true;
2254
2255 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002256 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002257 return false;
2258 }
Geoff Lange102fee2015-12-10 11:23:30 -05002259}
2260
Martin Radev9d901792016-07-15 15:58:58 +03002261static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2262{
2263 size_t labelLength = 0;
2264
2265 if (length < 0)
2266 {
2267 if (label != nullptr)
2268 {
2269 labelLength = strlen(label);
2270 }
2271 }
2272 else
2273 {
2274 labelLength = static_cast<size_t>(length);
2275 }
2276
2277 if (labelLength > context->getExtensions().maxLabelLength)
2278 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002279 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002280 return false;
2281 }
2282
2283 return true;
2284}
2285
Geoff Lange102fee2015-12-10 11:23:30 -05002286bool ValidateObjectLabelKHR(Context *context,
2287 GLenum identifier,
2288 GLuint name,
2289 GLsizei length,
2290 const GLchar *label)
2291{
2292 if (!context->getExtensions().debug)
2293 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002294 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002295 return false;
2296 }
2297
Geoff Lang70d0f492015-12-10 17:45:46 -05002298 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2299 {
2300 return false;
2301 }
2302
Martin Radev9d901792016-07-15 15:58:58 +03002303 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002304 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002305 return false;
2306 }
2307
Geoff Lange102fee2015-12-10 11:23:30 -05002308 return true;
2309}
2310
2311bool ValidateGetObjectLabelKHR(Context *context,
2312 GLenum identifier,
2313 GLuint name,
2314 GLsizei bufSize,
2315 GLsizei *length,
2316 GLchar *label)
2317{
2318 if (!context->getExtensions().debug)
2319 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002320 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002321 return false;
2322 }
2323
Geoff Lang70d0f492015-12-10 17:45:46 -05002324 if (bufSize < 0)
2325 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002326 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002327 return false;
2328 }
2329
2330 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2331 {
2332 return false;
2333 }
2334
Martin Radev9d901792016-07-15 15:58:58 +03002335 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002336}
2337
2338static bool ValidateObjectPtrName(Context *context, const void *ptr)
2339{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002340 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002341 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002342 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002343 return false;
2344 }
2345
Geoff Lange102fee2015-12-10 11:23:30 -05002346 return true;
2347}
2348
2349bool ValidateObjectPtrLabelKHR(Context *context,
2350 const void *ptr,
2351 GLsizei length,
2352 const GLchar *label)
2353{
2354 if (!context->getExtensions().debug)
2355 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002356 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002357 return false;
2358 }
2359
Geoff Lang70d0f492015-12-10 17:45:46 -05002360 if (!ValidateObjectPtrName(context, ptr))
2361 {
2362 return false;
2363 }
2364
Martin Radev9d901792016-07-15 15:58:58 +03002365 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002366 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002367 return false;
2368 }
2369
Geoff Lange102fee2015-12-10 11:23:30 -05002370 return true;
2371}
2372
2373bool ValidateGetObjectPtrLabelKHR(Context *context,
2374 const void *ptr,
2375 GLsizei bufSize,
2376 GLsizei *length,
2377 GLchar *label)
2378{
2379 if (!context->getExtensions().debug)
2380 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002382 return false;
2383 }
2384
Geoff Lang70d0f492015-12-10 17:45:46 -05002385 if (bufSize < 0)
2386 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002387 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002388 return false;
2389 }
2390
2391 if (!ValidateObjectPtrName(context, ptr))
2392 {
2393 return false;
2394 }
2395
Martin Radev9d901792016-07-15 15:58:58 +03002396 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002397}
2398
2399bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2400{
2401 if (!context->getExtensions().debug)
2402 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002403 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002404 return false;
2405 }
2406
Geoff Lang70d0f492015-12-10 17:45:46 -05002407 // TODO: represent this in Context::getQueryParameterInfo.
2408 switch (pname)
2409 {
2410 case GL_DEBUG_CALLBACK_FUNCTION:
2411 case GL_DEBUG_CALLBACK_USER_PARAM:
2412 break;
2413
2414 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002415 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002416 return false;
2417 }
2418
Geoff Lange102fee2015-12-10 11:23:30 -05002419 return true;
2420}
Jamie Madillc29968b2016-01-20 11:17:23 -05002421
2422bool ValidateBlitFramebufferANGLE(Context *context,
2423 GLint srcX0,
2424 GLint srcY0,
2425 GLint srcX1,
2426 GLint srcY1,
2427 GLint dstX0,
2428 GLint dstY0,
2429 GLint dstX1,
2430 GLint dstY1,
2431 GLbitfield mask,
2432 GLenum filter)
2433{
2434 if (!context->getExtensions().framebufferBlit)
2435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002436 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002437 return false;
2438 }
2439
2440 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2441 {
2442 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002443 context->handleError(InvalidOperation() << "Scaling and flipping in "
2444 "BlitFramebufferANGLE not supported by this "
2445 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002446 return false;
2447 }
2448
2449 if (filter == GL_LINEAR)
2450 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002451 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002452 return false;
2453 }
2454
Jamie Madill51f40ec2016-06-15 14:06:00 -04002455 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2456 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002457
2458 if (mask & GL_COLOR_BUFFER_BIT)
2459 {
2460 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2461 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2462
2463 if (readColorAttachment && drawColorAttachment)
2464 {
2465 if (!(readColorAttachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002466 readColorAttachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002467 readColorAttachment->type() != GL_RENDERBUFFER &&
2468 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002470 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002471 return false;
2472 }
2473
Geoff Langa15472a2015-08-11 11:48:03 -04002474 for (size_t drawbufferIdx = 0;
2475 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002476 {
Geoff Langa15472a2015-08-11 11:48:03 -04002477 const FramebufferAttachment *attachment =
2478 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2479 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002480 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002481 if (!(attachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002482 attachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 attachment->type() != GL_RENDERBUFFER &&
2484 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2485 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002486 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002487 return false;
2488 }
2489
2490 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002491 if (!Format::EquivalentForBlit(attachment->getFormat(),
2492 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002493 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002494 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002495 return false;
2496 }
2497 }
2498 }
2499
Jamie Madille98b1b52018-03-08 09:47:23 -05002500 GLint samples = 0;
2501 ANGLE_VALIDATION_TRY(readFramebuffer->getSamples(context, &samples));
2502 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002503 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2504 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2505 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002506 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002507 return false;
2508 }
2509 }
2510 }
2511
2512 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2513 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2514 for (size_t i = 0; i < 2; i++)
2515 {
2516 if (mask & masks[i])
2517 {
2518 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002519 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002520 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002521 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002522
2523 if (readBuffer && drawBuffer)
2524 {
2525 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2526 dstX0, dstY0, dstX1, dstY1))
2527 {
2528 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002529 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2530 "stencil blits are supported by "
2531 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002532 return false;
2533 }
2534
2535 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2536 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002537 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 return false;
2539 }
2540 }
2541 }
2542 }
2543
2544 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2545 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002546}
Jamie Madillc29968b2016-01-20 11:17:23 -05002547
Jamie Madill5b772312018-03-08 20:28:32 -05002548bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002549{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002550 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002551
2552 if (!ValidateFramebufferComplete(context, fbo, true))
Jamie Madillc29968b2016-01-20 11:17:23 -05002553 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002554 return false;
2555 }
2556
2557 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2558 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002559 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002560 return false;
2561 }
2562
Geoff Lang76e65652017-03-27 14:58:02 -04002563 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2564 {
2565 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2566 GL_SIGNED_NORMALIZED};
2567
Corentin Wallez59c41592017-07-11 13:19:54 -04002568 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002569 drawBufferIdx++)
2570 {
2571 if (!ValidateWebGLFramebufferAttachmentClearType(
2572 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2573 {
2574 return false;
2575 }
2576 }
2577 }
2578
Jamie Madillc29968b2016-01-20 11:17:23 -05002579 return true;
2580}
2581
Jamie Madill5b772312018-03-08 20:28:32 -05002582bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002583{
2584 if (!context->getExtensions().drawBuffers)
2585 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002586 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002587 return false;
2588 }
2589
2590 return ValidateDrawBuffersBase(context, n, bufs);
2591}
2592
Jamie Madill73a84962016-02-12 09:27:23 -05002593bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002594 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002595 GLint level,
2596 GLint internalformat,
2597 GLsizei width,
2598 GLsizei height,
2599 GLint border,
2600 GLenum format,
2601 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002602 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002603{
Martin Radev1be913c2016-07-11 17:59:16 +03002604 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002605 {
2606 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002607 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002608 }
2609
Martin Radev1be913c2016-07-11 17:59:16 +03002610 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002611 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002612 0, 0, width, height, 1, border, format, type, -1,
2613 pixels);
2614}
2615
2616bool ValidateTexImage2DRobust(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002617 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04002618 GLint level,
2619 GLint internalformat,
2620 GLsizei width,
2621 GLsizei height,
2622 GLint border,
2623 GLenum format,
2624 GLenum type,
2625 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002626 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002627{
2628 if (!ValidateRobustEntryPoint(context, bufSize))
2629 {
2630 return false;
2631 }
2632
2633 if (context->getClientMajorVersion() < 3)
2634 {
2635 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2636 0, 0, width, height, border, format, type, bufSize,
2637 pixels);
2638 }
2639
2640 ASSERT(context->getClientMajorVersion() >= 3);
2641 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2642 0, 0, width, height, 1, border, format, type, bufSize,
2643 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002644}
2645
2646bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002647 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002648 GLint level,
2649 GLint xoffset,
2650 GLint yoffset,
2651 GLsizei width,
2652 GLsizei height,
2653 GLenum format,
2654 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002655 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002656{
2657
Martin Radev1be913c2016-07-11 17:59:16 +03002658 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002659 {
2660 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002661 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002662 }
2663
Martin Radev1be913c2016-07-11 17:59:16 +03002664 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002665 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002666 yoffset, 0, width, height, 1, 0, format, type, -1,
2667 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002668}
2669
Geoff Langc52f6f12016-10-14 10:18:00 -04002670bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002671 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002672 GLint level,
2673 GLint xoffset,
2674 GLint yoffset,
2675 GLsizei width,
2676 GLsizei height,
2677 GLenum format,
2678 GLenum type,
2679 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002680 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002681{
2682 if (!ValidateRobustEntryPoint(context, bufSize))
2683 {
2684 return false;
2685 }
2686
2687 if (context->getClientMajorVersion() < 3)
2688 {
2689 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2690 yoffset, width, height, 0, format, type, bufSize,
2691 pixels);
2692 }
2693
2694 ASSERT(context->getClientMajorVersion() >= 3);
2695 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2696 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2697 pixels);
2698}
2699
Jamie Madill73a84962016-02-12 09:27:23 -05002700bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002701 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002702 GLint level,
2703 GLenum internalformat,
2704 GLsizei width,
2705 GLsizei height,
2706 GLint border,
2707 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002708 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002709{
Martin Radev1be913c2016-07-11 17:59:16 +03002710 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002711 {
2712 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002713 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002714 {
2715 return false;
2716 }
2717 }
2718 else
2719 {
Martin Radev1be913c2016-07-11 17:59:16 +03002720 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002721 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002722 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002723 data))
2724 {
2725 return false;
2726 }
2727 }
2728
Geoff Langca271392017-04-05 12:30:00 -04002729 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002730 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002731 if (blockSizeOrErr.isError())
2732 {
2733 context->handleError(blockSizeOrErr.getError());
2734 return false;
2735 }
2736
2737 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002738 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002739 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002740 return false;
2741 }
2742
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002743 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002744 {
2745 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2746 return false;
2747 }
2748
Jamie Madill73a84962016-02-12 09:27:23 -05002749 return true;
2750}
2751
Corentin Wallezb2931602017-04-11 15:58:57 -04002752bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002753 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002754 GLint level,
2755 GLenum internalformat,
2756 GLsizei width,
2757 GLsizei height,
2758 GLint border,
2759 GLsizei imageSize,
2760 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002761 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002762{
2763 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2764 {
2765 return false;
2766 }
2767
2768 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2769 border, imageSize, data);
2770}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002771
Corentin Wallezb2931602017-04-11 15:58:57 -04002772bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002773 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002774 GLint level,
2775 GLint xoffset,
2776 GLint yoffset,
2777 GLsizei width,
2778 GLsizei height,
2779 GLenum format,
2780 GLsizei imageSize,
2781 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002782 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002783{
2784 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2785 {
2786 return false;
2787 }
2788
2789 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2790 format, imageSize, data);
2791}
2792
Jamie Madill73a84962016-02-12 09:27:23 -05002793bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002794 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002795 GLint level,
2796 GLint xoffset,
2797 GLint yoffset,
2798 GLsizei width,
2799 GLsizei height,
2800 GLenum format,
2801 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002802 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002803{
Martin Radev1be913c2016-07-11 17:59:16 +03002804 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002805 {
2806 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002807 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002808 {
2809 return false;
2810 }
2811 }
2812 else
2813 {
Martin Radev1be913c2016-07-11 17:59:16 +03002814 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002815 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002816 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002817 data))
2818 {
2819 return false;
2820 }
2821 }
2822
Geoff Langca271392017-04-05 12:30:00 -04002823 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002824 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002825 if (blockSizeOrErr.isError())
2826 {
2827 context->handleError(blockSizeOrErr.getError());
2828 return false;
2829 }
2830
2831 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002832 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002833 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002834 return false;
2835 }
2836
2837 return true;
2838}
2839
Corentin Wallez336129f2017-10-17 15:55:40 -04002840bool ValidateGetBufferPointervOES(Context *context,
2841 BufferBinding target,
2842 GLenum pname,
2843 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002844{
Geoff Lang496c02d2016-10-20 11:38:11 -07002845 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002846}
2847
Corentin Wallez336129f2017-10-17 15:55:40 -04002848bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002849{
2850 if (!context->getExtensions().mapBuffer)
2851 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002852 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002853 return false;
2854 }
2855
Corentin Walleze4477002017-12-01 14:39:58 -05002856 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002857 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002858 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002859 return false;
2860 }
2861
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002862 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002863
2864 if (buffer == nullptr)
2865 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002866 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002867 return false;
2868 }
2869
2870 if (access != GL_WRITE_ONLY_OES)
2871 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002872 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002873 return false;
2874 }
2875
2876 if (buffer->isMapped())
2877 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002878 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002879 return false;
2880 }
2881
Geoff Lang79f71042017-08-14 16:43:43 -04002882 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002883}
2884
Corentin Wallez336129f2017-10-17 15:55:40 -04002885bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002886{
2887 if (!context->getExtensions().mapBuffer)
2888 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002889 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002890 return false;
2891 }
2892
2893 return ValidateUnmapBufferBase(context, target);
2894}
2895
2896bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002897 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002898 GLintptr offset,
2899 GLsizeiptr length,
2900 GLbitfield access)
2901{
2902 if (!context->getExtensions().mapBufferRange)
2903 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002904 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002905 return false;
2906 }
2907
2908 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2909}
2910
Corentin Wallez336129f2017-10-17 15:55:40 -04002911bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002912{
2913 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2914 ASSERT(buffer != nullptr);
2915
2916 // Check if this buffer is currently being used as a transform feedback output buffer
2917 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2918 if (transformFeedback != nullptr && transformFeedback->isActive())
2919 {
2920 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2921 {
2922 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2923 if (transformFeedbackBuffer.get() == buffer)
2924 {
2925 context->handleError(InvalidOperation()
2926 << "Buffer is currently bound for transform feedback.");
2927 return false;
2928 }
2929 }
2930 }
2931
James Darpiniane8a93c62018-01-04 18:02:24 -08002932 if (context->getExtensions().webglCompatibility &&
2933 buffer->isBoundForTransformFeedbackAndOtherUse())
2934 {
2935 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2936 return false;
2937 }
2938
Geoff Lang79f71042017-08-14 16:43:43 -04002939 return true;
2940}
2941
Olli Etuaho4f667482016-03-30 15:56:35 +03002942bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002943 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002944 GLintptr offset,
2945 GLsizeiptr length)
2946{
2947 if (!context->getExtensions().mapBufferRange)
2948 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002949 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002950 return false;
2951 }
2952
2953 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2954}
2955
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002956bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002957{
2958 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002959 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002960 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002961 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002962 return false;
2963 }
2964
Geoff Langf41a7152016-09-19 15:11:17 -04002965 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2966 !context->isTextureGenerated(texture))
2967 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002968 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002969 return false;
2970 }
2971
Ian Ewell54f87462016-03-10 13:47:21 -05002972 switch (target)
2973 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002974 case TextureType::_2D:
2975 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002976 break;
2977
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002978 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002979 if (!context->getExtensions().textureRectangle)
2980 {
2981 context->handleError(InvalidEnum()
2982 << "Context does not support GL_ANGLE_texture_rectangle");
2983 return false;
2984 }
2985 break;
2986
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002987 case TextureType::_3D:
2988 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002989 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002990 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002991 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002992 return false;
2993 }
2994 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002995
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002996 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04002997 if (context->getClientVersion() < Version(3, 1))
2998 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002999 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003000 return false;
3001 }
Geoff Lang3b573612016-10-31 14:08:10 -04003002 break;
3003
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003004 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003005 if (!context->getExtensions().eglImageExternal &&
3006 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003008 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003009 return false;
3010 }
3011 break;
3012 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003013 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003014 return false;
3015 }
3016
3017 return true;
3018}
3019
Geoff Langd8605522016-04-13 10:19:12 -04003020bool ValidateBindUniformLocationCHROMIUM(Context *context,
3021 GLuint program,
3022 GLint location,
3023 const GLchar *name)
3024{
3025 if (!context->getExtensions().bindUniformLocation)
3026 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003027 context->handleError(InvalidOperation()
3028 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003029 return false;
3030 }
3031
3032 Program *programObject = GetValidProgram(context, program);
3033 if (!programObject)
3034 {
3035 return false;
3036 }
3037
3038 if (location < 0)
3039 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003040 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003041 return false;
3042 }
3043
3044 const Caps &caps = context->getCaps();
3045 if (static_cast<size_t>(location) >=
3046 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3047 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003048 context->handleError(InvalidValue() << "Location must be less than "
3049 "(MAX_VERTEX_UNIFORM_VECTORS + "
3050 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003051 return false;
3052 }
3053
Geoff Langfc32e8b2017-05-31 14:16:59 -04003054 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3055 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003056 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003058 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003059 return false;
3060 }
3061
Geoff Langd8605522016-04-13 10:19:12 -04003062 if (strncmp(name, "gl_", 3) == 0)
3063 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003064 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003065 return false;
3066 }
3067
3068 return true;
3069}
3070
Jamie Madille2e406c2016-06-02 13:04:10 -04003071bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003072{
3073 if (!context->getExtensions().framebufferMixedSamples)
3074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003075 context->handleError(InvalidOperation()
3076 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003077 return false;
3078 }
3079 switch (components)
3080 {
3081 case GL_RGB:
3082 case GL_RGBA:
3083 case GL_ALPHA:
3084 case GL_NONE:
3085 break;
3086 default:
3087 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003088 InvalidEnum()
3089 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003090 return false;
3091 }
3092
3093 return true;
3094}
3095
Sami Väisänene45e53b2016-05-25 10:36:04 +03003096// CHROMIUM_path_rendering
3097
Jamie Madill007530e2017-12-28 14:27:04 -05003098bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003099{
Jamie Madill007530e2017-12-28 14:27:04 -05003100 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003101 {
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 if (matrix == nullptr)
3106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003107 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003108 return false;
3109 }
Jamie Madill007530e2017-12-28 14:27:04 -05003110
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111 return true;
3112}
3113
Jamie Madill007530e2017-12-28 14:27:04 -05003114bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003115{
Jamie Madill007530e2017-12-28 14:27:04 -05003116 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003117}
3118
Jamie Madill007530e2017-12-28 14:27:04 -05003119bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003120{
3121 if (!context->getExtensions().pathRendering)
3122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003123 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003124 return false;
3125 }
3126
3127 // range = 0 is undefined in NV_path_rendering.
3128 // we add stricter semantic check here and require a non zero positive range.
3129 if (range <= 0)
3130 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003131 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003132 return false;
3133 }
3134
3135 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003137 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003138 return false;
3139 }
3140
3141 return true;
3142}
3143
Jamie Madill007530e2017-12-28 14:27:04 -05003144bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003145{
3146 if (!context->getExtensions().pathRendering)
3147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003148 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003149 return false;
3150 }
3151
3152 // range = 0 is undefined in NV_path_rendering.
3153 // we add stricter semantic check here and require a non zero positive range.
3154 if (range <= 0)
3155 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003156 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003157 return false;
3158 }
3159
3160 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3161 checkedRange += range;
3162
3163 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003166 return false;
3167 }
3168 return true;
3169}
3170
Jamie Madill007530e2017-12-28 14:27:04 -05003171bool ValidatePathCommandsCHROMIUM(Context *context,
3172 GLuint path,
3173 GLsizei numCommands,
3174 const GLubyte *commands,
3175 GLsizei numCoords,
3176 GLenum coordType,
3177 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003178{
3179 if (!context->getExtensions().pathRendering)
3180 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003181 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003182 return false;
3183 }
3184 if (!context->hasPath(path))
3185 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003186 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003187 return false;
3188 }
3189
3190 if (numCommands < 0)
3191 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003192 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003193 return false;
3194 }
3195 else if (numCommands > 0)
3196 {
3197 if (!commands)
3198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003199 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003200 return false;
3201 }
3202 }
3203
3204 if (numCoords < 0)
3205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003206 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003207 return false;
3208 }
3209 else if (numCoords > 0)
3210 {
3211 if (!coords)
3212 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003213 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003214 return false;
3215 }
3216 }
3217
3218 std::uint32_t coordTypeSize = 0;
3219 switch (coordType)
3220 {
3221 case GL_BYTE:
3222 coordTypeSize = sizeof(GLbyte);
3223 break;
3224
3225 case GL_UNSIGNED_BYTE:
3226 coordTypeSize = sizeof(GLubyte);
3227 break;
3228
3229 case GL_SHORT:
3230 coordTypeSize = sizeof(GLshort);
3231 break;
3232
3233 case GL_UNSIGNED_SHORT:
3234 coordTypeSize = sizeof(GLushort);
3235 break;
3236
3237 case GL_FLOAT:
3238 coordTypeSize = sizeof(GLfloat);
3239 break;
3240
3241 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003242 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003243 return false;
3244 }
3245
3246 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3247 checkedSize += (coordTypeSize * numCoords);
3248 if (!checkedSize.IsValid())
3249 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003250 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003251 return false;
3252 }
3253
3254 // early return skips command data validation when it doesn't exist.
3255 if (!commands)
3256 return true;
3257
3258 GLsizei expectedNumCoords = 0;
3259 for (GLsizei i = 0; i < numCommands; ++i)
3260 {
3261 switch (commands[i])
3262 {
3263 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3264 break;
3265 case GL_MOVE_TO_CHROMIUM:
3266 case GL_LINE_TO_CHROMIUM:
3267 expectedNumCoords += 2;
3268 break;
3269 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3270 expectedNumCoords += 4;
3271 break;
3272 case GL_CUBIC_CURVE_TO_CHROMIUM:
3273 expectedNumCoords += 6;
3274 break;
3275 case GL_CONIC_CURVE_TO_CHROMIUM:
3276 expectedNumCoords += 5;
3277 break;
3278 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003279 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280 return false;
3281 }
3282 }
3283 if (expectedNumCoords != numCoords)
3284 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003285 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003286 return false;
3287 }
3288
3289 return true;
3290}
3291
Jamie Madill007530e2017-12-28 14:27:04 -05003292bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003293{
3294 if (!context->getExtensions().pathRendering)
3295 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003296 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003297 return false;
3298 }
3299 if (!context->hasPath(path))
3300 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003301 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003302 return false;
3303 }
3304
3305 switch (pname)
3306 {
3307 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3308 if (value < 0.0f)
3309 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003310 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003311 return false;
3312 }
3313 break;
3314 case GL_PATH_END_CAPS_CHROMIUM:
3315 switch (static_cast<GLenum>(value))
3316 {
3317 case GL_FLAT_CHROMIUM:
3318 case GL_SQUARE_CHROMIUM:
3319 case GL_ROUND_CHROMIUM:
3320 break;
3321 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003322 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003323 return false;
3324 }
3325 break;
3326 case GL_PATH_JOIN_STYLE_CHROMIUM:
3327 switch (static_cast<GLenum>(value))
3328 {
3329 case GL_MITER_REVERT_CHROMIUM:
3330 case GL_BEVEL_CHROMIUM:
3331 case GL_ROUND_CHROMIUM:
3332 break;
3333 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003334 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003335 return false;
3336 }
Nico Weber41b072b2018-02-09 10:01:32 -05003337 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003338 case GL_PATH_MITER_LIMIT_CHROMIUM:
3339 if (value < 0.0f)
3340 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003341 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003342 return false;
3343 }
3344 break;
3345
3346 case GL_PATH_STROKE_BOUND_CHROMIUM:
3347 // no errors, only clamping.
3348 break;
3349
3350 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003351 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003352 return false;
3353 }
3354 return true;
3355}
3356
Jamie Madill007530e2017-12-28 14:27:04 -05003357bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3358{
3359 // TODO(jmadill): Use proper clamping cast.
3360 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3361}
3362
3363bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003364{
3365 if (!context->getExtensions().pathRendering)
3366 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003367 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003368 return false;
3369 }
3370
3371 if (!context->hasPath(path))
3372 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003373 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003374 return false;
3375 }
3376 if (!value)
3377 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003378 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003379 return false;
3380 }
3381
3382 switch (pname)
3383 {
3384 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3385 case GL_PATH_END_CAPS_CHROMIUM:
3386 case GL_PATH_JOIN_STYLE_CHROMIUM:
3387 case GL_PATH_MITER_LIMIT_CHROMIUM:
3388 case GL_PATH_STROKE_BOUND_CHROMIUM:
3389 break;
3390
3391 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003392 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003393 return false;
3394 }
3395
3396 return true;
3397}
3398
Jamie Madill007530e2017-12-28 14:27:04 -05003399bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3400{
3401 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3402 reinterpret_cast<GLfloat *>(value));
3403}
3404
3405bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003406{
3407 if (!context->getExtensions().pathRendering)
3408 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003409 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003410 return false;
3411 }
3412
3413 switch (func)
3414 {
3415 case GL_NEVER:
3416 case GL_ALWAYS:
3417 case GL_LESS:
3418 case GL_LEQUAL:
3419 case GL_EQUAL:
3420 case GL_GEQUAL:
3421 case GL_GREATER:
3422 case GL_NOTEQUAL:
3423 break;
3424 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003425 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003426 return false;
3427 }
3428
3429 return true;
3430}
3431
3432// Note that the spec specifies that for the path drawing commands
3433// if the path object is not an existing path object the command
3434// does nothing and no error is generated.
3435// However if the path object exists but has not been specified any
3436// commands then an error is generated.
3437
Jamie Madill007530e2017-12-28 14:27:04 -05003438bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003439{
3440 if (!context->getExtensions().pathRendering)
3441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003442 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003443 return false;
3444 }
3445 if (context->hasPath(path) && !context->hasPathData(path))
3446 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003447 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003448 return false;
3449 }
3450
3451 switch (fillMode)
3452 {
3453 case GL_COUNT_UP_CHROMIUM:
3454 case GL_COUNT_DOWN_CHROMIUM:
3455 break;
3456 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003457 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458 return false;
3459 }
3460
3461 if (!isPow2(mask + 1))
3462 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003463 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003464 return false;
3465 }
3466
3467 return true;
3468}
3469
Jamie Madill007530e2017-12-28 14:27:04 -05003470bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471{
3472 if (!context->getExtensions().pathRendering)
3473 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003474 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003475 return false;
3476 }
3477 if (context->hasPath(path) && !context->hasPathData(path))
3478 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003479 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003480 return false;
3481 }
3482
3483 return true;
3484}
3485
Brandon Jonesd1049182018-03-28 10:02:20 -07003486bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3487{
3488 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3489}
3490
3491bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3492{
3493 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3494}
3495
Jamie Madill007530e2017-12-28 14:27:04 -05003496bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003497{
3498 if (!context->getExtensions().pathRendering)
3499 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003500 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003501 return false;
3502 }
3503 if (context->hasPath(path) && !context->hasPathData(path))
3504 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003506 return false;
3507 }
3508
3509 switch (coverMode)
3510 {
3511 case GL_CONVEX_HULL_CHROMIUM:
3512 case GL_BOUNDING_BOX_CHROMIUM:
3513 break;
3514 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003515 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003516 return false;
3517 }
3518 return true;
3519}
3520
Jamie Madill007530e2017-12-28 14:27:04 -05003521bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3522 GLuint path,
3523 GLenum fillMode,
3524 GLuint mask,
3525 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003526{
Jamie Madill007530e2017-12-28 14:27:04 -05003527 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3528 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003529}
3530
Jamie Madill007530e2017-12-28 14:27:04 -05003531bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3532 GLuint path,
3533 GLint reference,
3534 GLuint mask,
3535 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003536{
Jamie Madill007530e2017-12-28 14:27:04 -05003537 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3538 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003539}
3540
Brandon Jonesd1049182018-03-28 10:02:20 -07003541bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542{
3543 if (!context->getExtensions().pathRendering)
3544 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003545 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546 return false;
3547 }
3548 return true;
3549}
3550
Jamie Madill007530e2017-12-28 14:27:04 -05003551bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3552 GLsizei numPaths,
3553 GLenum pathNameType,
3554 const void *paths,
3555 GLuint pathBase,
3556 GLenum coverMode,
3557 GLenum transformType,
3558 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003559{
3560 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3561 transformType, transformValues))
3562 return false;
3563
3564 switch (coverMode)
3565 {
3566 case GL_CONVEX_HULL_CHROMIUM:
3567 case GL_BOUNDING_BOX_CHROMIUM:
3568 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3569 break;
3570 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003571 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003572 return false;
3573 }
3574
3575 return true;
3576}
3577
Jamie Madill007530e2017-12-28 14:27:04 -05003578bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3579 GLsizei numPaths,
3580 GLenum pathNameType,
3581 const void *paths,
3582 GLuint pathBase,
3583 GLenum coverMode,
3584 GLenum transformType,
3585 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003586{
3587 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3588 transformType, transformValues))
3589 return false;
3590
3591 switch (coverMode)
3592 {
3593 case GL_CONVEX_HULL_CHROMIUM:
3594 case GL_BOUNDING_BOX_CHROMIUM:
3595 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3596 break;
3597 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003598 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003599 return false;
3600 }
3601
3602 return true;
3603}
3604
Jamie Madill007530e2017-12-28 14:27:04 -05003605bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3606 GLsizei numPaths,
3607 GLenum pathNameType,
3608 const void *paths,
3609 GLuint pathBase,
3610 GLenum fillMode,
3611 GLuint mask,
3612 GLenum transformType,
3613 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003614{
3615
3616 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3617 transformType, transformValues))
3618 return false;
3619
3620 switch (fillMode)
3621 {
3622 case GL_COUNT_UP_CHROMIUM:
3623 case GL_COUNT_DOWN_CHROMIUM:
3624 break;
3625 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003626 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003627 return false;
3628 }
3629 if (!isPow2(mask + 1))
3630 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003631 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003632 return false;
3633 }
3634 return true;
3635}
3636
Jamie Madill007530e2017-12-28 14:27:04 -05003637bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3638 GLsizei numPaths,
3639 GLenum pathNameType,
3640 const void *paths,
3641 GLuint pathBase,
3642 GLint reference,
3643 GLuint mask,
3644 GLenum transformType,
3645 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003646{
3647 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3648 transformType, transformValues))
3649 return false;
3650
3651 // no more validation here.
3652
3653 return true;
3654}
3655
Jamie Madill007530e2017-12-28 14:27:04 -05003656bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3657 GLsizei numPaths,
3658 GLenum pathNameType,
3659 const void *paths,
3660 GLuint pathBase,
3661 GLenum fillMode,
3662 GLuint mask,
3663 GLenum coverMode,
3664 GLenum transformType,
3665 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003666{
3667 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3668 transformType, transformValues))
3669 return false;
3670
3671 switch (coverMode)
3672 {
3673 case GL_CONVEX_HULL_CHROMIUM:
3674 case GL_BOUNDING_BOX_CHROMIUM:
3675 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3676 break;
3677 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003678 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003679 return false;
3680 }
3681
3682 switch (fillMode)
3683 {
3684 case GL_COUNT_UP_CHROMIUM:
3685 case GL_COUNT_DOWN_CHROMIUM:
3686 break;
3687 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003688 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003689 return false;
3690 }
3691 if (!isPow2(mask + 1))
3692 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003693 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003694 return false;
3695 }
3696
3697 return true;
3698}
3699
Jamie Madill007530e2017-12-28 14:27:04 -05003700bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3701 GLsizei numPaths,
3702 GLenum pathNameType,
3703 const void *paths,
3704 GLuint pathBase,
3705 GLint reference,
3706 GLuint mask,
3707 GLenum coverMode,
3708 GLenum transformType,
3709 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003710{
3711 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3712 transformType, transformValues))
3713 return false;
3714
3715 switch (coverMode)
3716 {
3717 case GL_CONVEX_HULL_CHROMIUM:
3718 case GL_BOUNDING_BOX_CHROMIUM:
3719 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3720 break;
3721 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003722 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003723 return false;
3724 }
3725
3726 return true;
3727}
3728
Jamie Madill007530e2017-12-28 14:27:04 -05003729bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3730 GLuint program,
3731 GLint location,
3732 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003733{
3734 if (!context->getExtensions().pathRendering)
3735 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003736 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003737 return false;
3738 }
3739
3740 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3741 if (location >= MaxLocation)
3742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003743 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003744 return false;
3745 }
3746
3747 const auto *programObject = context->getProgram(program);
3748 if (!programObject)
3749 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003750 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003751 return false;
3752 }
3753
3754 if (!name)
3755 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003756 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003757 return false;
3758 }
3759
3760 if (angle::BeginsWith(name, "gl_"))
3761 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003762 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003763 return false;
3764 }
3765
3766 return true;
3767}
3768
Jamie Madill007530e2017-12-28 14:27:04 -05003769bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3770 GLuint program,
3771 GLint location,
3772 GLenum genMode,
3773 GLint components,
3774 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003775{
3776 if (!context->getExtensions().pathRendering)
3777 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003778 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003779 return false;
3780 }
3781
3782 const auto *programObject = context->getProgram(program);
3783 if (!programObject || programObject->isFlaggedForDeletion())
3784 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003785 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003786 return false;
3787 }
3788
3789 if (!programObject->isLinked())
3790 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003791 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003792 return false;
3793 }
3794
3795 switch (genMode)
3796 {
3797 case GL_NONE:
3798 if (components != 0)
3799 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003800 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003801 return false;
3802 }
3803 break;
3804
3805 case GL_OBJECT_LINEAR_CHROMIUM:
3806 case GL_EYE_LINEAR_CHROMIUM:
3807 case GL_CONSTANT_CHROMIUM:
3808 if (components < 1 || components > 4)
3809 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003810 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003811 return false;
3812 }
3813 if (!coeffs)
3814 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003815 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003816 return false;
3817 }
3818 break;
3819
3820 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003821 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003822 return false;
3823 }
3824
3825 // If the location is -1 then the command is silently ignored
3826 // and no further validation is needed.
3827 if (location == -1)
3828 return true;
3829
Jamie Madillbd044ed2017-06-05 12:59:21 -04003830 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003831
3832 if (!binding.valid)
3833 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003834 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003835 return false;
3836 }
3837
3838 if (binding.type != GL_NONE)
3839 {
3840 GLint expectedComponents = 0;
3841 switch (binding.type)
3842 {
3843 case GL_FLOAT:
3844 expectedComponents = 1;
3845 break;
3846 case GL_FLOAT_VEC2:
3847 expectedComponents = 2;
3848 break;
3849 case GL_FLOAT_VEC3:
3850 expectedComponents = 3;
3851 break;
3852 case GL_FLOAT_VEC4:
3853 expectedComponents = 4;
3854 break;
3855 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003856 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003857 InvalidOperation()
3858 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003859 return false;
3860 }
3861 if (expectedComponents != components && genMode != GL_NONE)
3862 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003863 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003864 return false;
3865 }
3866 }
3867 return true;
3868}
3869
Geoff Lang97073d12016-04-20 10:42:34 -07003870bool ValidateCopyTextureCHROMIUM(Context *context,
3871 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003872 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003873 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003874 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003875 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003876 GLint internalFormat,
3877 GLenum destType,
3878 GLboolean unpackFlipY,
3879 GLboolean unpackPremultiplyAlpha,
3880 GLboolean unpackUnmultiplyAlpha)
3881{
3882 if (!context->getExtensions().copyTexture)
3883 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003884 context->handleError(InvalidOperation()
3885 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003886 return false;
3887 }
3888
Geoff Lang4f0e0032017-05-01 16:04:35 -04003889 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003890 if (source == nullptr)
3891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003892 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003893 return false;
3894 }
3895
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003896 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003898 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003899 return false;
3900 }
3901
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003902 TextureType sourceType = source->getType();
3903 ASSERT(sourceType != TextureType::CubeMap);
3904 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003905
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003906 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003907 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003908 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003909 return false;
3910 }
3911
Geoff Lang4f0e0032017-05-01 16:04:35 -04003912 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3913 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3914 if (sourceWidth == 0 || sourceHeight == 0)
3915 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003916 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003917 return false;
3918 }
3919
3920 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3921 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003922 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003923 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003924 return false;
3925 }
3926
Geoff Lang63458a32017-10-30 15:16:53 -04003927 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3928 {
3929 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3930 return false;
3931 }
3932
Geoff Lang4f0e0032017-05-01 16:04:35 -04003933 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003934 if (dest == nullptr)
3935 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003936 context->handleError(InvalidValue()
3937 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003938 return false;
3939 }
3940
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003941 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003942 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003943 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003944 return false;
3945 }
3946
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003947 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003948 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003949 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003950 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003951 return false;
3952 }
3953
Geoff Lang97073d12016-04-20 10:42:34 -07003954 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3955 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003956 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003957 return false;
3958 }
3959
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003960 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003961 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003962 context->handleError(
3963 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003964 return false;
3965 }
3966
Geoff Lang97073d12016-04-20 10:42:34 -07003967 if (dest->getImmutableFormat())
3968 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003969 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003970 return false;
3971 }
3972
3973 return true;
3974}
3975
3976bool ValidateCopySubTextureCHROMIUM(Context *context,
3977 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003978 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003979 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003980 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003981 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003982 GLint xoffset,
3983 GLint yoffset,
3984 GLint x,
3985 GLint y,
3986 GLsizei width,
3987 GLsizei height,
3988 GLboolean unpackFlipY,
3989 GLboolean unpackPremultiplyAlpha,
3990 GLboolean unpackUnmultiplyAlpha)
3991{
3992 if (!context->getExtensions().copyTexture)
3993 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003994 context->handleError(InvalidOperation()
3995 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003996 return false;
3997 }
3998
Geoff Lang4f0e0032017-05-01 16:04:35 -04003999 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004000 if (source == nullptr)
4001 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004002 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004003 return false;
4004 }
4005
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004006 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004008 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004009 return false;
4010 }
4011
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004012 TextureType sourceType = source->getType();
4013 ASSERT(sourceType != TextureType::CubeMap);
4014 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004015
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004016 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004017 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004018 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004019 return false;
4020 }
4021
4022 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4023 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004024 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004025 context->handleError(InvalidValue()
4026 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004027 return false;
4028 }
4029
4030 if (x < 0 || y < 0)
4031 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004032 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004033 return false;
4034 }
4035
4036 if (width < 0 || height < 0)
4037 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004038 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004039 return false;
4040 }
4041
Geoff Lang4f0e0032017-05-01 16:04:35 -04004042 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4043 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004044 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004045 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004046 return false;
4047 }
4048
Geoff Lang4f0e0032017-05-01 16:04:35 -04004049 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4050 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004051 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004052 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004053 return false;
4054 }
4055
Geoff Lang63458a32017-10-30 15:16:53 -04004056 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4057 {
4058 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4059 return false;
4060 }
4061
Geoff Lang4f0e0032017-05-01 16:04:35 -04004062 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004063 if (dest == nullptr)
4064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004065 context->handleError(InvalidValue()
4066 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004067 return false;
4068 }
4069
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004070 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004072 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004073 return false;
4074 }
4075
Brandon Jones28783792018-03-05 09:37:32 -08004076 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4077 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004078 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004079 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004080 return false;
4081 }
4082
Geoff Lang4f0e0032017-05-01 16:04:35 -04004083 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4084 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004085 context
4086 ->handleError(InvalidOperation()
4087 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004088 return false;
4089 }
4090
4091 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4092 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004093 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004094 context->handleError(InvalidOperation()
4095 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004096 return false;
4097 }
4098
4099 if (xoffset < 0 || yoffset < 0)
4100 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004101 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004102 return false;
4103 }
4104
Geoff Lang4f0e0032017-05-01 16:04:35 -04004105 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4106 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004107 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004108 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004109 return false;
4110 }
4111
4112 return true;
4113}
4114
Geoff Lang47110bf2016-04-20 11:13:22 -07004115bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4116{
4117 if (!context->getExtensions().copyCompressedTexture)
4118 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004119 context->handleError(InvalidOperation()
4120 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004121 return false;
4122 }
4123
4124 const gl::Texture *source = context->getTexture(sourceId);
4125 if (source == nullptr)
4126 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004127 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004128 return false;
4129 }
4130
Corentin Wallez99d492c2018-02-27 15:17:10 -05004131 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004133 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004134 return false;
4135 }
4136
Corentin Wallez99d492c2018-02-27 15:17:10 -05004137 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4138 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004140 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004141 return false;
4142 }
4143
Corentin Wallez99d492c2018-02-27 15:17:10 -05004144 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004145 if (!sourceFormat.info->compressed)
4146 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004147 context->handleError(InvalidOperation()
4148 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004149 return false;
4150 }
4151
4152 const gl::Texture *dest = context->getTexture(destId);
4153 if (dest == nullptr)
4154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004155 context->handleError(InvalidValue()
4156 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004157 return false;
4158 }
4159
Corentin Wallez99d492c2018-02-27 15:17:10 -05004160 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004161 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004162 context->handleError(InvalidValue()
4163 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004164 return false;
4165 }
4166
4167 if (dest->getImmutableFormat())
4168 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004169 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004170 return false;
4171 }
4172
4173 return true;
4174}
4175
Jiawei Shao385b3e02018-03-21 09:43:28 +08004176bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004177{
4178 switch (type)
4179 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004180 case ShaderType::Vertex:
4181 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004182 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004183
Jiawei Shao385b3e02018-03-21 09:43:28 +08004184 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004185 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004186 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004187 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004188 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004189 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004190 break;
4191
Jiawei Shao385b3e02018-03-21 09:43:28 +08004192 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004193 if (!context->getExtensions().geometryShader)
4194 {
4195 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4196 return false;
4197 }
4198 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004199 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004201 return false;
4202 }
Jamie Madill29639852016-09-02 15:00:09 -04004203
4204 return true;
4205}
4206
Jamie Madill5b772312018-03-08 20:28:32 -05004207bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004208 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004209 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004210 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004211 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004212{
4213 if (size < 0)
4214 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004215 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004216 return false;
4217 }
4218
4219 switch (usage)
4220 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004221 case BufferUsage::StreamDraw:
4222 case BufferUsage::StaticDraw:
4223 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004224 break;
4225
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004226 case BufferUsage::StreamRead:
4227 case BufferUsage::StaticRead:
4228 case BufferUsage::DynamicRead:
4229 case BufferUsage::StreamCopy:
4230 case BufferUsage::StaticCopy:
4231 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004232 if (context->getClientMajorVersion() < 3)
4233 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004234 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004235 return false;
4236 }
4237 break;
4238
4239 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004240 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004241 return false;
4242 }
4243
Corentin Walleze4477002017-12-01 14:39:58 -05004244 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004246 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004247 return false;
4248 }
4249
4250 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4251
4252 if (!buffer)
4253 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004254 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004255 return false;
4256 }
4257
James Darpiniane8a93c62018-01-04 18:02:24 -08004258 if (context->getExtensions().webglCompatibility &&
4259 buffer->isBoundForTransformFeedbackAndOtherUse())
4260 {
4261 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4262 return false;
4263 }
4264
Jamie Madill29639852016-09-02 15:00:09 -04004265 return true;
4266}
4267
Jamie Madill5b772312018-03-08 20:28:32 -05004268bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004269 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004270 GLintptr offset,
4271 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004272 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004273{
Brandon Jones6cad5662017-06-14 13:25:13 -07004274 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004275 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004276 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4277 return false;
4278 }
4279
4280 if (offset < 0)
4281 {
4282 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004283 return false;
4284 }
4285
Corentin Walleze4477002017-12-01 14:39:58 -05004286 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004287 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004288 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004289 return false;
4290 }
4291
4292 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4293
4294 if (!buffer)
4295 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004296 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004297 return false;
4298 }
4299
4300 if (buffer->isMapped())
4301 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004302 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004303 return false;
4304 }
4305
James Darpiniane8a93c62018-01-04 18:02:24 -08004306 if (context->getExtensions().webglCompatibility &&
4307 buffer->isBoundForTransformFeedbackAndOtherUse())
4308 {
4309 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4310 return false;
4311 }
4312
Jamie Madill29639852016-09-02 15:00:09 -04004313 // Check for possible overflow of size + offset
4314 angle::CheckedNumeric<size_t> checkedSize(size);
4315 checkedSize += offset;
4316 if (!checkedSize.IsValid())
4317 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004318 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004319 return false;
4320 }
4321
4322 if (size + offset > buffer->getSize())
4323 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004324 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004325 return false;
4326 }
4327
Martin Radev4c4c8e72016-08-04 12:25:34 +03004328 return true;
4329}
4330
Geoff Lang111a99e2017-10-17 10:58:41 -04004331bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004332{
Geoff Langc339c4e2016-11-29 10:37:36 -05004333 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004334 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004335 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004336 return false;
4337 }
4338
Geoff Lang111a99e2017-10-17 10:58:41 -04004339 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004340 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004341 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004342 return false;
4343 }
4344
4345 return true;
4346}
4347
Jamie Madill5b772312018-03-08 20:28:32 -05004348bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004349{
4350 if (texture < GL_TEXTURE0 ||
4351 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4352 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004353 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004354 return false;
4355 }
4356
4357 return true;
4358}
4359
Jamie Madill5b772312018-03-08 20:28:32 -05004360bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004361{
4362 Program *programObject = GetValidProgram(context, program);
4363 if (!programObject)
4364 {
4365 return false;
4366 }
4367
4368 Shader *shaderObject = GetValidShader(context, shader);
4369 if (!shaderObject)
4370 {
4371 return false;
4372 }
4373
Jiawei Shao385b3e02018-03-21 09:43:28 +08004374 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004375 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004376 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4377 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004378 }
4379
4380 return true;
4381}
4382
Jamie Madill5b772312018-03-08 20:28:32 -05004383bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004384{
4385 if (index >= MAX_VERTEX_ATTRIBS)
4386 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004387 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004388 return false;
4389 }
4390
4391 if (strncmp(name, "gl_", 3) == 0)
4392 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004394 return false;
4395 }
4396
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004397 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004398 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004399 const size_t length = strlen(name);
4400
4401 if (!IsValidESSLString(name, length))
4402 {
4403 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4404 // for shader-related entry points
4405 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4406 return false;
4407 }
4408
4409 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4410 {
4411 return false;
4412 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004413 }
4414
Jamie Madill01a80ee2016-11-07 12:06:18 -05004415 return GetValidProgram(context, program) != nullptr;
4416}
4417
Jamie Madill5b772312018-03-08 20:28:32 -05004418bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004419{
Corentin Walleze4477002017-12-01 14:39:58 -05004420 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004421 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004422 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004423 return false;
4424 }
4425
4426 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4427 !context->isBufferGenerated(buffer))
4428 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004429 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004430 return false;
4431 }
4432
4433 return true;
4434}
4435
Jamie Madill5b772312018-03-08 20:28:32 -05004436bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004437{
Geoff Lange8afa902017-09-27 15:00:43 -04004438 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004439 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004440 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004441 return false;
4442 }
4443
4444 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4445 !context->isFramebufferGenerated(framebuffer))
4446 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004447 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004448 return false;
4449 }
4450
4451 return true;
4452}
4453
Jamie Madill5b772312018-03-08 20:28:32 -05004454bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004455{
4456 if (target != GL_RENDERBUFFER)
4457 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004458 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004459 return false;
4460 }
4461
4462 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4463 !context->isRenderbufferGenerated(renderbuffer))
4464 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004465 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004466 return false;
4467 }
4468
4469 return true;
4470}
4471
Jamie Madill5b772312018-03-08 20:28:32 -05004472static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004473{
4474 switch (mode)
4475 {
4476 case GL_FUNC_ADD:
4477 case GL_FUNC_SUBTRACT:
4478 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004479 return true;
4480
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004481 case GL_MIN:
4482 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004483 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004484
4485 default:
4486 return false;
4487 }
4488}
4489
Jamie Madill5b772312018-03-08 20:28:32 -05004490bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004491{
4492 return true;
4493}
4494
Jamie Madill5b772312018-03-08 20:28:32 -05004495bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004496{
Geoff Lang50cac572017-09-26 17:37:43 -04004497 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004498 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004499 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004500 return false;
4501 }
4502
4503 return true;
4504}
4505
Jamie Madill5b772312018-03-08 20:28:32 -05004506bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004507{
Geoff Lang50cac572017-09-26 17:37:43 -04004508 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004509 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004510 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004511 return false;
4512 }
4513
Geoff Lang50cac572017-09-26 17:37:43 -04004514 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004515 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004516 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004517 return false;
4518 }
4519
4520 return true;
4521}
4522
Jamie Madill5b772312018-03-08 20:28:32 -05004523bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004524{
4525 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4526}
4527
4528static bool ValidSrcBlendFunc(GLenum srcBlend)
4529{
4530 switch (srcBlend)
4531 {
4532 case GL_ZERO:
4533 case GL_ONE:
4534 case GL_SRC_COLOR:
4535 case GL_ONE_MINUS_SRC_COLOR:
4536 case GL_DST_COLOR:
4537 case GL_ONE_MINUS_DST_COLOR:
4538 case GL_SRC_ALPHA:
4539 case GL_ONE_MINUS_SRC_ALPHA:
4540 case GL_DST_ALPHA:
4541 case GL_ONE_MINUS_DST_ALPHA:
4542 case GL_CONSTANT_COLOR:
4543 case GL_ONE_MINUS_CONSTANT_COLOR:
4544 case GL_CONSTANT_ALPHA:
4545 case GL_ONE_MINUS_CONSTANT_ALPHA:
4546 case GL_SRC_ALPHA_SATURATE:
4547 return true;
4548
4549 default:
4550 return false;
4551 }
4552}
4553
4554static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4555{
4556 switch (dstBlend)
4557 {
4558 case GL_ZERO:
4559 case GL_ONE:
4560 case GL_SRC_COLOR:
4561 case GL_ONE_MINUS_SRC_COLOR:
4562 case GL_DST_COLOR:
4563 case GL_ONE_MINUS_DST_COLOR:
4564 case GL_SRC_ALPHA:
4565 case GL_ONE_MINUS_SRC_ALPHA:
4566 case GL_DST_ALPHA:
4567 case GL_ONE_MINUS_DST_ALPHA:
4568 case GL_CONSTANT_COLOR:
4569 case GL_ONE_MINUS_CONSTANT_COLOR:
4570 case GL_CONSTANT_ALPHA:
4571 case GL_ONE_MINUS_CONSTANT_ALPHA:
4572 return true;
4573
4574 case GL_SRC_ALPHA_SATURATE:
4575 return (contextMajorVersion >= 3);
4576
4577 default:
4578 return false;
4579 }
4580}
4581
Jamie Madill5b772312018-03-08 20:28:32 -05004582bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004583 GLenum srcRGB,
4584 GLenum dstRGB,
4585 GLenum srcAlpha,
4586 GLenum dstAlpha)
4587{
4588 if (!ValidSrcBlendFunc(srcRGB))
4589 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004590 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004591 return false;
4592 }
4593
4594 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4595 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004596 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004597 return false;
4598 }
4599
4600 if (!ValidSrcBlendFunc(srcAlpha))
4601 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004602 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004603 return false;
4604 }
4605
4606 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4607 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004609 return false;
4610 }
4611
Frank Henigman146e8a12017-03-02 23:22:37 -05004612 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4613 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004614 {
4615 bool constantColorUsed =
4616 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4617 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4618
4619 bool constantAlphaUsed =
4620 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4621 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4622
4623 if (constantColorUsed && constantAlphaUsed)
4624 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004625 const char *msg;
4626 if (context->getExtensions().webglCompatibility)
4627 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004628 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004629 }
4630 else
4631 {
4632 msg =
4633 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4634 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4635 "implementation.";
4636 ERR() << msg;
4637 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004638 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004639 return false;
4640 }
4641 }
4642
4643 return true;
4644}
4645
Geoff Langc339c4e2016-11-29 10:37:36 -05004646bool ValidateGetString(Context *context, GLenum name)
4647{
4648 switch (name)
4649 {
4650 case GL_VENDOR:
4651 case GL_RENDERER:
4652 case GL_VERSION:
4653 case GL_SHADING_LANGUAGE_VERSION:
4654 case GL_EXTENSIONS:
4655 break;
4656
4657 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4658 if (!context->getExtensions().requestExtension)
4659 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004660 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004661 return false;
4662 }
4663 break;
4664
4665 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004666 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004667 return false;
4668 }
4669
4670 return true;
4671}
4672
Jamie Madill5b772312018-03-08 20:28:32 -05004673bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004674{
4675 if (width <= 0.0f || isNaN(width))
4676 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004677 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004678 return false;
4679 }
4680
4681 return true;
4682}
4683
Jamie Madill5b772312018-03-08 20:28:32 -05004684bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004685 GLuint index,
4686 GLint size,
4687 GLenum type,
4688 GLboolean normalized,
4689 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004690 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004691{
Shao80957d92017-02-20 21:25:59 +08004692 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004693 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004694 return false;
4695 }
4696
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004697 if (stride < 0)
4698 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004699 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004700 return false;
4701 }
4702
Shao80957d92017-02-20 21:25:59 +08004703 const Caps &caps = context->getCaps();
4704 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004705 {
Shao80957d92017-02-20 21:25:59 +08004706 if (stride > caps.maxVertexAttribStride)
4707 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004708 context->handleError(InvalidValue()
4709 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004710 return false;
4711 }
4712
4713 if (index >= caps.maxVertexAttribBindings)
4714 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004715 context->handleError(InvalidValue()
4716 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004717 return false;
4718 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004719 }
4720
4721 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4722 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4723 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4724 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004725 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4726 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004727 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4728 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004729 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004730 context
4731 ->handleError(InvalidOperation()
4732 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004733 return false;
4734 }
4735
4736 if (context->getExtensions().webglCompatibility)
4737 {
4738 // WebGL 1.0 [Section 6.14] Fixed point support
4739 // The WebGL API does not support the GL_FIXED data type.
4740 if (type == GL_FIXED)
4741 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004742 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004743 return false;
4744 }
4745
Geoff Lang2d62ab72017-03-23 16:54:40 -04004746 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004747 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004748 return false;
4749 }
4750 }
4751
4752 return true;
4753}
4754
Jamie Madill5b772312018-03-08 20:28:32 -05004755bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004756{
4757 if (context->getExtensions().webglCompatibility && zNear > zFar)
4758 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004759 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004760 return false;
4761 }
4762
4763 return true;
4764}
4765
Jamie Madill5b772312018-03-08 20:28:32 -05004766bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004767 GLenum target,
4768 GLenum internalformat,
4769 GLsizei width,
4770 GLsizei height)
4771{
4772 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4773 height);
4774}
4775
Jamie Madill5b772312018-03-08 20:28:32 -05004776bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004777 GLenum target,
4778 GLsizei samples,
4779 GLenum internalformat,
4780 GLsizei width,
4781 GLsizei height)
4782{
4783 if (!context->getExtensions().framebufferMultisample)
4784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004785 context->handleError(InvalidOperation()
4786 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004787 return false;
4788 }
4789
4790 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4791 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4792 // generated.
4793 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4794 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004795 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004796 return false;
4797 }
4798
4799 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4800 // the specified storage. This is different than ES 3.0 in which a sample number higher
4801 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4802 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4803 if (context->getClientMajorVersion() >= 3)
4804 {
4805 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4806 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4807 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004808 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004809 return false;
4810 }
4811 }
4812
4813 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4814 width, height);
4815}
4816
Jamie Madill5b772312018-03-08 20:28:32 -05004817bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004818{
Geoff Lange8afa902017-09-27 15:00:43 -04004819 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004820 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004821 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004822 return false;
4823 }
4824
4825 return true;
4826}
4827
Jamie Madill5b772312018-03-08 20:28:32 -05004828bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004829{
4830 return true;
4831}
4832
Jamie Madill5b772312018-03-08 20:28:32 -05004833bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004834{
4835 return true;
4836}
4837
Jamie Madill5b772312018-03-08 20:28:32 -05004838bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004839{
4840 return true;
4841}
4842
Jamie Madill5b772312018-03-08 20:28:32 -05004843bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004844 GLboolean red,
4845 GLboolean green,
4846 GLboolean blue,
4847 GLboolean alpha)
4848{
4849 return true;
4850}
4851
Jamie Madill5b772312018-03-08 20:28:32 -05004852bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004853{
4854 return true;
4855}
4856
Jamie Madill5b772312018-03-08 20:28:32 -05004857bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004858{
4859 return true;
4860}
4861
Jamie Madill5b772312018-03-08 20:28:32 -05004862bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004863{
4864 switch (mode)
4865 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004866 case CullFaceMode::Front:
4867 case CullFaceMode::Back:
4868 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004869 break;
4870
4871 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004872 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004873 return false;
4874 }
4875
4876 return true;
4877}
4878
Jamie Madill5b772312018-03-08 20:28:32 -05004879bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004880{
4881 if (program == 0)
4882 {
4883 return false;
4884 }
4885
4886 if (!context->getProgram(program))
4887 {
4888 if (context->getShader(program))
4889 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004890 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004891 return false;
4892 }
4893 else
4894 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004895 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004896 return false;
4897 }
4898 }
4899
4900 return true;
4901}
4902
Jamie Madill5b772312018-03-08 20:28:32 -05004903bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004904{
4905 if (shader == 0)
4906 {
4907 return false;
4908 }
4909
4910 if (!context->getShader(shader))
4911 {
4912 if (context->getProgram(shader))
4913 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004914 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004915 return false;
4916 }
4917 else
4918 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004919 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004920 return false;
4921 }
4922 }
4923
4924 return true;
4925}
4926
Jamie Madill5b772312018-03-08 20:28:32 -05004927bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004928{
4929 switch (func)
4930 {
4931 case GL_NEVER:
4932 case GL_ALWAYS:
4933 case GL_LESS:
4934 case GL_LEQUAL:
4935 case GL_EQUAL:
4936 case GL_GREATER:
4937 case GL_GEQUAL:
4938 case GL_NOTEQUAL:
4939 break;
4940
4941 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004942 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004943 return false;
4944 }
4945
4946 return true;
4947}
4948
Jamie Madill5b772312018-03-08 20:28:32 -05004949bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004950{
4951 return true;
4952}
4953
Jamie Madill5b772312018-03-08 20:28:32 -05004954bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004955{
4956 Program *programObject = GetValidProgram(context, program);
4957 if (!programObject)
4958 {
4959 return false;
4960 }
4961
4962 Shader *shaderObject = GetValidShader(context, shader);
4963 if (!shaderObject)
4964 {
4965 return false;
4966 }
4967
Jiawei Shao385b3e02018-03-21 09:43:28 +08004968 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004969 if (attachedShader != shaderObject)
4970 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004971 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004972 return false;
4973 }
4974
4975 return true;
4976}
4977
Jamie Madill5b772312018-03-08 20:28:32 -05004978bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004979{
4980 if (index >= MAX_VERTEX_ATTRIBS)
4981 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004982 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004983 return false;
4984 }
4985
4986 return true;
4987}
4988
Jamie Madill5b772312018-03-08 20:28:32 -05004989bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004990{
4991 if (index >= MAX_VERTEX_ATTRIBS)
4992 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004993 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004994 return false;
4995 }
4996
4997 return true;
4998}
4999
Jamie Madill5b772312018-03-08 20:28:32 -05005000bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005001{
5002 return true;
5003}
5004
Jamie Madill5b772312018-03-08 20:28:32 -05005005bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005006{
5007 return true;
5008}
5009
Jamie Madill5b772312018-03-08 20:28:32 -05005010bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005011{
5012 switch (mode)
5013 {
5014 case GL_CW:
5015 case GL_CCW:
5016 break;
5017 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005018 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005019 return false;
5020 }
5021
5022 return true;
5023}
5024
Jamie Madill5b772312018-03-08 20:28:32 -05005025bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005026 GLuint program,
5027 GLuint index,
5028 GLsizei bufsize,
5029 GLsizei *length,
5030 GLint *size,
5031 GLenum *type,
5032 GLchar *name)
5033{
5034 if (bufsize < 0)
5035 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005036 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005037 return false;
5038 }
5039
5040 Program *programObject = GetValidProgram(context, program);
5041
5042 if (!programObject)
5043 {
5044 return false;
5045 }
5046
5047 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5048 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005049 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005050 return false;
5051 }
5052
5053 return true;
5054}
5055
Jamie Madill5b772312018-03-08 20:28:32 -05005056bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005057 GLuint program,
5058 GLuint index,
5059 GLsizei bufsize,
5060 GLsizei *length,
5061 GLint *size,
5062 GLenum *type,
5063 GLchar *name)
5064{
5065 if (bufsize < 0)
5066 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005067 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005068 return false;
5069 }
5070
5071 Program *programObject = GetValidProgram(context, program);
5072
5073 if (!programObject)
5074 {
5075 return false;
5076 }
5077
5078 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5079 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005080 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005081 return false;
5082 }
5083
5084 return true;
5085}
5086
Jamie Madill5b772312018-03-08 20:28:32 -05005087bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005088 GLuint program,
5089 GLsizei maxcount,
5090 GLsizei *count,
5091 GLuint *shaders)
5092{
5093 if (maxcount < 0)
5094 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005095 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005096 return false;
5097 }
5098
5099 Program *programObject = GetValidProgram(context, program);
5100
5101 if (!programObject)
5102 {
5103 return false;
5104 }
5105
5106 return true;
5107}
5108
Jamie Madill5b772312018-03-08 20:28:32 -05005109bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005111 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5112 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005113 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005114 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005115 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005116 return false;
5117 }
5118
Jamie Madillc1d770e2017-04-13 17:31:24 -04005119 Program *programObject = GetValidProgram(context, program);
5120
5121 if (!programObject)
5122 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005123 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005124 return false;
5125 }
5126
5127 if (!programObject->isLinked())
5128 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005129 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005130 return false;
5131 }
5132
5133 return true;
5134}
5135
Jamie Madill5b772312018-03-08 20:28:32 -05005136bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005137{
5138 GLenum nativeType;
5139 unsigned int numParams = 0;
5140 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5141}
5142
Jamie Madill5b772312018-03-08 20:28:32 -05005143bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005144{
5145 return true;
5146}
5147
Jamie Madill5b772312018-03-08 20:28:32 -05005148bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149{
5150 GLenum nativeType;
5151 unsigned int numParams = 0;
5152 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5153}
5154
Jamie Madill5b772312018-03-08 20:28:32 -05005155bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005156{
5157 GLenum nativeType;
5158 unsigned int numParams = 0;
5159 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5160}
5161
Jamie Madill5b772312018-03-08 20:28:32 -05005162bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005163 GLuint program,
5164 GLsizei bufsize,
5165 GLsizei *length,
5166 GLchar *infolog)
5167{
5168 if (bufsize < 0)
5169 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005170 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005171 return false;
5172 }
5173
5174 Program *programObject = GetValidProgram(context, program);
5175 if (!programObject)
5176 {
5177 return false;
5178 }
5179
5180 return true;
5181}
5182
Jamie Madill5b772312018-03-08 20:28:32 -05005183bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005184 GLuint shader,
5185 GLsizei bufsize,
5186 GLsizei *length,
5187 GLchar *infolog)
5188{
5189 if (bufsize < 0)
5190 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005191 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005192 return false;
5193 }
5194
5195 Shader *shaderObject = GetValidShader(context, shader);
5196 if (!shaderObject)
5197 {
5198 return false;
5199 }
5200
5201 return true;
5202}
5203
Jamie Madill5b772312018-03-08 20:28:32 -05005204bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005205 GLenum shadertype,
5206 GLenum precisiontype,
5207 GLint *range,
5208 GLint *precision)
5209{
5210 switch (shadertype)
5211 {
5212 case GL_VERTEX_SHADER:
5213 case GL_FRAGMENT_SHADER:
5214 break;
5215 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005216 context->handleError(InvalidOperation()
5217 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005218 return false;
5219 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005220 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005221 return false;
5222 }
5223
5224 switch (precisiontype)
5225 {
5226 case GL_LOW_FLOAT:
5227 case GL_MEDIUM_FLOAT:
5228 case GL_HIGH_FLOAT:
5229 case GL_LOW_INT:
5230 case GL_MEDIUM_INT:
5231 case GL_HIGH_INT:
5232 break;
5233
5234 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005235 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005236 return false;
5237 }
5238
5239 return true;
5240}
5241
Jamie Madill5b772312018-03-08 20:28:32 -05005242bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005243 GLuint shader,
5244 GLsizei bufsize,
5245 GLsizei *length,
5246 GLchar *source)
5247{
5248 if (bufsize < 0)
5249 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005250 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005251 return false;
5252 }
5253
5254 Shader *shaderObject = GetValidShader(context, shader);
5255 if (!shaderObject)
5256 {
5257 return false;
5258 }
5259
5260 return true;
5261}
5262
Jamie Madill5b772312018-03-08 20:28:32 -05005263bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005264{
5265 if (strstr(name, "gl_") == name)
5266 {
5267 return false;
5268 }
5269
Geoff Langfc32e8b2017-05-31 14:16:59 -04005270 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5271 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005272 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005273 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005274 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005275 return false;
5276 }
5277
Jamie Madillc1d770e2017-04-13 17:31:24 -04005278 Program *programObject = GetValidProgram(context, program);
5279
5280 if (!programObject)
5281 {
5282 return false;
5283 }
5284
5285 if (!programObject->isLinked())
5286 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005287 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005288 return false;
5289 }
5290
5291 return true;
5292}
5293
Jamie Madill5b772312018-03-08 20:28:32 -05005294bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005295{
5296 switch (mode)
5297 {
5298 case GL_FASTEST:
5299 case GL_NICEST:
5300 case GL_DONT_CARE:
5301 break;
5302
5303 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005304 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005305 return false;
5306 }
5307
5308 switch (target)
5309 {
5310 case GL_GENERATE_MIPMAP_HINT:
5311 break;
5312
Geoff Lange7bd2182017-06-16 16:13:13 -04005313 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5314 if (context->getClientVersion() < ES_3_0 &&
5315 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005316 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005317 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005318 return false;
5319 }
5320 break;
5321
5322 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005323 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005324 return false;
5325 }
5326
5327 return true;
5328}
5329
Jamie Madill5b772312018-03-08 20:28:32 -05005330bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005331{
5332 return true;
5333}
5334
Jamie Madill5b772312018-03-08 20:28:32 -05005335bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005336{
5337 return true;
5338}
5339
Jamie Madill5b772312018-03-08 20:28:32 -05005340bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005341{
5342 return true;
5343}
5344
Jamie Madill5b772312018-03-08 20:28:32 -05005345bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005346{
5347 return true;
5348}
5349
Jamie Madill5b772312018-03-08 20:28:32 -05005350bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005351{
5352 return true;
5353}
5354
Jamie Madill5b772312018-03-08 20:28:32 -05005355bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005356{
5357 return true;
5358}
5359
Jamie Madill5b772312018-03-08 20:28:32 -05005360bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005361{
5362 if (context->getClientMajorVersion() < 3)
5363 {
5364 switch (pname)
5365 {
5366 case GL_UNPACK_IMAGE_HEIGHT:
5367 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005368 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005369 return false;
5370
5371 case GL_UNPACK_ROW_LENGTH:
5372 case GL_UNPACK_SKIP_ROWS:
5373 case GL_UNPACK_SKIP_PIXELS:
5374 if (!context->getExtensions().unpackSubimage)
5375 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005376 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005377 return false;
5378 }
5379 break;
5380
5381 case GL_PACK_ROW_LENGTH:
5382 case GL_PACK_SKIP_ROWS:
5383 case GL_PACK_SKIP_PIXELS:
5384 if (!context->getExtensions().packSubimage)
5385 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005386 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005387 return false;
5388 }
5389 break;
5390 }
5391 }
5392
5393 if (param < 0)
5394 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005395 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005396 return false;
5397 }
5398
5399 switch (pname)
5400 {
5401 case GL_UNPACK_ALIGNMENT:
5402 if (param != 1 && param != 2 && param != 4 && param != 8)
5403 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005404 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005405 return false;
5406 }
5407 break;
5408
5409 case GL_PACK_ALIGNMENT:
5410 if (param != 1 && param != 2 && param != 4 && param != 8)
5411 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005412 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005413 return false;
5414 }
5415 break;
5416
5417 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005418 if (!context->getExtensions().packReverseRowOrder)
5419 {
5420 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5421 }
5422 break;
5423
Jamie Madillc1d770e2017-04-13 17:31:24 -04005424 case GL_UNPACK_ROW_LENGTH:
5425 case GL_UNPACK_IMAGE_HEIGHT:
5426 case GL_UNPACK_SKIP_IMAGES:
5427 case GL_UNPACK_SKIP_ROWS:
5428 case GL_UNPACK_SKIP_PIXELS:
5429 case GL_PACK_ROW_LENGTH:
5430 case GL_PACK_SKIP_ROWS:
5431 case GL_PACK_SKIP_PIXELS:
5432 break;
5433
5434 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005435 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005436 return false;
5437 }
5438
5439 return true;
5440}
5441
Jamie Madill5b772312018-03-08 20:28:32 -05005442bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005443{
5444 return true;
5445}
5446
Jamie Madill5b772312018-03-08 20:28:32 -05005447bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005448{
5449 return true;
5450}
5451
Jamie Madill5b772312018-03-08 20:28:32 -05005452bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005453{
5454 return true;
5455}
5456
Jamie Madill5b772312018-03-08 20:28:32 -05005457bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005458{
5459 if (width < 0 || height < 0)
5460 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005461 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005462 return false;
5463 }
5464
5465 return true;
5466}
5467
Jamie Madill5b772312018-03-08 20:28:32 -05005468bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005469 GLsizei n,
5470 const GLuint *shaders,
5471 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005472 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005473 GLsizei length)
5474{
5475 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5476 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5477 shaderBinaryFormats.end())
5478 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005479 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005480 return false;
5481 }
5482
5483 return true;
5484}
5485
Jamie Madill5b772312018-03-08 20:28:32 -05005486bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005487 GLuint shader,
5488 GLsizei count,
5489 const GLchar *const *string,
5490 const GLint *length)
5491{
5492 if (count < 0)
5493 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005494 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005495 return false;
5496 }
5497
Geoff Langfc32e8b2017-05-31 14:16:59 -04005498 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5499 // shader-related entry points
5500 if (context->getExtensions().webglCompatibility)
5501 {
5502 for (GLsizei i = 0; i < count; i++)
5503 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005504 size_t len =
5505 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005506
5507 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005508 if (!IsValidESSLShaderSourceString(string[i], len,
5509 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005510 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005511 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005512 return false;
5513 }
5514 }
5515 }
5516
Jamie Madillc1d770e2017-04-13 17:31:24 -04005517 Shader *shaderObject = GetValidShader(context, shader);
5518 if (!shaderObject)
5519 {
5520 return false;
5521 }
5522
5523 return true;
5524}
5525
Jamie Madill5b772312018-03-08 20:28:32 -05005526bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005527{
5528 if (!IsValidStencilFunc(func))
5529 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005530 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005531 return false;
5532 }
5533
5534 return true;
5535}
5536
Jamie Madill5b772312018-03-08 20:28:32 -05005537bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005538{
5539 if (!IsValidStencilFace(face))
5540 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005541 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005542 return false;
5543 }
5544
5545 if (!IsValidStencilFunc(func))
5546 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005547 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005548 return false;
5549 }
5550
5551 return true;
5552}
5553
Jamie Madill5b772312018-03-08 20:28:32 -05005554bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005555{
5556 return true;
5557}
5558
Jamie Madill5b772312018-03-08 20:28:32 -05005559bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005560{
5561 if (!IsValidStencilFace(face))
5562 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005563 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005564 return false;
5565 }
5566
5567 return true;
5568}
5569
Jamie Madill5b772312018-03-08 20:28:32 -05005570bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005571{
5572 if (!IsValidStencilOp(fail))
5573 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005574 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005575 return false;
5576 }
5577
5578 if (!IsValidStencilOp(zfail))
5579 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005580 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005581 return false;
5582 }
5583
5584 if (!IsValidStencilOp(zpass))
5585 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005586 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005587 return false;
5588 }
5589
5590 return true;
5591}
5592
Jamie Madill5b772312018-03-08 20:28:32 -05005593bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005594 GLenum face,
5595 GLenum fail,
5596 GLenum zfail,
5597 GLenum zpass)
5598{
5599 if (!IsValidStencilFace(face))
5600 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602 return false;
5603 }
5604
5605 return ValidateStencilOp(context, fail, zfail, zpass);
5606}
5607
Jamie Madill5b772312018-03-08 20:28:32 -05005608bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005609{
5610 return ValidateUniform(context, GL_FLOAT, location, 1);
5611}
5612
Jamie Madill5b772312018-03-08 20:28:32 -05005613bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005614{
5615 return ValidateUniform(context, GL_FLOAT, location, count);
5616}
5617
Jamie Madill5b772312018-03-08 20:28:32 -05005618bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005619{
5620 return ValidateUniform1iv(context, location, 1, &x);
5621}
5622
Jamie Madill5b772312018-03-08 20:28:32 -05005623bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005624{
5625 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5626}
5627
Jamie Madill5b772312018-03-08 20:28:32 -05005628bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629{
5630 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5631}
5632
Jamie Madill5b772312018-03-08 20:28:32 -05005633bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005634{
5635 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5636}
5637
Jamie Madill5b772312018-03-08 20:28:32 -05005638bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005639{
5640 return ValidateUniform(context, GL_INT_VEC2, location, count);
5641}
5642
Jamie Madill5b772312018-03-08 20:28:32 -05005643bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005644{
5645 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5646}
5647
Jamie Madill5b772312018-03-08 20:28:32 -05005648bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005649{
5650 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5651}
5652
Jamie Madill5b772312018-03-08 20:28:32 -05005653bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005654{
5655 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5656}
5657
Jamie Madill5b772312018-03-08 20:28:32 -05005658bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005659{
5660 return ValidateUniform(context, GL_INT_VEC3, location, count);
5661}
5662
Jamie Madill5b772312018-03-08 20:28:32 -05005663bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005664{
5665 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5666}
5667
Jamie Madill5b772312018-03-08 20:28:32 -05005668bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005669{
5670 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5671}
5672
Jamie Madill5b772312018-03-08 20:28:32 -05005673bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005674{
5675 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5676}
5677
Jamie Madill5b772312018-03-08 20:28:32 -05005678bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005679{
5680 return ValidateUniform(context, GL_INT_VEC4, location, count);
5681}
5682
Jamie Madill5b772312018-03-08 20:28:32 -05005683bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005684 GLint location,
5685 GLsizei count,
5686 GLboolean transpose,
5687 const GLfloat *value)
5688{
5689 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5690}
5691
Jamie Madill5b772312018-03-08 20:28:32 -05005692bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005693 GLint location,
5694 GLsizei count,
5695 GLboolean transpose,
5696 const GLfloat *value)
5697{
5698 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5699}
5700
Jamie Madill5b772312018-03-08 20:28:32 -05005701bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005702 GLint location,
5703 GLsizei count,
5704 GLboolean transpose,
5705 const GLfloat *value)
5706{
5707 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5708}
5709
Jamie Madill5b772312018-03-08 20:28:32 -05005710bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005711{
5712 Program *programObject = GetValidProgram(context, program);
5713
5714 if (!programObject)
5715 {
5716 return false;
5717 }
5718
5719 return true;
5720}
5721
Jamie Madill5b772312018-03-08 20:28:32 -05005722bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005723{
5724 return ValidateVertexAttribIndex(context, index);
5725}
5726
Jamie Madill5b772312018-03-08 20:28:32 -05005727bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005728{
5729 return ValidateVertexAttribIndex(context, index);
5730}
5731
Jamie Madill5b772312018-03-08 20:28:32 -05005732bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005733{
5734 return ValidateVertexAttribIndex(context, index);
5735}
5736
Jamie Madill5b772312018-03-08 20:28:32 -05005737bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005738{
5739 return ValidateVertexAttribIndex(context, index);
5740}
5741
Jamie Madill5b772312018-03-08 20:28:32 -05005742bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005743{
5744 return ValidateVertexAttribIndex(context, index);
5745}
5746
Jamie Madill5b772312018-03-08 20:28:32 -05005747bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005748{
5749 return ValidateVertexAttribIndex(context, index);
5750}
5751
Jamie Madill5b772312018-03-08 20:28:32 -05005752bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005753 GLuint index,
5754 GLfloat x,
5755 GLfloat y,
5756 GLfloat z,
5757 GLfloat w)
5758{
5759 return ValidateVertexAttribIndex(context, index);
5760}
5761
Jamie Madill5b772312018-03-08 20:28:32 -05005762bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005763{
5764 return ValidateVertexAttribIndex(context, index);
5765}
5766
Jamie Madill5b772312018-03-08 20:28:32 -05005767bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005768{
5769 if (width < 0 || height < 0)
5770 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005771 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005772 return false;
5773 }
5774
5775 return true;
5776}
5777
Jamie Madill5b772312018-03-08 20:28:32 -05005778bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005779{
5780 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5781}
5782
Jamie Madill5b772312018-03-08 20:28:32 -05005783bool ValidateDrawElements(Context *context,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005784 GLenum mode,
5785 GLsizei count,
5786 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005787 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005788{
5789 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5790}
5791
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005792bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005793 GLenum target,
5794 GLenum attachment,
5795 GLenum pname,
5796 GLint *params)
5797{
5798 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5799 nullptr);
5800}
5801
Jamie Madill5b772312018-03-08 20:28:32 -05005802bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005803{
5804 return ValidateGetProgramivBase(context, program, pname, nullptr);
5805}
5806
Jamie Madill5b772312018-03-08 20:28:32 -05005807bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005808 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005809 GLint level,
5810 GLenum internalformat,
5811 GLint x,
5812 GLint y,
5813 GLsizei width,
5814 GLsizei height,
5815 GLint border)
5816{
5817 if (context->getClientMajorVersion() < 3)
5818 {
5819 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5820 0, x, y, width, height, border);
5821 }
5822
5823 ASSERT(context->getClientMajorVersion() == 3);
5824 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5825 0, x, y, width, height, border);
5826}
5827
5828bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005829 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005830 GLint level,
5831 GLint xoffset,
5832 GLint yoffset,
5833 GLint x,
5834 GLint y,
5835 GLsizei width,
5836 GLsizei height)
5837{
5838 if (context->getClientMajorVersion() < 3)
5839 {
5840 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5841 yoffset, x, y, width, height, 0);
5842 }
5843
5844 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5845 yoffset, 0, x, y, width, height, 0);
5846}
5847
5848bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5849{
5850 return ValidateGenOrDelete(context, n);
5851}
5852
5853bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5854{
5855 return ValidateGenOrDelete(context, n);
5856}
5857
5858bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5859{
5860 return ValidateGenOrDelete(context, n);
5861}
5862
5863bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5864{
5865 return ValidateGenOrDelete(context, n);
5866}
5867
5868bool ValidateDisable(Context *context, GLenum cap)
5869{
5870 if (!ValidCap(context, cap, false))
5871 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005872 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005873 return false;
5874 }
5875
5876 return true;
5877}
5878
5879bool ValidateEnable(Context *context, GLenum cap)
5880{
5881 if (!ValidCap(context, cap, false))
5882 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005883 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005884 return false;
5885 }
5886
5887 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5888 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5889 {
5890 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005891 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005892
5893 // We also output an error message to the debugger window if tracing is active, so that
5894 // developers can see the error message.
5895 ERR() << errorMessage;
5896 return false;
5897 }
5898
5899 return true;
5900}
5901
5902bool ValidateFramebufferRenderbuffer(Context *context,
5903 GLenum target,
5904 GLenum attachment,
5905 GLenum renderbuffertarget,
5906 GLuint renderbuffer)
5907{
Geoff Lange8afa902017-09-27 15:00:43 -04005908 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005909 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005910 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5911 return false;
5912 }
5913
5914 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5915 {
5916 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005917 return false;
5918 }
5919
5920 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5921 renderbuffertarget, renderbuffer);
5922}
5923
5924bool ValidateFramebufferTexture2D(Context *context,
5925 GLenum target,
5926 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005927 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005928 GLuint texture,
5929 GLint level)
5930{
5931 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5932 // extension
5933 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5934 level != 0)
5935 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005936 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005937 return false;
5938 }
5939
5940 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5941 {
5942 return false;
5943 }
5944
5945 if (texture != 0)
5946 {
5947 gl::Texture *tex = context->getTexture(texture);
5948 ASSERT(tex);
5949
5950 const gl::Caps &caps = context->getCaps();
5951
5952 switch (textarget)
5953 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005954 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005955 {
5956 if (level > gl::log2(caps.max2DTextureSize))
5957 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005958 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005959 return false;
5960 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005961 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005962 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005963 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005964 return false;
5965 }
5966 }
5967 break;
5968
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005969 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005970 {
5971 if (level != 0)
5972 {
5973 context->handleError(InvalidValue());
5974 return false;
5975 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005976 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005977 {
5978 context->handleError(InvalidOperation()
5979 << "Textarget must match the texture target type.");
5980 return false;
5981 }
5982 }
5983 break;
5984
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005985 case TextureTarget::CubeMapNegativeX:
5986 case TextureTarget::CubeMapNegativeY:
5987 case TextureTarget::CubeMapNegativeZ:
5988 case TextureTarget::CubeMapPositiveX:
5989 case TextureTarget::CubeMapPositiveY:
5990 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005991 {
5992 if (level > gl::log2(caps.maxCubeMapTextureSize))
5993 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005994 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005995 return false;
5996 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005997 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04005998 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005999 context->handleError(InvalidOperation()
6000 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006001 return false;
6002 }
6003 }
6004 break;
6005
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006006 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006007 {
6008 if (context->getClientVersion() < ES_3_1)
6009 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006010 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006011 return false;
6012 }
6013
6014 if (level != 0)
6015 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006016 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006017 return false;
6018 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006019 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006021 context->handleError(InvalidOperation()
6022 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006023 return false;
6024 }
6025 }
6026 break;
6027
6028 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006029 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006030 return false;
6031 }
6032
6033 const Format &format = tex->getFormat(textarget, level);
6034 if (format.info->compressed)
6035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006036 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 return false;
6038 }
6039 }
6040
6041 return true;
6042}
6043
6044bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6045{
6046 return ValidateGenOrDelete(context, n);
6047}
6048
6049bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6050{
6051 return ValidateGenOrDelete(context, n);
6052}
6053
6054bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6055{
6056 return ValidateGenOrDelete(context, n);
6057}
6058
6059bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6060{
6061 return ValidateGenOrDelete(context, n);
6062}
6063
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006064bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006065{
6066 if (!ValidTextureTarget(context, target))
6067 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006068 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006069 return false;
6070 }
6071
6072 Texture *texture = context->getTargetTexture(target);
6073
6074 if (texture == nullptr)
6075 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006076 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006077 return false;
6078 }
6079
6080 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6081
6082 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6083 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6084 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6085 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006086 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006087 return false;
6088 }
6089
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006090 TextureTarget baseTarget = (target == TextureType::CubeMap)
6091 ? TextureTarget::CubeMapPositiveX
6092 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006093 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6094 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6095 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006096 {
6097 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6098 return false;
6099 }
6100
Geoff Lang536eca12017-09-13 11:23:35 -04006101 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6102 bool formatUnsized = !format.sized;
6103 bool formatColorRenderableAndFilterable =
6104 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6105 format.renderSupport(context->getClientVersion(), context->getExtensions());
6106 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006107 {
Geoff Lang536eca12017-09-13 11:23:35 -04006108 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006109 return false;
6110 }
6111
Geoff Lang536eca12017-09-13 11:23:35 -04006112 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6113 // generation
6114 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6115 {
6116 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6117 return false;
6118 }
6119
6120 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6121 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006122 bool supportsSRGBMipmapGeneration =
6123 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006124 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006125 {
Geoff Lang536eca12017-09-13 11:23:35 -04006126 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006127 return false;
6128 }
6129
6130 // Non-power of 2 ES2 check
6131 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6132 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6133 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6134 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006135 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6136 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006137 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006138 return false;
6139 }
6140
6141 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006142 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006145 return false;
6146 }
6147
6148 return true;
6149}
6150
Jamie Madill5b772312018-03-08 20:28:32 -05006151bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006152 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006153 GLenum pname,
6154 GLint *params)
6155{
6156 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6157}
6158
6159bool ValidateGetRenderbufferParameteriv(Context *context,
6160 GLenum target,
6161 GLenum pname,
6162 GLint *params)
6163{
6164 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6165}
6166
6167bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6168{
6169 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6170}
6171
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006172bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006173{
6174 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6175}
6176
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006177bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006178{
6179 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6180}
6181
6182bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6183{
6184 return ValidateGetUniformBase(context, program, location);
6185}
6186
6187bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6188{
6189 return ValidateGetUniformBase(context, program, location);
6190}
6191
6192bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6193{
6194 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6195}
6196
6197bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6198{
6199 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6200}
6201
6202bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6203{
6204 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6205}
6206
6207bool ValidateIsEnabled(Context *context, GLenum cap)
6208{
6209 if (!ValidCap(context, cap, true))
6210 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006211 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006212 return false;
6213 }
6214
6215 return true;
6216}
6217
6218bool ValidateLinkProgram(Context *context, GLuint program)
6219{
6220 if (context->hasActiveTransformFeedback(program))
6221 {
6222 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006223 context->handleError(InvalidOperation() << "Cannot link program while program is "
6224 "associated with an active transform "
6225 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006226 return false;
6227 }
6228
6229 Program *programObject = GetValidProgram(context, program);
6230 if (!programObject)
6231 {
6232 return false;
6233 }
6234
6235 return true;
6236}
6237
Jamie Madill4928b7c2017-06-20 12:57:39 -04006238bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006239 GLint x,
6240 GLint y,
6241 GLsizei width,
6242 GLsizei height,
6243 GLenum format,
6244 GLenum type,
6245 void *pixels)
6246{
6247 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6248 nullptr, pixels);
6249}
6250
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006251bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006252{
6253 return ValidateTexParameterBase(context, target, pname, -1, &param);
6254}
6255
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006256bool ValidateTexParameterfv(Context *context,
6257 TextureType target,
6258 GLenum pname,
6259 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006260{
6261 return ValidateTexParameterBase(context, target, pname, -1, params);
6262}
6263
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006264bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006265{
6266 return ValidateTexParameterBase(context, target, pname, -1, &param);
6267}
6268
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006269bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006270{
6271 return ValidateTexParameterBase(context, target, pname, -1, params);
6272}
6273
6274bool ValidateUseProgram(Context *context, GLuint program)
6275{
6276 if (program != 0)
6277 {
6278 Program *programObject = context->getProgram(program);
6279 if (!programObject)
6280 {
6281 // ES 3.1.0 section 7.3 page 72
6282 if (context->getShader(program))
6283 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006284 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006285 return false;
6286 }
6287 else
6288 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006289 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006290 return false;
6291 }
6292 }
6293 if (!programObject->isLinked())
6294 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006296 return false;
6297 }
6298 }
6299 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6300 {
6301 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006302 context
6303 ->handleError(InvalidOperation()
6304 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006305 return false;
6306 }
6307
6308 return true;
6309}
6310
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006311bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6312{
6313 if (!context->getExtensions().fence)
6314 {
6315 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6316 return false;
6317 }
6318
6319 if (n < 0)
6320 {
6321 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6322 return false;
6323 }
6324
6325 return true;
6326}
6327
6328bool ValidateFinishFenceNV(Context *context, GLuint fence)
6329{
6330 if (!context->getExtensions().fence)
6331 {
6332 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6333 return false;
6334 }
6335
6336 FenceNV *fenceObject = context->getFenceNV(fence);
6337
6338 if (fenceObject == nullptr)
6339 {
6340 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6341 return false;
6342 }
6343
6344 if (!fenceObject->isSet())
6345 {
6346 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6347 return false;
6348 }
6349
6350 return true;
6351}
6352
6353bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6354{
6355 if (!context->getExtensions().fence)
6356 {
6357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6358 return false;
6359 }
6360
6361 if (n < 0)
6362 {
6363 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6364 return false;
6365 }
6366
6367 return true;
6368}
6369
6370bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6371{
6372 if (!context->getExtensions().fence)
6373 {
6374 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6375 return false;
6376 }
6377
6378 FenceNV *fenceObject = context->getFenceNV(fence);
6379
6380 if (fenceObject == nullptr)
6381 {
6382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6383 return false;
6384 }
6385
6386 if (!fenceObject->isSet())
6387 {
6388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6389 return false;
6390 }
6391
6392 switch (pname)
6393 {
6394 case GL_FENCE_STATUS_NV:
6395 case GL_FENCE_CONDITION_NV:
6396 break;
6397
6398 default:
6399 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6400 return false;
6401 }
6402
6403 return true;
6404}
6405
6406bool ValidateGetGraphicsResetStatusEXT(Context *context)
6407{
6408 if (!context->getExtensions().robustness)
6409 {
6410 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6411 return false;
6412 }
6413
6414 return true;
6415}
6416
6417bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6418 GLuint shader,
6419 GLsizei bufsize,
6420 GLsizei *length,
6421 GLchar *source)
6422{
6423 if (!context->getExtensions().translatedShaderSource)
6424 {
6425 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6426 return false;
6427 }
6428
6429 if (bufsize < 0)
6430 {
6431 context->handleError(InvalidValue());
6432 return false;
6433 }
6434
6435 Shader *shaderObject = context->getShader(shader);
6436
6437 if (!shaderObject)
6438 {
6439 context->handleError(InvalidOperation());
6440 return false;
6441 }
6442
6443 return true;
6444}
6445
6446bool ValidateIsFenceNV(Context *context, GLuint fence)
6447{
6448 if (!context->getExtensions().fence)
6449 {
6450 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6451 return false;
6452 }
6453
6454 return true;
6455}
6456
Jamie Madill007530e2017-12-28 14:27:04 -05006457bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6458{
6459 if (!context->getExtensions().fence)
6460 {
6461 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6462 return false;
6463 }
6464
6465 if (condition != GL_ALL_COMPLETED_NV)
6466 {
6467 context->handleError(InvalidEnum());
6468 return false;
6469 }
6470
6471 FenceNV *fenceObject = context->getFenceNV(fence);
6472
6473 if (fenceObject == nullptr)
6474 {
6475 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6476 return false;
6477 }
6478
6479 return true;
6480}
6481
6482bool ValidateTestFenceNV(Context *context, GLuint fence)
6483{
6484 if (!context->getExtensions().fence)
6485 {
6486 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6487 return false;
6488 }
6489
6490 FenceNV *fenceObject = context->getFenceNV(fence);
6491
6492 if (fenceObject == nullptr)
6493 {
6494 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6495 return false;
6496 }
6497
6498 if (fenceObject->isSet() != GL_TRUE)
6499 {
6500 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6501 return false;
6502 }
6503
6504 return true;
6505}
6506
6507bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006508 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006509 GLsizei levels,
6510 GLenum internalformat,
6511 GLsizei width,
6512 GLsizei height)
6513{
6514 if (!context->getExtensions().textureStorage)
6515 {
6516 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6517 return false;
6518 }
6519
6520 if (context->getClientMajorVersion() < 3)
6521 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006522 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006523 height);
6524 }
6525
6526 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006527 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006528 1);
6529}
6530
6531bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6532{
6533 if (!context->getExtensions().instancedArrays)
6534 {
6535 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6536 return false;
6537 }
6538
6539 if (index >= MAX_VERTEX_ATTRIBS)
6540 {
6541 context->handleError(InvalidValue());
6542 return false;
6543 }
6544
6545 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6546 {
6547 if (index == 0 && divisor != 0)
6548 {
6549 const char *errorMessage =
6550 "The current context doesn't support setting a non-zero divisor on the "
6551 "attribute with index zero. "
6552 "Please reorder the attributes in your vertex shader so that attribute zero "
6553 "can have a zero divisor.";
6554 context->handleError(InvalidOperation() << errorMessage);
6555
6556 // We also output an error message to the debugger window if tracing is active, so
6557 // that developers can see the error message.
6558 ERR() << errorMessage;
6559 return false;
6560 }
6561 }
6562
6563 return true;
6564}
6565
6566bool ValidateTexImage3DOES(Context *context,
6567 GLenum target,
6568 GLint level,
6569 GLenum internalformat,
6570 GLsizei width,
6571 GLsizei height,
6572 GLsizei depth,
6573 GLint border,
6574 GLenum format,
6575 GLenum type,
6576 const void *pixels)
6577{
6578 UNIMPLEMENTED(); // FIXME
6579 return false;
6580}
6581
6582bool ValidatePopGroupMarkerEXT(Context *context)
6583{
6584 if (!context->getExtensions().debugMarker)
6585 {
6586 // The debug marker calls should not set error state
6587 // However, it seems reasonable to set an error state if the extension is not enabled
6588 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6589 return false;
6590 }
6591
6592 return true;
6593}
6594
Jamie Madillfa920eb2018-01-04 11:45:50 -05006595bool ValidateTexStorage1DEXT(Context *context,
6596 GLenum target,
6597 GLsizei levels,
6598 GLenum internalformat,
6599 GLsizei width)
6600{
6601 UNIMPLEMENTED();
6602 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6603 return false;
6604}
6605
6606bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006607 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006608 GLsizei levels,
6609 GLenum internalformat,
6610 GLsizei width,
6611 GLsizei height,
6612 GLsizei depth)
6613{
6614 if (!context->getExtensions().textureStorage)
6615 {
6616 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6617 return false;
6618 }
6619
6620 if (context->getClientMajorVersion() < 3)
6621 {
6622 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6623 return false;
6624 }
6625
6626 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6627 depth);
6628}
6629
Jamie Madillc29968b2016-01-20 11:17:23 -05006630} // namespace gl