blob: 8146679c731499ff637ce5f6e94e2c8d43085137 [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
Jamie Madill007530e2017-12-28 14:27:04 -05003486bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003487{
3488 if (!context->getExtensions().pathRendering)
3489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003490 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003491 return false;
3492 }
3493 if (context->hasPath(path) && !context->hasPathData(path))
3494 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003495 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003496 return false;
3497 }
3498
3499 switch (coverMode)
3500 {
3501 case GL_CONVEX_HULL_CHROMIUM:
3502 case GL_BOUNDING_BOX_CHROMIUM:
3503 break;
3504 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003505 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003506 return false;
3507 }
3508 return true;
3509}
3510
Jamie Madill007530e2017-12-28 14:27:04 -05003511bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3512 GLuint path,
3513 GLenum fillMode,
3514 GLuint mask,
3515 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003516{
Jamie Madill007530e2017-12-28 14:27:04 -05003517 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3518 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003519}
3520
Jamie Madill007530e2017-12-28 14:27:04 -05003521bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3522 GLuint path,
3523 GLint reference,
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 ValidateStencilStrokePathCHROMIUM(context, path, reference, 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 ValidateIsPathCHROMIUM(Context *context)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003532{
3533 if (!context->getExtensions().pathRendering)
3534 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003535 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003536 return false;
3537 }
3538 return true;
3539}
3540
Jamie Madill007530e2017-12-28 14:27:04 -05003541bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3542 GLsizei numPaths,
3543 GLenum pathNameType,
3544 const void *paths,
3545 GLuint pathBase,
3546 GLenum coverMode,
3547 GLenum transformType,
3548 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003549{
3550 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3551 transformType, transformValues))
3552 return false;
3553
3554 switch (coverMode)
3555 {
3556 case GL_CONVEX_HULL_CHROMIUM:
3557 case GL_BOUNDING_BOX_CHROMIUM:
3558 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3559 break;
3560 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003561 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003562 return false;
3563 }
3564
3565 return true;
3566}
3567
Jamie Madill007530e2017-12-28 14:27:04 -05003568bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3569 GLsizei numPaths,
3570 GLenum pathNameType,
3571 const void *paths,
3572 GLuint pathBase,
3573 GLenum coverMode,
3574 GLenum transformType,
3575 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003576{
3577 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3578 transformType, transformValues))
3579 return false;
3580
3581 switch (coverMode)
3582 {
3583 case GL_CONVEX_HULL_CHROMIUM:
3584 case GL_BOUNDING_BOX_CHROMIUM:
3585 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3586 break;
3587 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003588 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003589 return false;
3590 }
3591
3592 return true;
3593}
3594
Jamie Madill007530e2017-12-28 14:27:04 -05003595bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3596 GLsizei numPaths,
3597 GLenum pathNameType,
3598 const void *paths,
3599 GLuint pathBase,
3600 GLenum fillMode,
3601 GLuint mask,
3602 GLenum transformType,
3603 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003604{
3605
3606 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3607 transformType, transformValues))
3608 return false;
3609
3610 switch (fillMode)
3611 {
3612 case GL_COUNT_UP_CHROMIUM:
3613 case GL_COUNT_DOWN_CHROMIUM:
3614 break;
3615 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003616 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003617 return false;
3618 }
3619 if (!isPow2(mask + 1))
3620 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003621 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003622 return false;
3623 }
3624 return true;
3625}
3626
Jamie Madill007530e2017-12-28 14:27:04 -05003627bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3628 GLsizei numPaths,
3629 GLenum pathNameType,
3630 const void *paths,
3631 GLuint pathBase,
3632 GLint reference,
3633 GLuint mask,
3634 GLenum transformType,
3635 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003636{
3637 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3638 transformType, transformValues))
3639 return false;
3640
3641 // no more validation here.
3642
3643 return true;
3644}
3645
Jamie Madill007530e2017-12-28 14:27:04 -05003646bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3647 GLsizei numPaths,
3648 GLenum pathNameType,
3649 const void *paths,
3650 GLuint pathBase,
3651 GLenum fillMode,
3652 GLuint mask,
3653 GLenum coverMode,
3654 GLenum transformType,
3655 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003656{
3657 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3658 transformType, transformValues))
3659 return false;
3660
3661 switch (coverMode)
3662 {
3663 case GL_CONVEX_HULL_CHROMIUM:
3664 case GL_BOUNDING_BOX_CHROMIUM:
3665 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3666 break;
3667 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003668 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003669 return false;
3670 }
3671
3672 switch (fillMode)
3673 {
3674 case GL_COUNT_UP_CHROMIUM:
3675 case GL_COUNT_DOWN_CHROMIUM:
3676 break;
3677 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003678 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003679 return false;
3680 }
3681 if (!isPow2(mask + 1))
3682 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003683 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003684 return false;
3685 }
3686
3687 return true;
3688}
3689
Jamie Madill007530e2017-12-28 14:27:04 -05003690bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3691 GLsizei numPaths,
3692 GLenum pathNameType,
3693 const void *paths,
3694 GLuint pathBase,
3695 GLint reference,
3696 GLuint mask,
3697 GLenum coverMode,
3698 GLenum transformType,
3699 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003700{
3701 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3702 transformType, transformValues))
3703 return false;
3704
3705 switch (coverMode)
3706 {
3707 case GL_CONVEX_HULL_CHROMIUM:
3708 case GL_BOUNDING_BOX_CHROMIUM:
3709 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3710 break;
3711 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003712 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003713 return false;
3714 }
3715
3716 return true;
3717}
3718
Jamie Madill007530e2017-12-28 14:27:04 -05003719bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3720 GLuint program,
3721 GLint location,
3722 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003723{
3724 if (!context->getExtensions().pathRendering)
3725 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003726 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003727 return false;
3728 }
3729
3730 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3731 if (location >= MaxLocation)
3732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003733 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003734 return false;
3735 }
3736
3737 const auto *programObject = context->getProgram(program);
3738 if (!programObject)
3739 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003740 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003741 return false;
3742 }
3743
3744 if (!name)
3745 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003746 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003747 return false;
3748 }
3749
3750 if (angle::BeginsWith(name, "gl_"))
3751 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003752 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003753 return false;
3754 }
3755
3756 return true;
3757}
3758
Jamie Madill007530e2017-12-28 14:27:04 -05003759bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3760 GLuint program,
3761 GLint location,
3762 GLenum genMode,
3763 GLint components,
3764 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003765{
3766 if (!context->getExtensions().pathRendering)
3767 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003768 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003769 return false;
3770 }
3771
3772 const auto *programObject = context->getProgram(program);
3773 if (!programObject || programObject->isFlaggedForDeletion())
3774 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003775 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003776 return false;
3777 }
3778
3779 if (!programObject->isLinked())
3780 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003781 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003782 return false;
3783 }
3784
3785 switch (genMode)
3786 {
3787 case GL_NONE:
3788 if (components != 0)
3789 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003790 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003791 return false;
3792 }
3793 break;
3794
3795 case GL_OBJECT_LINEAR_CHROMIUM:
3796 case GL_EYE_LINEAR_CHROMIUM:
3797 case GL_CONSTANT_CHROMIUM:
3798 if (components < 1 || components > 4)
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 if (!coeffs)
3804 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003805 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003806 return false;
3807 }
3808 break;
3809
3810 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003811 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003812 return false;
3813 }
3814
3815 // If the location is -1 then the command is silently ignored
3816 // and no further validation is needed.
3817 if (location == -1)
3818 return true;
3819
Jamie Madillbd044ed2017-06-05 12:59:21 -04003820 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003821
3822 if (!binding.valid)
3823 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003824 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003825 return false;
3826 }
3827
3828 if (binding.type != GL_NONE)
3829 {
3830 GLint expectedComponents = 0;
3831 switch (binding.type)
3832 {
3833 case GL_FLOAT:
3834 expectedComponents = 1;
3835 break;
3836 case GL_FLOAT_VEC2:
3837 expectedComponents = 2;
3838 break;
3839 case GL_FLOAT_VEC3:
3840 expectedComponents = 3;
3841 break;
3842 case GL_FLOAT_VEC4:
3843 expectedComponents = 4;
3844 break;
3845 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003846 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003847 InvalidOperation()
3848 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003849 return false;
3850 }
3851 if (expectedComponents != components && genMode != GL_NONE)
3852 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003853 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003854 return false;
3855 }
3856 }
3857 return true;
3858}
3859
Geoff Lang97073d12016-04-20 10:42:34 -07003860bool ValidateCopyTextureCHROMIUM(Context *context,
3861 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003862 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003863 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003864 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003865 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003866 GLint internalFormat,
3867 GLenum destType,
3868 GLboolean unpackFlipY,
3869 GLboolean unpackPremultiplyAlpha,
3870 GLboolean unpackUnmultiplyAlpha)
3871{
3872 if (!context->getExtensions().copyTexture)
3873 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003874 context->handleError(InvalidOperation()
3875 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003876 return false;
3877 }
3878
Geoff Lang4f0e0032017-05-01 16:04:35 -04003879 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003880 if (source == nullptr)
3881 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003882 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003883 return false;
3884 }
3885
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003886 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003887 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003888 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003889 return false;
3890 }
3891
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003892 TextureType sourceType = source->getType();
3893 ASSERT(sourceType != TextureType::CubeMap);
3894 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003895
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003896 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003898 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003899 return false;
3900 }
3901
Geoff Lang4f0e0032017-05-01 16:04:35 -04003902 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3903 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3904 if (sourceWidth == 0 || sourceHeight == 0)
3905 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003906 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003907 return false;
3908 }
3909
3910 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3911 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003912 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003913 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003914 return false;
3915 }
3916
Geoff Lang63458a32017-10-30 15:16:53 -04003917 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3918 {
3919 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3920 return false;
3921 }
3922
Geoff Lang4f0e0032017-05-01 16:04:35 -04003923 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003924 if (dest == nullptr)
3925 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003926 context->handleError(InvalidValue()
3927 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003928 return false;
3929 }
3930
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003931 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003932 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003933 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003934 return false;
3935 }
3936
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003937 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003938 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003939 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003940 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003941 return false;
3942 }
3943
Geoff Lang97073d12016-04-20 10:42:34 -07003944 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3945 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003946 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003947 return false;
3948 }
3949
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003950 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003951 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003952 context->handleError(
3953 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003954 return false;
3955 }
3956
Geoff Lang97073d12016-04-20 10:42:34 -07003957 if (dest->getImmutableFormat())
3958 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003959 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003960 return false;
3961 }
3962
3963 return true;
3964}
3965
3966bool ValidateCopySubTextureCHROMIUM(Context *context,
3967 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003968 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003969 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003970 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003971 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003972 GLint xoffset,
3973 GLint yoffset,
3974 GLint x,
3975 GLint y,
3976 GLsizei width,
3977 GLsizei height,
3978 GLboolean unpackFlipY,
3979 GLboolean unpackPremultiplyAlpha,
3980 GLboolean unpackUnmultiplyAlpha)
3981{
3982 if (!context->getExtensions().copyTexture)
3983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003984 context->handleError(InvalidOperation()
3985 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003986 return false;
3987 }
3988
Geoff Lang4f0e0032017-05-01 16:04:35 -04003989 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003990 if (source == nullptr)
3991 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003992 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003993 return false;
3994 }
3995
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003996 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003997 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003998 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003999 return false;
4000 }
4001
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004002 TextureType sourceType = source->getType();
4003 ASSERT(sourceType != TextureType::CubeMap);
4004 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004005
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004006 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004007 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004008 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004009 return false;
4010 }
4011
4012 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4013 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004014 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004015 context->handleError(InvalidValue()
4016 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004017 return false;
4018 }
4019
4020 if (x < 0 || y < 0)
4021 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004022 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004023 return false;
4024 }
4025
4026 if (width < 0 || height < 0)
4027 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004028 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004029 return false;
4030 }
4031
Geoff Lang4f0e0032017-05-01 16:04:35 -04004032 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4033 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004034 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004035 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004036 return false;
4037 }
4038
Geoff Lang4f0e0032017-05-01 16:04:35 -04004039 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4040 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004041 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004042 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004043 return false;
4044 }
4045
Geoff Lang63458a32017-10-30 15:16:53 -04004046 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4047 {
4048 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4049 return false;
4050 }
4051
Geoff Lang4f0e0032017-05-01 16:04:35 -04004052 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004053 if (dest == nullptr)
4054 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004055 context->handleError(InvalidValue()
4056 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004057 return false;
4058 }
4059
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004060 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004061 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004062 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004063 return false;
4064 }
4065
Brandon Jones28783792018-03-05 09:37:32 -08004066 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4067 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004069 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004070 return false;
4071 }
4072
Geoff Lang4f0e0032017-05-01 16:04:35 -04004073 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4074 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004075 context
4076 ->handleError(InvalidOperation()
4077 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004078 return false;
4079 }
4080
4081 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4082 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004083 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004084 context->handleError(InvalidOperation()
4085 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004086 return false;
4087 }
4088
4089 if (xoffset < 0 || yoffset < 0)
4090 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004091 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004092 return false;
4093 }
4094
Geoff Lang4f0e0032017-05-01 16:04:35 -04004095 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4096 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004097 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004098 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004099 return false;
4100 }
4101
4102 return true;
4103}
4104
Geoff Lang47110bf2016-04-20 11:13:22 -07004105bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4106{
4107 if (!context->getExtensions().copyCompressedTexture)
4108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004109 context->handleError(InvalidOperation()
4110 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004111 return false;
4112 }
4113
4114 const gl::Texture *source = context->getTexture(sourceId);
4115 if (source == nullptr)
4116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004117 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004118 return false;
4119 }
4120
Corentin Wallez99d492c2018-02-27 15:17:10 -05004121 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004123 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004124 return false;
4125 }
4126
Corentin Wallez99d492c2018-02-27 15:17:10 -05004127 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4128 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004129 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004130 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004131 return false;
4132 }
4133
Corentin Wallez99d492c2018-02-27 15:17:10 -05004134 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004135 if (!sourceFormat.info->compressed)
4136 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004137 context->handleError(InvalidOperation()
4138 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004139 return false;
4140 }
4141
4142 const gl::Texture *dest = context->getTexture(destId);
4143 if (dest == nullptr)
4144 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004145 context->handleError(InvalidValue()
4146 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004147 return false;
4148 }
4149
Corentin Wallez99d492c2018-02-27 15:17:10 -05004150 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004151 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004152 context->handleError(InvalidValue()
4153 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004154 return false;
4155 }
4156
4157 if (dest->getImmutableFormat())
4158 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004159 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004160 return false;
4161 }
4162
4163 return true;
4164}
4165
Jiawei Shao385b3e02018-03-21 09:43:28 +08004166bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004167{
4168 switch (type)
4169 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004170 case ShaderType::Vertex:
4171 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004172 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004173
Jiawei Shao385b3e02018-03-21 09:43:28 +08004174 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004175 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004176 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004177 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004178 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004179 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004180 break;
4181
Jiawei Shao385b3e02018-03-21 09:43:28 +08004182 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004183 if (!context->getExtensions().geometryShader)
4184 {
4185 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4186 return false;
4187 }
4188 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004189 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004190 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004191 return false;
4192 }
Jamie Madill29639852016-09-02 15:00:09 -04004193
4194 return true;
4195}
4196
Jamie Madill5b772312018-03-08 20:28:32 -05004197bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004198 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004199 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004200 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004201 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004202{
4203 if (size < 0)
4204 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004205 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004206 return false;
4207 }
4208
4209 switch (usage)
4210 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004211 case BufferUsage::StreamDraw:
4212 case BufferUsage::StaticDraw:
4213 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004214 break;
4215
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004216 case BufferUsage::StreamRead:
4217 case BufferUsage::StaticRead:
4218 case BufferUsage::DynamicRead:
4219 case BufferUsage::StreamCopy:
4220 case BufferUsage::StaticCopy:
4221 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004222 if (context->getClientMajorVersion() < 3)
4223 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004224 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004225 return false;
4226 }
4227 break;
4228
4229 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004230 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004231 return false;
4232 }
4233
Corentin Walleze4477002017-12-01 14:39:58 -05004234 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004235 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004236 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004237 return false;
4238 }
4239
4240 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4241
4242 if (!buffer)
4243 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004244 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004245 return false;
4246 }
4247
James Darpiniane8a93c62018-01-04 18:02:24 -08004248 if (context->getExtensions().webglCompatibility &&
4249 buffer->isBoundForTransformFeedbackAndOtherUse())
4250 {
4251 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4252 return false;
4253 }
4254
Jamie Madill29639852016-09-02 15:00:09 -04004255 return true;
4256}
4257
Jamie Madill5b772312018-03-08 20:28:32 -05004258bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004259 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004260 GLintptr offset,
4261 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004262 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004263{
Brandon Jones6cad5662017-06-14 13:25:13 -07004264 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004265 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004266 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4267 return false;
4268 }
4269
4270 if (offset < 0)
4271 {
4272 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004273 return false;
4274 }
4275
Corentin Walleze4477002017-12-01 14:39:58 -05004276 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004277 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004278 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004279 return false;
4280 }
4281
4282 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4283
4284 if (!buffer)
4285 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004286 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004287 return false;
4288 }
4289
4290 if (buffer->isMapped())
4291 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004292 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004293 return false;
4294 }
4295
James Darpiniane8a93c62018-01-04 18:02:24 -08004296 if (context->getExtensions().webglCompatibility &&
4297 buffer->isBoundForTransformFeedbackAndOtherUse())
4298 {
4299 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4300 return false;
4301 }
4302
Jamie Madill29639852016-09-02 15:00:09 -04004303 // Check for possible overflow of size + offset
4304 angle::CheckedNumeric<size_t> checkedSize(size);
4305 checkedSize += offset;
4306 if (!checkedSize.IsValid())
4307 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004308 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004309 return false;
4310 }
4311
4312 if (size + offset > buffer->getSize())
4313 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004314 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004315 return false;
4316 }
4317
Martin Radev4c4c8e72016-08-04 12:25:34 +03004318 return true;
4319}
4320
Geoff Lang111a99e2017-10-17 10:58:41 -04004321bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004322{
Geoff Langc339c4e2016-11-29 10:37:36 -05004323 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004324 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004325 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004326 return false;
4327 }
4328
Geoff Lang111a99e2017-10-17 10:58:41 -04004329 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004330 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004331 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004332 return false;
4333 }
4334
4335 return true;
4336}
4337
Jamie Madill5b772312018-03-08 20:28:32 -05004338bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004339{
4340 if (texture < GL_TEXTURE0 ||
4341 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4342 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004343 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004344 return false;
4345 }
4346
4347 return true;
4348}
4349
Jamie Madill5b772312018-03-08 20:28:32 -05004350bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004351{
4352 Program *programObject = GetValidProgram(context, program);
4353 if (!programObject)
4354 {
4355 return false;
4356 }
4357
4358 Shader *shaderObject = GetValidShader(context, shader);
4359 if (!shaderObject)
4360 {
4361 return false;
4362 }
4363
Jiawei Shao385b3e02018-03-21 09:43:28 +08004364 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004365 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004366 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4367 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004368 }
4369
4370 return true;
4371}
4372
Jamie Madill5b772312018-03-08 20:28:32 -05004373bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004374{
4375 if (index >= MAX_VERTEX_ATTRIBS)
4376 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004377 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004378 return false;
4379 }
4380
4381 if (strncmp(name, "gl_", 3) == 0)
4382 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004383 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004384 return false;
4385 }
4386
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004387 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004388 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004389 const size_t length = strlen(name);
4390
4391 if (!IsValidESSLString(name, length))
4392 {
4393 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4394 // for shader-related entry points
4395 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4396 return false;
4397 }
4398
4399 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4400 {
4401 return false;
4402 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004403 }
4404
Jamie Madill01a80ee2016-11-07 12:06:18 -05004405 return GetValidProgram(context, program) != nullptr;
4406}
4407
Jamie Madill5b772312018-03-08 20:28:32 -05004408bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004409{
Corentin Walleze4477002017-12-01 14:39:58 -05004410 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004411 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004412 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004413 return false;
4414 }
4415
4416 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4417 !context->isBufferGenerated(buffer))
4418 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004419 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004420 return false;
4421 }
4422
4423 return true;
4424}
4425
Jamie Madill5b772312018-03-08 20:28:32 -05004426bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004427{
Geoff Lange8afa902017-09-27 15:00:43 -04004428 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004429 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004430 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004431 return false;
4432 }
4433
4434 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4435 !context->isFramebufferGenerated(framebuffer))
4436 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004437 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004438 return false;
4439 }
4440
4441 return true;
4442}
4443
Jamie Madill5b772312018-03-08 20:28:32 -05004444bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004445{
4446 if (target != GL_RENDERBUFFER)
4447 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004448 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004449 return false;
4450 }
4451
4452 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4453 !context->isRenderbufferGenerated(renderbuffer))
4454 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004455 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004456 return false;
4457 }
4458
4459 return true;
4460}
4461
Jamie Madill5b772312018-03-08 20:28:32 -05004462static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004463{
4464 switch (mode)
4465 {
4466 case GL_FUNC_ADD:
4467 case GL_FUNC_SUBTRACT:
4468 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004469 return true;
4470
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004471 case GL_MIN:
4472 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004473 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004474
4475 default:
4476 return false;
4477 }
4478}
4479
Jamie Madill5b772312018-03-08 20:28:32 -05004480bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004481{
4482 return true;
4483}
4484
Jamie Madill5b772312018-03-08 20:28:32 -05004485bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004486{
Geoff Lang50cac572017-09-26 17:37:43 -04004487 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004488 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004489 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004490 return false;
4491 }
4492
4493 return true;
4494}
4495
Jamie Madill5b772312018-03-08 20:28:32 -05004496bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004497{
Geoff Lang50cac572017-09-26 17:37:43 -04004498 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004499 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004500 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004501 return false;
4502 }
4503
Geoff Lang50cac572017-09-26 17:37:43 -04004504 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004505 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004506 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004507 return false;
4508 }
4509
4510 return true;
4511}
4512
Jamie Madill5b772312018-03-08 20:28:32 -05004513bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004514{
4515 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4516}
4517
4518static bool ValidSrcBlendFunc(GLenum srcBlend)
4519{
4520 switch (srcBlend)
4521 {
4522 case GL_ZERO:
4523 case GL_ONE:
4524 case GL_SRC_COLOR:
4525 case GL_ONE_MINUS_SRC_COLOR:
4526 case GL_DST_COLOR:
4527 case GL_ONE_MINUS_DST_COLOR:
4528 case GL_SRC_ALPHA:
4529 case GL_ONE_MINUS_SRC_ALPHA:
4530 case GL_DST_ALPHA:
4531 case GL_ONE_MINUS_DST_ALPHA:
4532 case GL_CONSTANT_COLOR:
4533 case GL_ONE_MINUS_CONSTANT_COLOR:
4534 case GL_CONSTANT_ALPHA:
4535 case GL_ONE_MINUS_CONSTANT_ALPHA:
4536 case GL_SRC_ALPHA_SATURATE:
4537 return true;
4538
4539 default:
4540 return false;
4541 }
4542}
4543
4544static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4545{
4546 switch (dstBlend)
4547 {
4548 case GL_ZERO:
4549 case GL_ONE:
4550 case GL_SRC_COLOR:
4551 case GL_ONE_MINUS_SRC_COLOR:
4552 case GL_DST_COLOR:
4553 case GL_ONE_MINUS_DST_COLOR:
4554 case GL_SRC_ALPHA:
4555 case GL_ONE_MINUS_SRC_ALPHA:
4556 case GL_DST_ALPHA:
4557 case GL_ONE_MINUS_DST_ALPHA:
4558 case GL_CONSTANT_COLOR:
4559 case GL_ONE_MINUS_CONSTANT_COLOR:
4560 case GL_CONSTANT_ALPHA:
4561 case GL_ONE_MINUS_CONSTANT_ALPHA:
4562 return true;
4563
4564 case GL_SRC_ALPHA_SATURATE:
4565 return (contextMajorVersion >= 3);
4566
4567 default:
4568 return false;
4569 }
4570}
4571
Jamie Madill5b772312018-03-08 20:28:32 -05004572bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004573 GLenum srcRGB,
4574 GLenum dstRGB,
4575 GLenum srcAlpha,
4576 GLenum dstAlpha)
4577{
4578 if (!ValidSrcBlendFunc(srcRGB))
4579 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004580 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004581 return false;
4582 }
4583
4584 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4585 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004586 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004587 return false;
4588 }
4589
4590 if (!ValidSrcBlendFunc(srcAlpha))
4591 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004592 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004593 return false;
4594 }
4595
4596 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4597 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004598 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004599 return false;
4600 }
4601
Frank Henigman146e8a12017-03-02 23:22:37 -05004602 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4603 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004604 {
4605 bool constantColorUsed =
4606 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4607 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4608
4609 bool constantAlphaUsed =
4610 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4611 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4612
4613 if (constantColorUsed && constantAlphaUsed)
4614 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004615 const char *msg;
4616 if (context->getExtensions().webglCompatibility)
4617 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004618 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004619 }
4620 else
4621 {
4622 msg =
4623 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4624 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4625 "implementation.";
4626 ERR() << msg;
4627 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004628 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004629 return false;
4630 }
4631 }
4632
4633 return true;
4634}
4635
Geoff Langc339c4e2016-11-29 10:37:36 -05004636bool ValidateGetString(Context *context, GLenum name)
4637{
4638 switch (name)
4639 {
4640 case GL_VENDOR:
4641 case GL_RENDERER:
4642 case GL_VERSION:
4643 case GL_SHADING_LANGUAGE_VERSION:
4644 case GL_EXTENSIONS:
4645 break;
4646
4647 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4648 if (!context->getExtensions().requestExtension)
4649 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004650 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004651 return false;
4652 }
4653 break;
4654
4655 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004656 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004657 return false;
4658 }
4659
4660 return true;
4661}
4662
Jamie Madill5b772312018-03-08 20:28:32 -05004663bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004664{
4665 if (width <= 0.0f || isNaN(width))
4666 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004667 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004668 return false;
4669 }
4670
4671 return true;
4672}
4673
Jamie Madill5b772312018-03-08 20:28:32 -05004674bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004675 GLuint index,
4676 GLint size,
4677 GLenum type,
4678 GLboolean normalized,
4679 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004680 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004681{
Shao80957d92017-02-20 21:25:59 +08004682 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004683 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004684 return false;
4685 }
4686
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004687 if (stride < 0)
4688 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004689 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004690 return false;
4691 }
4692
Shao80957d92017-02-20 21:25:59 +08004693 const Caps &caps = context->getCaps();
4694 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004695 {
Shao80957d92017-02-20 21:25:59 +08004696 if (stride > caps.maxVertexAttribStride)
4697 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004698 context->handleError(InvalidValue()
4699 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004700 return false;
4701 }
4702
4703 if (index >= caps.maxVertexAttribBindings)
4704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004705 context->handleError(InvalidValue()
4706 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004707 return false;
4708 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004709 }
4710
4711 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4712 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4713 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4714 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004715 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4716 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004717 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4718 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004720 context
4721 ->handleError(InvalidOperation()
4722 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004723 return false;
4724 }
4725
4726 if (context->getExtensions().webglCompatibility)
4727 {
4728 // WebGL 1.0 [Section 6.14] Fixed point support
4729 // The WebGL API does not support the GL_FIXED data type.
4730 if (type == GL_FIXED)
4731 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004732 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004733 return false;
4734 }
4735
Geoff Lang2d62ab72017-03-23 16:54:40 -04004736 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004737 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004738 return false;
4739 }
4740 }
4741
4742 return true;
4743}
4744
Jamie Madill5b772312018-03-08 20:28:32 -05004745bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004746{
4747 if (context->getExtensions().webglCompatibility && zNear > zFar)
4748 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004749 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004750 return false;
4751 }
4752
4753 return true;
4754}
4755
Jamie Madill5b772312018-03-08 20:28:32 -05004756bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004757 GLenum target,
4758 GLenum internalformat,
4759 GLsizei width,
4760 GLsizei height)
4761{
4762 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4763 height);
4764}
4765
Jamie Madill5b772312018-03-08 20:28:32 -05004766bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004767 GLenum target,
4768 GLsizei samples,
4769 GLenum internalformat,
4770 GLsizei width,
4771 GLsizei height)
4772{
4773 if (!context->getExtensions().framebufferMultisample)
4774 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004775 context->handleError(InvalidOperation()
4776 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004777 return false;
4778 }
4779
4780 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4781 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4782 // generated.
4783 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004785 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004786 return false;
4787 }
4788
4789 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4790 // the specified storage. This is different than ES 3.0 in which a sample number higher
4791 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4792 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4793 if (context->getClientMajorVersion() >= 3)
4794 {
4795 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4796 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004798 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004799 return false;
4800 }
4801 }
4802
4803 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4804 width, height);
4805}
4806
Jamie Madill5b772312018-03-08 20:28:32 -05004807bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004808{
Geoff Lange8afa902017-09-27 15:00:43 -04004809 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004810 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004811 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004812 return false;
4813 }
4814
4815 return true;
4816}
4817
Jamie Madill5b772312018-03-08 20:28:32 -05004818bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004819{
4820 return true;
4821}
4822
Jamie Madill5b772312018-03-08 20:28:32 -05004823bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004824{
4825 return true;
4826}
4827
Jamie Madill5b772312018-03-08 20:28:32 -05004828bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004829{
4830 return true;
4831}
4832
Jamie Madill5b772312018-03-08 20:28:32 -05004833bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004834 GLboolean red,
4835 GLboolean green,
4836 GLboolean blue,
4837 GLboolean alpha)
4838{
4839 return true;
4840}
4841
Jamie Madill5b772312018-03-08 20:28:32 -05004842bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004843{
4844 return true;
4845}
4846
Jamie Madill5b772312018-03-08 20:28:32 -05004847bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004848{
4849 return true;
4850}
4851
Jamie Madill5b772312018-03-08 20:28:32 -05004852bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004853{
4854 switch (mode)
4855 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004856 case CullFaceMode::Front:
4857 case CullFaceMode::Back:
4858 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004859 break;
4860
4861 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004862 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004863 return false;
4864 }
4865
4866 return true;
4867}
4868
Jamie Madill5b772312018-03-08 20:28:32 -05004869bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004870{
4871 if (program == 0)
4872 {
4873 return false;
4874 }
4875
4876 if (!context->getProgram(program))
4877 {
4878 if (context->getShader(program))
4879 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004880 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004881 return false;
4882 }
4883 else
4884 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004885 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004886 return false;
4887 }
4888 }
4889
4890 return true;
4891}
4892
Jamie Madill5b772312018-03-08 20:28:32 -05004893bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894{
4895 if (shader == 0)
4896 {
4897 return false;
4898 }
4899
4900 if (!context->getShader(shader))
4901 {
4902 if (context->getProgram(shader))
4903 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004904 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004905 return false;
4906 }
4907 else
4908 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004909 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004910 return false;
4911 }
4912 }
4913
4914 return true;
4915}
4916
Jamie Madill5b772312018-03-08 20:28:32 -05004917bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004918{
4919 switch (func)
4920 {
4921 case GL_NEVER:
4922 case GL_ALWAYS:
4923 case GL_LESS:
4924 case GL_LEQUAL:
4925 case GL_EQUAL:
4926 case GL_GREATER:
4927 case GL_GEQUAL:
4928 case GL_NOTEQUAL:
4929 break;
4930
4931 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004932 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004933 return false;
4934 }
4935
4936 return true;
4937}
4938
Jamie Madill5b772312018-03-08 20:28:32 -05004939bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004940{
4941 return true;
4942}
4943
Jamie Madill5b772312018-03-08 20:28:32 -05004944bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004945{
4946 Program *programObject = GetValidProgram(context, program);
4947 if (!programObject)
4948 {
4949 return false;
4950 }
4951
4952 Shader *shaderObject = GetValidShader(context, shader);
4953 if (!shaderObject)
4954 {
4955 return false;
4956 }
4957
Jiawei Shao385b3e02018-03-21 09:43:28 +08004958 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004959 if (attachedShader != shaderObject)
4960 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004961 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004962 return false;
4963 }
4964
4965 return true;
4966}
4967
Jamie Madill5b772312018-03-08 20:28:32 -05004968bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004969{
4970 if (index >= MAX_VERTEX_ATTRIBS)
4971 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004972 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004973 return false;
4974 }
4975
4976 return true;
4977}
4978
Jamie Madill5b772312018-03-08 20:28:32 -05004979bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004980{
4981 if (index >= MAX_VERTEX_ATTRIBS)
4982 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004983 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004984 return false;
4985 }
4986
4987 return true;
4988}
4989
Jamie Madill5b772312018-03-08 20:28:32 -05004990bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004991{
4992 return true;
4993}
4994
Jamie Madill5b772312018-03-08 20:28:32 -05004995bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004996{
4997 return true;
4998}
4999
Jamie Madill5b772312018-03-08 20:28:32 -05005000bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005001{
5002 switch (mode)
5003 {
5004 case GL_CW:
5005 case GL_CCW:
5006 break;
5007 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005008 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005009 return false;
5010 }
5011
5012 return true;
5013}
5014
Jamie Madill5b772312018-03-08 20:28:32 -05005015bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005016 GLuint program,
5017 GLuint index,
5018 GLsizei bufsize,
5019 GLsizei *length,
5020 GLint *size,
5021 GLenum *type,
5022 GLchar *name)
5023{
5024 if (bufsize < 0)
5025 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005026 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005027 return false;
5028 }
5029
5030 Program *programObject = GetValidProgram(context, program);
5031
5032 if (!programObject)
5033 {
5034 return false;
5035 }
5036
5037 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5038 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005039 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005040 return false;
5041 }
5042
5043 return true;
5044}
5045
Jamie Madill5b772312018-03-08 20:28:32 -05005046bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005047 GLuint program,
5048 GLuint index,
5049 GLsizei bufsize,
5050 GLsizei *length,
5051 GLint *size,
5052 GLenum *type,
5053 GLchar *name)
5054{
5055 if (bufsize < 0)
5056 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005057 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005058 return false;
5059 }
5060
5061 Program *programObject = GetValidProgram(context, program);
5062
5063 if (!programObject)
5064 {
5065 return false;
5066 }
5067
5068 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5069 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005070 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005071 return false;
5072 }
5073
5074 return true;
5075}
5076
Jamie Madill5b772312018-03-08 20:28:32 -05005077bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005078 GLuint program,
5079 GLsizei maxcount,
5080 GLsizei *count,
5081 GLuint *shaders)
5082{
5083 if (maxcount < 0)
5084 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005085 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005086 return false;
5087 }
5088
5089 Program *programObject = GetValidProgram(context, program);
5090
5091 if (!programObject)
5092 {
5093 return false;
5094 }
5095
5096 return true;
5097}
5098
Jamie Madill5b772312018-03-08 20:28:32 -05005099bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005100{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005101 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5102 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005103 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005104 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005105 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005106 return false;
5107 }
5108
Jamie Madillc1d770e2017-04-13 17:31:24 -04005109 Program *programObject = GetValidProgram(context, program);
5110
5111 if (!programObject)
5112 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005113 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005114 return false;
5115 }
5116
5117 if (!programObject->isLinked())
5118 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005119 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005120 return false;
5121 }
5122
5123 return true;
5124}
5125
Jamie Madill5b772312018-03-08 20:28:32 -05005126bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005127{
5128 GLenum nativeType;
5129 unsigned int numParams = 0;
5130 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5131}
5132
Jamie Madill5b772312018-03-08 20:28:32 -05005133bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005134{
5135 return true;
5136}
5137
Jamie Madill5b772312018-03-08 20:28:32 -05005138bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005139{
5140 GLenum nativeType;
5141 unsigned int numParams = 0;
5142 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5143}
5144
Jamie Madill5b772312018-03-08 20:28:32 -05005145bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005146{
5147 GLenum nativeType;
5148 unsigned int numParams = 0;
5149 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5150}
5151
Jamie Madill5b772312018-03-08 20:28:32 -05005152bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005153 GLuint program,
5154 GLsizei bufsize,
5155 GLsizei *length,
5156 GLchar *infolog)
5157{
5158 if (bufsize < 0)
5159 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005160 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161 return false;
5162 }
5163
5164 Program *programObject = GetValidProgram(context, program);
5165 if (!programObject)
5166 {
5167 return false;
5168 }
5169
5170 return true;
5171}
5172
Jamie Madill5b772312018-03-08 20:28:32 -05005173bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005174 GLuint shader,
5175 GLsizei bufsize,
5176 GLsizei *length,
5177 GLchar *infolog)
5178{
5179 if (bufsize < 0)
5180 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005181 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005182 return false;
5183 }
5184
5185 Shader *shaderObject = GetValidShader(context, shader);
5186 if (!shaderObject)
5187 {
5188 return false;
5189 }
5190
5191 return true;
5192}
5193
Jamie Madill5b772312018-03-08 20:28:32 -05005194bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005195 GLenum shadertype,
5196 GLenum precisiontype,
5197 GLint *range,
5198 GLint *precision)
5199{
5200 switch (shadertype)
5201 {
5202 case GL_VERTEX_SHADER:
5203 case GL_FRAGMENT_SHADER:
5204 break;
5205 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005206 context->handleError(InvalidOperation()
5207 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005208 return false;
5209 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005210 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005211 return false;
5212 }
5213
5214 switch (precisiontype)
5215 {
5216 case GL_LOW_FLOAT:
5217 case GL_MEDIUM_FLOAT:
5218 case GL_HIGH_FLOAT:
5219 case GL_LOW_INT:
5220 case GL_MEDIUM_INT:
5221 case GL_HIGH_INT:
5222 break;
5223
5224 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005225 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005226 return false;
5227 }
5228
5229 return true;
5230}
5231
Jamie Madill5b772312018-03-08 20:28:32 -05005232bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005233 GLuint shader,
5234 GLsizei bufsize,
5235 GLsizei *length,
5236 GLchar *source)
5237{
5238 if (bufsize < 0)
5239 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005240 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005241 return false;
5242 }
5243
5244 Shader *shaderObject = GetValidShader(context, shader);
5245 if (!shaderObject)
5246 {
5247 return false;
5248 }
5249
5250 return true;
5251}
5252
Jamie Madill5b772312018-03-08 20:28:32 -05005253bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005254{
5255 if (strstr(name, "gl_") == name)
5256 {
5257 return false;
5258 }
5259
Geoff Langfc32e8b2017-05-31 14:16:59 -04005260 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5261 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005262 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005263 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005264 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005265 return false;
5266 }
5267
Jamie Madillc1d770e2017-04-13 17:31:24 -04005268 Program *programObject = GetValidProgram(context, program);
5269
5270 if (!programObject)
5271 {
5272 return false;
5273 }
5274
5275 if (!programObject->isLinked())
5276 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005277 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005278 return false;
5279 }
5280
5281 return true;
5282}
5283
Jamie Madill5b772312018-03-08 20:28:32 -05005284bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005285{
5286 switch (mode)
5287 {
5288 case GL_FASTEST:
5289 case GL_NICEST:
5290 case GL_DONT_CARE:
5291 break;
5292
5293 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005294 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005295 return false;
5296 }
5297
5298 switch (target)
5299 {
5300 case GL_GENERATE_MIPMAP_HINT:
5301 break;
5302
Geoff Lange7bd2182017-06-16 16:13:13 -04005303 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5304 if (context->getClientVersion() < ES_3_0 &&
5305 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005306 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005307 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005308 return false;
5309 }
5310 break;
5311
5312 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005313 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005314 return false;
5315 }
5316
5317 return true;
5318}
5319
Jamie Madill5b772312018-03-08 20:28:32 -05005320bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005321{
5322 return true;
5323}
5324
Jamie Madill5b772312018-03-08 20:28:32 -05005325bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005326{
5327 return true;
5328}
5329
Jamie Madill5b772312018-03-08 20:28:32 -05005330bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005331{
5332 return true;
5333}
5334
Jamie Madill5b772312018-03-08 20:28:32 -05005335bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005336{
5337 return true;
5338}
5339
Jamie Madill5b772312018-03-08 20:28:32 -05005340bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005341{
5342 return true;
5343}
5344
Jamie Madill5b772312018-03-08 20:28:32 -05005345bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005346{
5347 return true;
5348}
5349
Jamie Madill5b772312018-03-08 20:28:32 -05005350bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005351{
5352 if (context->getClientMajorVersion() < 3)
5353 {
5354 switch (pname)
5355 {
5356 case GL_UNPACK_IMAGE_HEIGHT:
5357 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005358 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005359 return false;
5360
5361 case GL_UNPACK_ROW_LENGTH:
5362 case GL_UNPACK_SKIP_ROWS:
5363 case GL_UNPACK_SKIP_PIXELS:
5364 if (!context->getExtensions().unpackSubimage)
5365 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005366 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005367 return false;
5368 }
5369 break;
5370
5371 case GL_PACK_ROW_LENGTH:
5372 case GL_PACK_SKIP_ROWS:
5373 case GL_PACK_SKIP_PIXELS:
5374 if (!context->getExtensions().packSubimage)
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 }
5382
5383 if (param < 0)
5384 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005385 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005386 return false;
5387 }
5388
5389 switch (pname)
5390 {
5391 case GL_UNPACK_ALIGNMENT:
5392 if (param != 1 && param != 2 && param != 4 && param != 8)
5393 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005394 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005395 return false;
5396 }
5397 break;
5398
5399 case GL_PACK_ALIGNMENT:
5400 if (param != 1 && param != 2 && param != 4 && param != 8)
5401 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005402 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005403 return false;
5404 }
5405 break;
5406
5407 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005408 if (!context->getExtensions().packReverseRowOrder)
5409 {
5410 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5411 }
5412 break;
5413
Jamie Madillc1d770e2017-04-13 17:31:24 -04005414 case GL_UNPACK_ROW_LENGTH:
5415 case GL_UNPACK_IMAGE_HEIGHT:
5416 case GL_UNPACK_SKIP_IMAGES:
5417 case GL_UNPACK_SKIP_ROWS:
5418 case GL_UNPACK_SKIP_PIXELS:
5419 case GL_PACK_ROW_LENGTH:
5420 case GL_PACK_SKIP_ROWS:
5421 case GL_PACK_SKIP_PIXELS:
5422 break;
5423
5424 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005425 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005426 return false;
5427 }
5428
5429 return true;
5430}
5431
Jamie Madill5b772312018-03-08 20:28:32 -05005432bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005433{
5434 return true;
5435}
5436
Jamie Madill5b772312018-03-08 20:28:32 -05005437bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005438{
5439 return true;
5440}
5441
Jamie Madill5b772312018-03-08 20:28:32 -05005442bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005443{
5444 return true;
5445}
5446
Jamie Madill5b772312018-03-08 20:28:32 -05005447bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005448{
5449 if (width < 0 || height < 0)
5450 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005451 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005452 return false;
5453 }
5454
5455 return true;
5456}
5457
Jamie Madill5b772312018-03-08 20:28:32 -05005458bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005459 GLsizei n,
5460 const GLuint *shaders,
5461 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005462 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005463 GLsizei length)
5464{
5465 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5466 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5467 shaderBinaryFormats.end())
5468 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005469 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470 return false;
5471 }
5472
5473 return true;
5474}
5475
Jamie Madill5b772312018-03-08 20:28:32 -05005476bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477 GLuint shader,
5478 GLsizei count,
5479 const GLchar *const *string,
5480 const GLint *length)
5481{
5482 if (count < 0)
5483 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005484 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485 return false;
5486 }
5487
Geoff Langfc32e8b2017-05-31 14:16:59 -04005488 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5489 // shader-related entry points
5490 if (context->getExtensions().webglCompatibility)
5491 {
5492 for (GLsizei i = 0; i < count; i++)
5493 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005494 size_t len =
5495 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005496
5497 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005498 if (!IsValidESSLShaderSourceString(string[i], len,
5499 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005500 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005501 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005502 return false;
5503 }
5504 }
5505 }
5506
Jamie Madillc1d770e2017-04-13 17:31:24 -04005507 Shader *shaderObject = GetValidShader(context, shader);
5508 if (!shaderObject)
5509 {
5510 return false;
5511 }
5512
5513 return true;
5514}
5515
Jamie Madill5b772312018-03-08 20:28:32 -05005516bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005517{
5518 if (!IsValidStencilFunc(func))
5519 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005520 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005521 return false;
5522 }
5523
5524 return true;
5525}
5526
Jamie Madill5b772312018-03-08 20:28:32 -05005527bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005528{
5529 if (!IsValidStencilFace(face))
5530 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005531 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005532 return false;
5533 }
5534
5535 if (!IsValidStencilFunc(func))
5536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005537 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005538 return false;
5539 }
5540
5541 return true;
5542}
5543
Jamie Madill5b772312018-03-08 20:28:32 -05005544bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005545{
5546 return true;
5547}
5548
Jamie Madill5b772312018-03-08 20:28:32 -05005549bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005550{
5551 if (!IsValidStencilFace(face))
5552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005553 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005554 return false;
5555 }
5556
5557 return true;
5558}
5559
Jamie Madill5b772312018-03-08 20:28:32 -05005560bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005561{
5562 if (!IsValidStencilOp(fail))
5563 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005564 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005565 return false;
5566 }
5567
5568 if (!IsValidStencilOp(zfail))
5569 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005570 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005571 return false;
5572 }
5573
5574 if (!IsValidStencilOp(zpass))
5575 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005576 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005577 return false;
5578 }
5579
5580 return true;
5581}
5582
Jamie Madill5b772312018-03-08 20:28:32 -05005583bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005584 GLenum face,
5585 GLenum fail,
5586 GLenum zfail,
5587 GLenum zpass)
5588{
5589 if (!IsValidStencilFace(face))
5590 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005591 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005592 return false;
5593 }
5594
5595 return ValidateStencilOp(context, fail, zfail, zpass);
5596}
5597
Jamie Madill5b772312018-03-08 20:28:32 -05005598bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005599{
5600 return ValidateUniform(context, GL_FLOAT, location, 1);
5601}
5602
Jamie Madill5b772312018-03-08 20:28:32 -05005603bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005604{
5605 return ValidateUniform(context, GL_FLOAT, location, count);
5606}
5607
Jamie Madill5b772312018-03-08 20:28:32 -05005608bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005609{
5610 return ValidateUniform1iv(context, location, 1, &x);
5611}
5612
Jamie Madill5b772312018-03-08 20:28:32 -05005613bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005614{
5615 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5616}
5617
Jamie Madill5b772312018-03-08 20:28:32 -05005618bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005619{
5620 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5621}
5622
Jamie Madill5b772312018-03-08 20:28:32 -05005623bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005624{
5625 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5626}
5627
Jamie Madill5b772312018-03-08 20:28:32 -05005628bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629{
5630 return ValidateUniform(context, GL_INT_VEC2, location, count);
5631}
5632
Jamie Madill5b772312018-03-08 20:28:32 -05005633bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005634{
5635 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5636}
5637
Jamie Madill5b772312018-03-08 20:28:32 -05005638bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005639{
5640 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5641}
5642
Jamie Madill5b772312018-03-08 20:28:32 -05005643bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005644{
5645 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5646}
5647
Jamie Madill5b772312018-03-08 20:28:32 -05005648bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005649{
5650 return ValidateUniform(context, GL_INT_VEC3, location, count);
5651}
5652
Jamie Madill5b772312018-03-08 20:28:32 -05005653bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005654{
5655 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5656}
5657
Jamie Madill5b772312018-03-08 20:28:32 -05005658bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005659{
5660 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5661}
5662
Jamie Madill5b772312018-03-08 20:28:32 -05005663bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005664{
5665 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5666}
5667
Jamie Madill5b772312018-03-08 20:28:32 -05005668bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005669{
5670 return ValidateUniform(context, GL_INT_VEC4, location, count);
5671}
5672
Jamie Madill5b772312018-03-08 20:28:32 -05005673bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005674 GLint location,
5675 GLsizei count,
5676 GLboolean transpose,
5677 const GLfloat *value)
5678{
5679 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5680}
5681
Jamie Madill5b772312018-03-08 20:28:32 -05005682bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005683 GLint location,
5684 GLsizei count,
5685 GLboolean transpose,
5686 const GLfloat *value)
5687{
5688 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5689}
5690
Jamie Madill5b772312018-03-08 20:28:32 -05005691bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005692 GLint location,
5693 GLsizei count,
5694 GLboolean transpose,
5695 const GLfloat *value)
5696{
5697 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5698}
5699
Jamie Madill5b772312018-03-08 20:28:32 -05005700bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005701{
5702 Program *programObject = GetValidProgram(context, program);
5703
5704 if (!programObject)
5705 {
5706 return false;
5707 }
5708
5709 return true;
5710}
5711
Jamie Madill5b772312018-03-08 20:28:32 -05005712bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005713{
5714 return ValidateVertexAttribIndex(context, index);
5715}
5716
Jamie Madill5b772312018-03-08 20:28:32 -05005717bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005718{
5719 return ValidateVertexAttribIndex(context, index);
5720}
5721
Jamie Madill5b772312018-03-08 20:28:32 -05005722bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005723{
5724 return ValidateVertexAttribIndex(context, index);
5725}
5726
Jamie Madill5b772312018-03-08 20:28:32 -05005727bool ValidateVertexAttrib2fv(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 ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005733{
5734 return ValidateVertexAttribIndex(context, index);
5735}
5736
Jamie Madill5b772312018-03-08 20:28:32 -05005737bool ValidateVertexAttrib3fv(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 ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005743 GLuint index,
5744 GLfloat x,
5745 GLfloat y,
5746 GLfloat z,
5747 GLfloat w)
5748{
5749 return ValidateVertexAttribIndex(context, index);
5750}
5751
Jamie Madill5b772312018-03-08 20:28:32 -05005752bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005753{
5754 return ValidateVertexAttribIndex(context, index);
5755}
5756
Jamie Madill5b772312018-03-08 20:28:32 -05005757bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005758{
5759 if (width < 0 || height < 0)
5760 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005761 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005762 return false;
5763 }
5764
5765 return true;
5766}
5767
Jamie Madill5b772312018-03-08 20:28:32 -05005768bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005769{
5770 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5771}
5772
Jamie Madill5b772312018-03-08 20:28:32 -05005773bool ValidateDrawElements(Context *context,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005774 GLenum mode,
5775 GLsizei count,
5776 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005777 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005778{
5779 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5780}
5781
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005782bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005783 GLenum target,
5784 GLenum attachment,
5785 GLenum pname,
5786 GLint *params)
5787{
5788 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5789 nullptr);
5790}
5791
Jamie Madill5b772312018-03-08 20:28:32 -05005792bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005793{
5794 return ValidateGetProgramivBase(context, program, pname, nullptr);
5795}
5796
Jamie Madill5b772312018-03-08 20:28:32 -05005797bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005798 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005799 GLint level,
5800 GLenum internalformat,
5801 GLint x,
5802 GLint y,
5803 GLsizei width,
5804 GLsizei height,
5805 GLint border)
5806{
5807 if (context->getClientMajorVersion() < 3)
5808 {
5809 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5810 0, x, y, width, height, border);
5811 }
5812
5813 ASSERT(context->getClientMajorVersion() == 3);
5814 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5815 0, x, y, width, height, border);
5816}
5817
5818bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005819 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005820 GLint level,
5821 GLint xoffset,
5822 GLint yoffset,
5823 GLint x,
5824 GLint y,
5825 GLsizei width,
5826 GLsizei height)
5827{
5828 if (context->getClientMajorVersion() < 3)
5829 {
5830 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5831 yoffset, x, y, width, height, 0);
5832 }
5833
5834 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5835 yoffset, 0, x, y, width, height, 0);
5836}
5837
5838bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5839{
5840 return ValidateGenOrDelete(context, n);
5841}
5842
5843bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5844{
5845 return ValidateGenOrDelete(context, n);
5846}
5847
5848bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5849{
5850 return ValidateGenOrDelete(context, n);
5851}
5852
5853bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5854{
5855 return ValidateGenOrDelete(context, n);
5856}
5857
5858bool ValidateDisable(Context *context, GLenum cap)
5859{
5860 if (!ValidCap(context, cap, false))
5861 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005862 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005863 return false;
5864 }
5865
5866 return true;
5867}
5868
5869bool ValidateEnable(Context *context, GLenum cap)
5870{
5871 if (!ValidCap(context, cap, false))
5872 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005873 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005874 return false;
5875 }
5876
5877 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5878 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5879 {
5880 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005881 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005882
5883 // We also output an error message to the debugger window if tracing is active, so that
5884 // developers can see the error message.
5885 ERR() << errorMessage;
5886 return false;
5887 }
5888
5889 return true;
5890}
5891
5892bool ValidateFramebufferRenderbuffer(Context *context,
5893 GLenum target,
5894 GLenum attachment,
5895 GLenum renderbuffertarget,
5896 GLuint renderbuffer)
5897{
Geoff Lange8afa902017-09-27 15:00:43 -04005898 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005899 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005900 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5901 return false;
5902 }
5903
5904 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5905 {
5906 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005907 return false;
5908 }
5909
5910 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5911 renderbuffertarget, renderbuffer);
5912}
5913
5914bool ValidateFramebufferTexture2D(Context *context,
5915 GLenum target,
5916 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005917 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005918 GLuint texture,
5919 GLint level)
5920{
5921 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5922 // extension
5923 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5924 level != 0)
5925 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005926 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005927 return false;
5928 }
5929
5930 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5931 {
5932 return false;
5933 }
5934
5935 if (texture != 0)
5936 {
5937 gl::Texture *tex = context->getTexture(texture);
5938 ASSERT(tex);
5939
5940 const gl::Caps &caps = context->getCaps();
5941
5942 switch (textarget)
5943 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005944 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005945 {
5946 if (level > gl::log2(caps.max2DTextureSize))
5947 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005948 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005949 return false;
5950 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005951 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005952 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005953 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005954 return false;
5955 }
5956 }
5957 break;
5958
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005959 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005960 {
5961 if (level != 0)
5962 {
5963 context->handleError(InvalidValue());
5964 return false;
5965 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005966 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005967 {
5968 context->handleError(InvalidOperation()
5969 << "Textarget must match the texture target type.");
5970 return false;
5971 }
5972 }
5973 break;
5974
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005975 case TextureTarget::CubeMapNegativeX:
5976 case TextureTarget::CubeMapNegativeY:
5977 case TextureTarget::CubeMapNegativeZ:
5978 case TextureTarget::CubeMapPositiveX:
5979 case TextureTarget::CubeMapPositiveY:
5980 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005981 {
5982 if (level > gl::log2(caps.maxCubeMapTextureSize))
5983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005984 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005985 return false;
5986 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005987 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04005988 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005989 context->handleError(InvalidOperation()
5990 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005991 return false;
5992 }
5993 }
5994 break;
5995
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005996 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04005997 {
5998 if (context->getClientVersion() < ES_3_1)
5999 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006000 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006001 return false;
6002 }
6003
6004 if (level != 0)
6005 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006006 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006007 return false;
6008 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006009 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006011 context->handleError(InvalidOperation()
6012 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 return false;
6014 }
6015 }
6016 break;
6017
6018 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006019 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006020 return false;
6021 }
6022
6023 const Format &format = tex->getFormat(textarget, level);
6024 if (format.info->compressed)
6025 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006026 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006027 return false;
6028 }
6029 }
6030
6031 return true;
6032}
6033
6034bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6035{
6036 return ValidateGenOrDelete(context, n);
6037}
6038
6039bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6040{
6041 return ValidateGenOrDelete(context, n);
6042}
6043
6044bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6045{
6046 return ValidateGenOrDelete(context, n);
6047}
6048
6049bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6050{
6051 return ValidateGenOrDelete(context, n);
6052}
6053
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006054bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006055{
6056 if (!ValidTextureTarget(context, target))
6057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006058 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006059 return false;
6060 }
6061
6062 Texture *texture = context->getTargetTexture(target);
6063
6064 if (texture == nullptr)
6065 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006066 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006067 return false;
6068 }
6069
6070 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6071
6072 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6073 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6074 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6075 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006076 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006077 return false;
6078 }
6079
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006080 TextureTarget baseTarget = (target == TextureType::CubeMap)
6081 ? TextureTarget::CubeMapPositiveX
6082 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006083 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6084 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6085 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006086 {
6087 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6088 return false;
6089 }
6090
Geoff Lang536eca12017-09-13 11:23:35 -04006091 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6092 bool formatUnsized = !format.sized;
6093 bool formatColorRenderableAndFilterable =
6094 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6095 format.renderSupport(context->getClientVersion(), context->getExtensions());
6096 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006097 {
Geoff Lang536eca12017-09-13 11:23:35 -04006098 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006099 return false;
6100 }
6101
Geoff Lang536eca12017-09-13 11:23:35 -04006102 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6103 // generation
6104 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6105 {
6106 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6107 return false;
6108 }
6109
6110 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6111 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006112 bool supportsSRGBMipmapGeneration =
6113 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006114 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006115 {
Geoff Lang536eca12017-09-13 11:23:35 -04006116 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006117 return false;
6118 }
6119
6120 // Non-power of 2 ES2 check
6121 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6122 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6123 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6124 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006125 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6126 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006127 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006128 return false;
6129 }
6130
6131 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006132 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006133 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006134 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006135 return false;
6136 }
6137
6138 return true;
6139}
6140
Jamie Madill5b772312018-03-08 20:28:32 -05006141bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006142 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006143 GLenum pname,
6144 GLint *params)
6145{
6146 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6147}
6148
6149bool ValidateGetRenderbufferParameteriv(Context *context,
6150 GLenum target,
6151 GLenum pname,
6152 GLint *params)
6153{
6154 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6155}
6156
6157bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6158{
6159 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6160}
6161
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006162bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006163{
6164 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6165}
6166
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006167bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006168{
6169 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6170}
6171
6172bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6173{
6174 return ValidateGetUniformBase(context, program, location);
6175}
6176
6177bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6178{
6179 return ValidateGetUniformBase(context, program, location);
6180}
6181
6182bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6183{
6184 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6185}
6186
6187bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6188{
6189 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6190}
6191
6192bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6193{
6194 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6195}
6196
6197bool ValidateIsEnabled(Context *context, GLenum cap)
6198{
6199 if (!ValidCap(context, cap, true))
6200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006201 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006202 return false;
6203 }
6204
6205 return true;
6206}
6207
6208bool ValidateLinkProgram(Context *context, GLuint program)
6209{
6210 if (context->hasActiveTransformFeedback(program))
6211 {
6212 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006213 context->handleError(InvalidOperation() << "Cannot link program while program is "
6214 "associated with an active transform "
6215 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006216 return false;
6217 }
6218
6219 Program *programObject = GetValidProgram(context, program);
6220 if (!programObject)
6221 {
6222 return false;
6223 }
6224
6225 return true;
6226}
6227
Jamie Madill4928b7c2017-06-20 12:57:39 -04006228bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006229 GLint x,
6230 GLint y,
6231 GLsizei width,
6232 GLsizei height,
6233 GLenum format,
6234 GLenum type,
6235 void *pixels)
6236{
6237 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6238 nullptr, pixels);
6239}
6240
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006241bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006242{
6243 return ValidateTexParameterBase(context, target, pname, -1, &param);
6244}
6245
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006246bool ValidateTexParameterfv(Context *context,
6247 TextureType target,
6248 GLenum pname,
6249 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006250{
6251 return ValidateTexParameterBase(context, target, pname, -1, params);
6252}
6253
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006254bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006255{
6256 return ValidateTexParameterBase(context, target, pname, -1, &param);
6257}
6258
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006259bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006260{
6261 return ValidateTexParameterBase(context, target, pname, -1, params);
6262}
6263
6264bool ValidateUseProgram(Context *context, GLuint program)
6265{
6266 if (program != 0)
6267 {
6268 Program *programObject = context->getProgram(program);
6269 if (!programObject)
6270 {
6271 // ES 3.1.0 section 7.3 page 72
6272 if (context->getShader(program))
6273 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006274 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006275 return false;
6276 }
6277 else
6278 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006279 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006280 return false;
6281 }
6282 }
6283 if (!programObject->isLinked())
6284 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006285 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006286 return false;
6287 }
6288 }
6289 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6290 {
6291 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006292 context
6293 ->handleError(InvalidOperation()
6294 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006295 return false;
6296 }
6297
6298 return true;
6299}
6300
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006301bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6302{
6303 if (!context->getExtensions().fence)
6304 {
6305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6306 return false;
6307 }
6308
6309 if (n < 0)
6310 {
6311 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6312 return false;
6313 }
6314
6315 return true;
6316}
6317
6318bool ValidateFinishFenceNV(Context *context, GLuint fence)
6319{
6320 if (!context->getExtensions().fence)
6321 {
6322 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6323 return false;
6324 }
6325
6326 FenceNV *fenceObject = context->getFenceNV(fence);
6327
6328 if (fenceObject == nullptr)
6329 {
6330 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6331 return false;
6332 }
6333
6334 if (!fenceObject->isSet())
6335 {
6336 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6337 return false;
6338 }
6339
6340 return true;
6341}
6342
6343bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6344{
6345 if (!context->getExtensions().fence)
6346 {
6347 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6348 return false;
6349 }
6350
6351 if (n < 0)
6352 {
6353 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6354 return false;
6355 }
6356
6357 return true;
6358}
6359
6360bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6361{
6362 if (!context->getExtensions().fence)
6363 {
6364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6365 return false;
6366 }
6367
6368 FenceNV *fenceObject = context->getFenceNV(fence);
6369
6370 if (fenceObject == nullptr)
6371 {
6372 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6373 return false;
6374 }
6375
6376 if (!fenceObject->isSet())
6377 {
6378 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6379 return false;
6380 }
6381
6382 switch (pname)
6383 {
6384 case GL_FENCE_STATUS_NV:
6385 case GL_FENCE_CONDITION_NV:
6386 break;
6387
6388 default:
6389 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6390 return false;
6391 }
6392
6393 return true;
6394}
6395
6396bool ValidateGetGraphicsResetStatusEXT(Context *context)
6397{
6398 if (!context->getExtensions().robustness)
6399 {
6400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6401 return false;
6402 }
6403
6404 return true;
6405}
6406
6407bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6408 GLuint shader,
6409 GLsizei bufsize,
6410 GLsizei *length,
6411 GLchar *source)
6412{
6413 if (!context->getExtensions().translatedShaderSource)
6414 {
6415 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6416 return false;
6417 }
6418
6419 if (bufsize < 0)
6420 {
6421 context->handleError(InvalidValue());
6422 return false;
6423 }
6424
6425 Shader *shaderObject = context->getShader(shader);
6426
6427 if (!shaderObject)
6428 {
6429 context->handleError(InvalidOperation());
6430 return false;
6431 }
6432
6433 return true;
6434}
6435
6436bool ValidateIsFenceNV(Context *context, GLuint fence)
6437{
6438 if (!context->getExtensions().fence)
6439 {
6440 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6441 return false;
6442 }
6443
6444 return true;
6445}
6446
Jamie Madill007530e2017-12-28 14:27:04 -05006447bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6448{
6449 if (!context->getExtensions().fence)
6450 {
6451 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6452 return false;
6453 }
6454
6455 if (condition != GL_ALL_COMPLETED_NV)
6456 {
6457 context->handleError(InvalidEnum());
6458 return false;
6459 }
6460
6461 FenceNV *fenceObject = context->getFenceNV(fence);
6462
6463 if (fenceObject == nullptr)
6464 {
6465 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6466 return false;
6467 }
6468
6469 return true;
6470}
6471
6472bool ValidateTestFenceNV(Context *context, GLuint fence)
6473{
6474 if (!context->getExtensions().fence)
6475 {
6476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6477 return false;
6478 }
6479
6480 FenceNV *fenceObject = context->getFenceNV(fence);
6481
6482 if (fenceObject == nullptr)
6483 {
6484 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6485 return false;
6486 }
6487
6488 if (fenceObject->isSet() != GL_TRUE)
6489 {
6490 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6491 return false;
6492 }
6493
6494 return true;
6495}
6496
6497bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006498 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006499 GLsizei levels,
6500 GLenum internalformat,
6501 GLsizei width,
6502 GLsizei height)
6503{
6504 if (!context->getExtensions().textureStorage)
6505 {
6506 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6507 return false;
6508 }
6509
6510 if (context->getClientMajorVersion() < 3)
6511 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006512 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006513 height);
6514 }
6515
6516 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006517 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006518 1);
6519}
6520
6521bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6522{
6523 if (!context->getExtensions().instancedArrays)
6524 {
6525 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6526 return false;
6527 }
6528
6529 if (index >= MAX_VERTEX_ATTRIBS)
6530 {
6531 context->handleError(InvalidValue());
6532 return false;
6533 }
6534
6535 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6536 {
6537 if (index == 0 && divisor != 0)
6538 {
6539 const char *errorMessage =
6540 "The current context doesn't support setting a non-zero divisor on the "
6541 "attribute with index zero. "
6542 "Please reorder the attributes in your vertex shader so that attribute zero "
6543 "can have a zero divisor.";
6544 context->handleError(InvalidOperation() << errorMessage);
6545
6546 // We also output an error message to the debugger window if tracing is active, so
6547 // that developers can see the error message.
6548 ERR() << errorMessage;
6549 return false;
6550 }
6551 }
6552
6553 return true;
6554}
6555
6556bool ValidateTexImage3DOES(Context *context,
6557 GLenum target,
6558 GLint level,
6559 GLenum internalformat,
6560 GLsizei width,
6561 GLsizei height,
6562 GLsizei depth,
6563 GLint border,
6564 GLenum format,
6565 GLenum type,
6566 const void *pixels)
6567{
6568 UNIMPLEMENTED(); // FIXME
6569 return false;
6570}
6571
6572bool ValidatePopGroupMarkerEXT(Context *context)
6573{
6574 if (!context->getExtensions().debugMarker)
6575 {
6576 // The debug marker calls should not set error state
6577 // However, it seems reasonable to set an error state if the extension is not enabled
6578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6579 return false;
6580 }
6581
6582 return true;
6583}
6584
Jamie Madillfa920eb2018-01-04 11:45:50 -05006585bool ValidateTexStorage1DEXT(Context *context,
6586 GLenum target,
6587 GLsizei levels,
6588 GLenum internalformat,
6589 GLsizei width)
6590{
6591 UNIMPLEMENTED();
6592 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6593 return false;
6594}
6595
6596bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006597 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006598 GLsizei levels,
6599 GLenum internalformat,
6600 GLsizei width,
6601 GLsizei height,
6602 GLsizei depth)
6603{
6604 if (!context->getExtensions().textureStorage)
6605 {
6606 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6607 return false;
6608 }
6609
6610 if (context->getClientMajorVersion() < 3)
6611 {
6612 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6613 return false;
6614 }
6615
6616 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6617 depth);
6618}
6619
Jamie Madillc29968b2016-01-20 11:17:23 -05006620} // namespace gl