blob: d9261c5a20e1f43869cbd0ceaf27ec98b7345693 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
78 if (context->hasPath(pathName) && !context->hasPathData(pathName))
79 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madill5b772312018-03-08 20:28:32 -0500458bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
795 default:
796 return false;
797 }
798}
799
Geoff Langfc32e8b2017-05-31 14:16:59 -0400800// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
801// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400802bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400803{
804 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400805 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
806 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400807 {
808 return true;
809 }
810
811 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
812 if (c >= 9 && c <= 13)
813 {
814 return true;
815 }
816
817 return false;
818}
819
Geoff Langcab92ee2017-07-19 17:32:07 -0400820bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400821{
Geoff Langa71a98e2017-06-19 15:15:00 -0400822 for (size_t i = 0; i < len; i++)
823 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400824 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400825 {
826 return false;
827 }
828 }
829
830 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400831}
832
Geoff Langcab92ee2017-07-19 17:32:07 -0400833bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
834{
835 enum class ParseState
836 {
837 // Have not seen an ASCII non-whitespace character yet on
838 // this line. Possible that we might see a preprocessor
839 // directive.
840 BEGINING_OF_LINE,
841
842 // Have seen at least one ASCII non-whitespace character
843 // on this line.
844 MIDDLE_OF_LINE,
845
846 // Handling a preprocessor directive. Passes through all
847 // characters up to the end of the line. Disables comment
848 // processing.
849 IN_PREPROCESSOR_DIRECTIVE,
850
851 // Handling a single-line comment. The comment text is
852 // replaced with a single space.
853 IN_SINGLE_LINE_COMMENT,
854
855 // Handling a multi-line comment. Newlines are passed
856 // through to preserve line numbers.
857 IN_MULTI_LINE_COMMENT
858 };
859
860 ParseState state = ParseState::BEGINING_OF_LINE;
861 size_t pos = 0;
862
863 while (pos < len)
864 {
865 char c = str[pos];
866 char next = pos + 1 < len ? str[pos + 1] : 0;
867
868 // Check for newlines
869 if (c == '\n' || c == '\r')
870 {
871 if (state != ParseState::IN_MULTI_LINE_COMMENT)
872 {
873 state = ParseState::BEGINING_OF_LINE;
874 }
875
876 pos++;
877 continue;
878 }
879
880 switch (state)
881 {
882 case ParseState::BEGINING_OF_LINE:
883 if (c == ' ')
884 {
885 // Maintain the BEGINING_OF_LINE state until a non-space is seen
886 pos++;
887 }
888 else if (c == '#')
889 {
890 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
891 pos++;
892 }
893 else
894 {
895 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
896 state = ParseState::MIDDLE_OF_LINE;
897 }
898 break;
899
900 case ParseState::MIDDLE_OF_LINE:
901 if (c == '/' && next == '/')
902 {
903 state = ParseState::IN_SINGLE_LINE_COMMENT;
904 pos++;
905 }
906 else if (c == '/' && next == '*')
907 {
908 state = ParseState::IN_MULTI_LINE_COMMENT;
909 pos++;
910 }
911 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
912 {
913 // Skip line continuation characters
914 }
915 else if (!IsValidESSLCharacter(c))
916 {
917 return false;
918 }
919 pos++;
920 break;
921
922 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700923 // Line-continuation characters may not be permitted.
924 // Otherwise, just pass it through. Do not parse comments in this state.
925 if (!lineContinuationAllowed && c == '\\')
926 {
927 return false;
928 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400929 pos++;
930 break;
931
932 case ParseState::IN_SINGLE_LINE_COMMENT:
933 // Line-continuation characters are processed before comment processing.
934 // Advance string if a new line character is immediately behind
935 // line-continuation character.
936 if (c == '\\' && (next == '\n' || next == '\r'))
937 {
938 pos++;
939 }
940 pos++;
941 break;
942
943 case ParseState::IN_MULTI_LINE_COMMENT:
944 if (c == '*' && next == '/')
945 {
946 state = ParseState::MIDDLE_OF_LINE;
947 pos++;
948 }
949 pos++;
950 break;
951 }
952 }
953
954 return true;
955}
956
Jamie Madill5b772312018-03-08 20:28:32 -0500957bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700958{
959 ASSERT(context->isWebGL());
960
961 // WebGL 1.0 [Section 6.16] GLSL Constructs
962 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
963 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
964 {
965 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
966 return false;
967 }
968
969 return true;
970}
971
Jamie Madill5b772312018-03-08 20:28:32 -0500972bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700973{
974 ASSERT(context->isWebGL());
975
976 if (context->isWebGL1() && length > 256)
977 {
978 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
979 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
980 // locations.
981 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
982
983 return false;
984 }
985 else if (length > 1024)
986 {
987 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
988 // uniform and attribute locations.
989 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
990 return false;
991 }
992
993 return true;
994}
995
Jamie Madill007530e2017-12-28 14:27:04 -0500996bool ValidateMatrixMode(Context *context, GLenum matrixMode)
997{
998 if (!context->getExtensions().pathRendering)
999 {
1000 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1001 return false;
1002 }
1003
1004 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1005 {
1006 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1007 return false;
1008 }
1009 return true;
1010}
Jamie Madillc29968b2016-01-20 11:17:23 -05001011} // anonymous namespace
1012
Geoff Langff5b2d52016-09-07 11:32:23 -04001013bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001014 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001015 GLint level,
1016 GLenum internalformat,
1017 bool isCompressed,
1018 bool isSubImage,
1019 GLint xoffset,
1020 GLint yoffset,
1021 GLsizei width,
1022 GLsizei height,
1023 GLint border,
1024 GLenum format,
1025 GLenum type,
1026 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001027 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001028{
Jamie Madill6f38f822014-06-06 17:12:20 -04001029 if (!ValidTexture2DDestinationTarget(context, target))
1030 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001031 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001032 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001033 }
1034
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001035 TextureType texType = TextureTargetToType(target);
1036 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001037 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001038 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001039 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001040 }
1041
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001042 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001043 {
1044 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1045 return false;
1046 }
1047
1048 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001049 std::numeric_limits<GLsizei>::max() - yoffset < height)
1050 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001051 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001052 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001053 }
1054
Geoff Lang6e898aa2017-06-02 11:17:26 -04001055 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1056 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1057 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1058 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1059 // case.
1060 bool nonEqualFormatsAllowed =
1061 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1062 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1063
1064 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001065 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001066 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001067 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001068 }
1069
Geoff Langaae65a42014-05-26 12:43:44 -04001070 const gl::Caps &caps = context->getCaps();
1071
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001072 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001073 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001074 case TextureType::_2D:
1075 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1076 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1077 {
1078 context->handleError(InvalidValue());
1079 return false;
1080 }
1081 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001082
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001083 case TextureType::Rectangle:
1084 ASSERT(level == 0);
1085 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1086 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1087 {
1088 context->handleError(InvalidValue());
1089 return false;
1090 }
1091 if (isCompressed)
1092 {
1093 context->handleError(InvalidEnum()
1094 << "Rectangle texture cannot have a compressed format.");
1095 return false;
1096 }
1097 break;
1098
1099 case TextureType::CubeMap:
1100 if (!isSubImage && width != height)
1101 {
1102 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1103 return false;
1104 }
1105
1106 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1107 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1108 {
1109 context->handleError(InvalidValue());
1110 return false;
1111 }
1112 break;
1113
1114 default:
1115 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001116 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001117 }
1118
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001119 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001120 if (!texture)
1121 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001122 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001123 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001124 }
1125
Geoff Langa9be0dc2014-12-17 12:34:40 -05001126 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001127 {
Geoff Langca271392017-04-05 12:30:00 -04001128 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1129 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001131 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001132 return false;
1133 }
1134
Geoff Langa9be0dc2014-12-17 12:34:40 -05001135 if (format != GL_NONE)
1136 {
Geoff Langca271392017-04-05 12:30:00 -04001137 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1138 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001139 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001140 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001141 return false;
1142 }
1143 }
1144
1145 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1146 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001148 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001149 return false;
1150 }
Geoff Langfb052642017-10-24 13:42:09 -04001151
1152 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001153 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001154 {
1155 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1156 return false;
1157 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001158 }
1159 else
1160 {
Geoff Lang69cce582015-09-17 13:20:36 -04001161 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001163 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001164 return false;
1165 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001166 }
1167
1168 // Verify zero border
1169 if (border != 0)
1170 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001171 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001172 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001173 }
1174
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001175 if (isCompressed)
1176 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001177 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001178 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1179 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001180 switch (actualInternalFormat)
1181 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001182 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1183 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1184 if (!context->getExtensions().textureCompressionDXT1)
1185 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001186 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001187 return false;
1188 }
1189 break;
1190 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001191 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001192 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001193 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001194 return false;
1195 }
1196 break;
1197 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1198 if (!context->getExtensions().textureCompressionDXT5)
1199 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001201 return false;
1202 }
1203 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001204 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1205 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1206 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1207 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1208 if (!context->getExtensions().textureCompressionS3TCsRGB)
1209 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001210 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001211 return false;
1212 }
1213 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001214 case GL_ETC1_RGB8_OES:
1215 if (!context->getExtensions().compressedETC1RGB8Texture)
1216 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001217 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001218 return false;
1219 }
Geoff Lang86f81162017-10-30 15:10:45 -04001220 if (isSubImage)
1221 {
1222 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1223 return false;
1224 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001225 break;
1226 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001227 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1228 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1229 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1230 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001231 if (!context->getExtensions().lossyETCDecode)
1232 {
Geoff Lang86f81162017-10-30 15:10:45 -04001233 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001234 return false;
1235 }
1236 break;
1237 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001238 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001239 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001240 }
Geoff Lang966c9402017-04-18 12:38:27 -04001241
1242 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001243 {
Geoff Lang966c9402017-04-18 12:38:27 -04001244 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1245 height, texture->getWidth(target, level),
1246 texture->getHeight(target, level)))
1247 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001248 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001249 return false;
1250 }
1251
1252 if (format != actualInternalFormat)
1253 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001254 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001255 return false;
1256 }
1257 }
1258 else
1259 {
1260 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1261 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001262 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001263 return false;
1264 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001265 }
1266 }
1267 else
1268 {
1269 // validate <type> by itself (used as secondary key below)
1270 switch (type)
1271 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001272 case GL_UNSIGNED_BYTE:
1273 case GL_UNSIGNED_SHORT_5_6_5:
1274 case GL_UNSIGNED_SHORT_4_4_4_4:
1275 case GL_UNSIGNED_SHORT_5_5_5_1:
1276 case GL_UNSIGNED_SHORT:
1277 case GL_UNSIGNED_INT:
1278 case GL_UNSIGNED_INT_24_8_OES:
1279 case GL_HALF_FLOAT_OES:
1280 case GL_FLOAT:
1281 break;
1282 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001283 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001284 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001285 }
1286
1287 // validate <format> + <type> combinations
1288 // - invalid <format> -> sets INVALID_ENUM
1289 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1290 switch (format)
1291 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001292 case GL_ALPHA:
1293 case GL_LUMINANCE:
1294 case GL_LUMINANCE_ALPHA:
1295 switch (type)
1296 {
1297 case GL_UNSIGNED_BYTE:
1298 case GL_FLOAT:
1299 case GL_HALF_FLOAT_OES:
1300 break;
1301 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001302 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 return false;
1304 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001305 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001306 case GL_RED:
1307 case GL_RG:
1308 if (!context->getExtensions().textureRG)
1309 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001310 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001311 return false;
1312 }
1313 switch (type)
1314 {
1315 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001316 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001317 case GL_FLOAT:
1318 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001319 if (!context->getExtensions().textureFloat)
1320 {
1321 context->handleError(InvalidEnum());
1322 return false;
1323 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001324 break;
1325 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001326 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001327 return false;
1328 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001330 case GL_RGB:
1331 switch (type)
1332 {
1333 case GL_UNSIGNED_BYTE:
1334 case GL_UNSIGNED_SHORT_5_6_5:
1335 case GL_FLOAT:
1336 case GL_HALF_FLOAT_OES:
1337 break;
1338 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001339 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001340 return false;
1341 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001342 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001343 case GL_RGBA:
1344 switch (type)
1345 {
1346 case GL_UNSIGNED_BYTE:
1347 case GL_UNSIGNED_SHORT_4_4_4_4:
1348 case GL_UNSIGNED_SHORT_5_5_5_1:
1349 case GL_FLOAT:
1350 case GL_HALF_FLOAT_OES:
1351 break;
1352 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001354 return false;
1355 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001356 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001357 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001358 if (!context->getExtensions().textureFormatBGRA8888)
1359 {
1360 context->handleError(InvalidEnum());
1361 return false;
1362 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001363 switch (type)
1364 {
1365 case GL_UNSIGNED_BYTE:
1366 break;
1367 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 return false;
1370 }
1371 break;
1372 case GL_SRGB_EXT:
1373 case GL_SRGB_ALPHA_EXT:
1374 if (!context->getExtensions().sRGB)
1375 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001376 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001377 return false;
1378 }
1379 switch (type)
1380 {
1381 case GL_UNSIGNED_BYTE:
1382 break;
1383 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001384 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001385 return false;
1386 }
1387 break;
1388 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1389 // handled below
1390 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1391 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1392 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1393 break;
1394 case GL_DEPTH_COMPONENT:
1395 switch (type)
1396 {
1397 case GL_UNSIGNED_SHORT:
1398 case GL_UNSIGNED_INT:
1399 break;
1400 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001401 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001402 return false;
1403 }
1404 break;
1405 case GL_DEPTH_STENCIL_OES:
1406 switch (type)
1407 {
1408 case GL_UNSIGNED_INT_24_8_OES:
1409 break;
1410 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001411 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001412 return false;
1413 }
1414 break;
1415 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001416 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001417 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001418 }
1419
1420 switch (format)
1421 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001422 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1423 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1424 if (context->getExtensions().textureCompressionDXT1)
1425 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001426 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001427 return false;
1428 }
1429 else
1430 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001431 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001432 return false;
1433 }
1434 break;
1435 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1436 if (context->getExtensions().textureCompressionDXT3)
1437 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001438 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001439 return false;
1440 }
1441 else
1442 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001443 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001444 return false;
1445 }
1446 break;
1447 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1448 if (context->getExtensions().textureCompressionDXT5)
1449 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001450 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 return false;
1452 }
1453 else
1454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001455 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001456 return false;
1457 }
1458 break;
1459 case GL_ETC1_RGB8_OES:
1460 if (context->getExtensions().compressedETC1RGB8Texture)
1461 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001462 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001463 return false;
1464 }
1465 else
1466 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001467 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 return false;
1469 }
1470 break;
1471 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001472 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1473 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1474 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1475 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001476 if (context->getExtensions().lossyETCDecode)
1477 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001478 context->handleError(InvalidOperation()
1479 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001480 return false;
1481 }
1482 else
1483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001484 context->handleError(InvalidEnum()
1485 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001486 return false;
1487 }
1488 break;
1489 case GL_DEPTH_COMPONENT:
1490 case GL_DEPTH_STENCIL_OES:
1491 if (!context->getExtensions().depthTextures)
1492 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001493 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001494 return false;
1495 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001496 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001498 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001499 return false;
1500 }
1501 // OES_depth_texture supports loading depth data and multiple levels,
1502 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001503 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001504 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1506 return false;
1507 }
1508 if (level != 0)
1509 {
1510 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001511 return false;
1512 }
1513 break;
1514 default:
1515 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001516 }
1517
Geoff Lang6e898aa2017-06-02 11:17:26 -04001518 if (!isSubImage)
1519 {
1520 switch (internalformat)
1521 {
1522 case GL_RGBA32F:
1523 if (!context->getExtensions().colorBufferFloatRGBA)
1524 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001525 context->handleError(InvalidValue()
1526 << "Sized GL_RGBA32F internal format requires "
1527 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001528 return false;
1529 }
1530 if (type != GL_FLOAT)
1531 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001532 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001533 return false;
1534 }
1535 if (format != GL_RGBA)
1536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001537 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001538 return false;
1539 }
1540 break;
1541
1542 case GL_RGB32F:
1543 if (!context->getExtensions().colorBufferFloatRGB)
1544 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001545 context->handleError(InvalidValue()
1546 << "Sized GL_RGB32F internal format requires "
1547 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001548 return false;
1549 }
1550 if (type != GL_FLOAT)
1551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001552 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001553 return false;
1554 }
1555 if (format != GL_RGB)
1556 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001557 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001558 return false;
1559 }
1560 break;
1561
1562 default:
1563 break;
1564 }
1565 }
1566
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001567 if (type == GL_FLOAT)
1568 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001569 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001570 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001571 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001572 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001573 }
1574 }
1575 else if (type == GL_HALF_FLOAT_OES)
1576 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001577 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001578 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001579 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001580 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001581 }
1582 }
1583 }
1584
Geoff Langdbcced82017-06-06 15:55:54 -04001585 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001586 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001587 imageSize))
1588 {
1589 return false;
1590 }
1591
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001592 return true;
1593}
1594
He Yunchaoced53ae2016-11-29 15:00:51 +08001595bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001596 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001597 GLsizei levels,
1598 GLenum internalformat,
1599 GLsizei width,
1600 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001601{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001602 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1603 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001604 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001605 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001606 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001607 }
1608
1609 if (width < 1 || height < 1 || levels < 1)
1610 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001611 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001612 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001613 }
1614
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001615 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001616 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001617 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001618 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001619 }
1620
1621 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1622 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001623 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001624 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001625 }
1626
Geoff Langca271392017-04-05 12:30:00 -04001627 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001628 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001629 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001630 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001631 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001632 }
1633
Geoff Langaae65a42014-05-26 12:43:44 -04001634 const gl::Caps &caps = context->getCaps();
1635
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 switch (target)
1637 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001638 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001639 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1640 static_cast<GLuint>(height) > caps.max2DTextureSize)
1641 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001642 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001643 return false;
1644 }
1645 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001646 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001647 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1648 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1649 {
1650 context->handleError(InvalidValue());
1651 return false;
1652 }
1653 if (formatInfo.compressed)
1654 {
1655 context->handleError(InvalidEnum()
1656 << "Rectangle texture cannot have a compressed format.");
1657 return false;
1658 }
1659 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001660 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001661 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1662 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1663 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001664 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001665 return false;
1666 }
1667 break;
1668 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001669 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001670 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001671 }
1672
Geoff Langc0b9ef42014-07-02 10:02:37 -04001673 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001674 {
1675 if (!gl::isPow2(width) || !gl::isPow2(height))
1676 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001677 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001678 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001679 }
1680 }
1681
1682 switch (internalformat)
1683 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001684 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1685 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1686 if (!context->getExtensions().textureCompressionDXT1)
1687 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001688 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001689 return false;
1690 }
1691 break;
1692 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1693 if (!context->getExtensions().textureCompressionDXT3)
1694 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001695 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001696 return false;
1697 }
1698 break;
1699 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1700 if (!context->getExtensions().textureCompressionDXT5)
1701 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001702 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001703 return false;
1704 }
1705 break;
1706 case GL_ETC1_RGB8_OES:
1707 if (!context->getExtensions().compressedETC1RGB8Texture)
1708 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001709 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001710 return false;
1711 }
1712 break;
1713 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001714 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1715 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1716 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1717 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001718 if (!context->getExtensions().lossyETCDecode)
1719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001720 context->handleError(InvalidEnum()
1721 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001722 return false;
1723 }
1724 break;
1725 case GL_RGBA32F_EXT:
1726 case GL_RGB32F_EXT:
1727 case GL_ALPHA32F_EXT:
1728 case GL_LUMINANCE32F_EXT:
1729 case GL_LUMINANCE_ALPHA32F_EXT:
1730 if (!context->getExtensions().textureFloat)
1731 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001732 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001733 return false;
1734 }
1735 break;
1736 case GL_RGBA16F_EXT:
1737 case GL_RGB16F_EXT:
1738 case GL_ALPHA16F_EXT:
1739 case GL_LUMINANCE16F_EXT:
1740 case GL_LUMINANCE_ALPHA16F_EXT:
1741 if (!context->getExtensions().textureHalfFloat)
1742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001743 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001744 return false;
1745 }
1746 break;
1747 case GL_R8_EXT:
1748 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001749 if (!context->getExtensions().textureRG)
1750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001751 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001752 return false;
1753 }
1754 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001755 case GL_R16F_EXT:
1756 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001757 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001759 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001760 return false;
1761 }
1762 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001763 case GL_R32F_EXT:
1764 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001765 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001767 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001768 return false;
1769 }
1770 break;
1771 case GL_DEPTH_COMPONENT16:
1772 case GL_DEPTH_COMPONENT32_OES:
1773 case GL_DEPTH24_STENCIL8_OES:
1774 if (!context->getExtensions().depthTextures)
1775 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001776 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001777 return false;
1778 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001779 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001781 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001782 return false;
1783 }
1784 // ANGLE_depth_texture only supports 1-level textures
1785 if (levels != 1)
1786 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001787 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001788 return false;
1789 }
1790 break;
1791 default:
1792 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001793 }
1794
Geoff Lang691e58c2014-12-19 17:03:25 -05001795 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001796 if (!texture || texture->id() == 0)
1797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001798 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001799 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001800 }
1801
Geoff Lang69cce582015-09-17 13:20:36 -04001802 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001803 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001804 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001805 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001806 }
1807
1808 return true;
1809}
1810
He Yunchaoced53ae2016-11-29 15:00:51 +08001811bool ValidateDiscardFramebufferEXT(Context *context,
1812 GLenum target,
1813 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001814 const GLenum *attachments)
1815{
Jamie Madillc29968b2016-01-20 11:17:23 -05001816 if (!context->getExtensions().discardFramebuffer)
1817 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001818 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001819 return false;
1820 }
1821
Austin Kinross08332632015-05-05 13:35:47 -07001822 bool defaultFramebuffer = false;
1823
1824 switch (target)
1825 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001826 case GL_FRAMEBUFFER:
1827 defaultFramebuffer =
1828 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1829 break;
1830 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001831 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001832 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001833 }
1834
He Yunchaoced53ae2016-11-29 15:00:51 +08001835 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1836 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001837}
1838
Austin Kinrossbc781f32015-10-26 09:27:38 -07001839bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1840{
1841 if (!context->getExtensions().vertexArrayObject)
1842 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001843 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001844 return false;
1845 }
1846
1847 return ValidateBindVertexArrayBase(context, array);
1848}
1849
Jamie Madilld7576732017-08-26 18:49:50 -04001850bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001851{
1852 if (!context->getExtensions().vertexArrayObject)
1853 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001854 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001855 return false;
1856 }
1857
Olli Etuaho41997e72016-03-10 13:38:39 +02001858 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001859}
1860
Jamie Madilld7576732017-08-26 18:49:50 -04001861bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001862{
1863 if (!context->getExtensions().vertexArrayObject)
1864 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001865 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001866 return false;
1867 }
1868
Olli Etuaho41997e72016-03-10 13:38:39 +02001869 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870}
1871
Jamie Madilld7576732017-08-26 18:49:50 -04001872bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001873{
1874 if (!context->getExtensions().vertexArrayObject)
1875 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001876 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001877 return false;
1878 }
1879
1880 return true;
1881}
Geoff Langc5629752015-12-07 16:29:04 -05001882
1883bool ValidateProgramBinaryOES(Context *context,
1884 GLuint program,
1885 GLenum binaryFormat,
1886 const void *binary,
1887 GLint length)
1888{
1889 if (!context->getExtensions().getProgramBinary)
1890 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001891 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001892 return false;
1893 }
1894
1895 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1896}
1897
1898bool ValidateGetProgramBinaryOES(Context *context,
1899 GLuint program,
1900 GLsizei bufSize,
1901 GLsizei *length,
1902 GLenum *binaryFormat,
1903 void *binary)
1904{
1905 if (!context->getExtensions().getProgramBinary)
1906 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001907 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001908 return false;
1909 }
1910
1911 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1912}
Geoff Lange102fee2015-12-10 11:23:30 -05001913
Geoff Lang70d0f492015-12-10 17:45:46 -05001914static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1915{
1916 switch (source)
1917 {
1918 case GL_DEBUG_SOURCE_API:
1919 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1920 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1921 case GL_DEBUG_SOURCE_OTHER:
1922 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1923 return !mustBeThirdPartyOrApplication;
1924
1925 case GL_DEBUG_SOURCE_THIRD_PARTY:
1926 case GL_DEBUG_SOURCE_APPLICATION:
1927 return true;
1928
1929 default:
1930 return false;
1931 }
1932}
1933
1934static bool ValidDebugType(GLenum type)
1935{
1936 switch (type)
1937 {
1938 case GL_DEBUG_TYPE_ERROR:
1939 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1940 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1941 case GL_DEBUG_TYPE_PERFORMANCE:
1942 case GL_DEBUG_TYPE_PORTABILITY:
1943 case GL_DEBUG_TYPE_OTHER:
1944 case GL_DEBUG_TYPE_MARKER:
1945 case GL_DEBUG_TYPE_PUSH_GROUP:
1946 case GL_DEBUG_TYPE_POP_GROUP:
1947 return true;
1948
1949 default:
1950 return false;
1951 }
1952}
1953
1954static bool ValidDebugSeverity(GLenum severity)
1955{
1956 switch (severity)
1957 {
1958 case GL_DEBUG_SEVERITY_HIGH:
1959 case GL_DEBUG_SEVERITY_MEDIUM:
1960 case GL_DEBUG_SEVERITY_LOW:
1961 case GL_DEBUG_SEVERITY_NOTIFICATION:
1962 return true;
1963
1964 default:
1965 return false;
1966 }
1967}
1968
Geoff Lange102fee2015-12-10 11:23:30 -05001969bool ValidateDebugMessageControlKHR(Context *context,
1970 GLenum source,
1971 GLenum type,
1972 GLenum severity,
1973 GLsizei count,
1974 const GLuint *ids,
1975 GLboolean enabled)
1976{
1977 if (!context->getExtensions().debug)
1978 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001979 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001980 return false;
1981 }
1982
Geoff Lang70d0f492015-12-10 17:45:46 -05001983 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1984 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001986 return false;
1987 }
1988
1989 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1990 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001991 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001992 return false;
1993 }
1994
1995 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1996 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001997 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001998 return false;
1999 }
2000
2001 if (count > 0)
2002 {
2003 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2004 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002005 context->handleError(
2006 InvalidOperation()
2007 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002008 return false;
2009 }
2010
2011 if (severity != GL_DONT_CARE)
2012 {
Jamie Madill437fa652016-05-03 15:13:24 -04002013 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002014 InvalidOperation()
2015 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002016 return false;
2017 }
2018 }
2019
Geoff Lange102fee2015-12-10 11:23:30 -05002020 return true;
2021}
2022
2023bool ValidateDebugMessageInsertKHR(Context *context,
2024 GLenum source,
2025 GLenum type,
2026 GLuint id,
2027 GLenum severity,
2028 GLsizei length,
2029 const GLchar *buf)
2030{
2031 if (!context->getExtensions().debug)
2032 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002033 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002034 return false;
2035 }
2036
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002037 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002038 {
2039 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2040 // not generate an error.
2041 return false;
2042 }
2043
2044 if (!ValidDebugSeverity(severity))
2045 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002046 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002047 return false;
2048 }
2049
2050 if (!ValidDebugType(type))
2051 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002052 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002053 return false;
2054 }
2055
2056 if (!ValidDebugSource(source, true))
2057 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002058 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002059 return false;
2060 }
2061
2062 size_t messageLength = (length < 0) ? strlen(buf) : length;
2063 if (messageLength > context->getExtensions().maxDebugMessageLength)
2064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002065 context->handleError(InvalidValue()
2066 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002067 return false;
2068 }
2069
Geoff Lange102fee2015-12-10 11:23:30 -05002070 return true;
2071}
2072
2073bool ValidateDebugMessageCallbackKHR(Context *context,
2074 GLDEBUGPROCKHR callback,
2075 const void *userParam)
2076{
2077 if (!context->getExtensions().debug)
2078 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002079 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002080 return false;
2081 }
2082
Geoff Lange102fee2015-12-10 11:23:30 -05002083 return true;
2084}
2085
2086bool ValidateGetDebugMessageLogKHR(Context *context,
2087 GLuint count,
2088 GLsizei bufSize,
2089 GLenum *sources,
2090 GLenum *types,
2091 GLuint *ids,
2092 GLenum *severities,
2093 GLsizei *lengths,
2094 GLchar *messageLog)
2095{
2096 if (!context->getExtensions().debug)
2097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002098 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002099 return false;
2100 }
2101
Geoff Lang70d0f492015-12-10 17:45:46 -05002102 if (bufSize < 0 && messageLog != nullptr)
2103 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002104 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002105 return false;
2106 }
2107
Geoff Lange102fee2015-12-10 11:23:30 -05002108 return true;
2109}
2110
2111bool ValidatePushDebugGroupKHR(Context *context,
2112 GLenum source,
2113 GLuint id,
2114 GLsizei length,
2115 const GLchar *message)
2116{
2117 if (!context->getExtensions().debug)
2118 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002119 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002120 return false;
2121 }
2122
Geoff Lang70d0f492015-12-10 17:45:46 -05002123 if (!ValidDebugSource(source, true))
2124 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002125 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 return false;
2127 }
2128
2129 size_t messageLength = (length < 0) ? strlen(message) : length;
2130 if (messageLength > context->getExtensions().maxDebugMessageLength)
2131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002132 context->handleError(InvalidValue()
2133 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002134 return false;
2135 }
2136
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002137 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002138 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002140 context
2141 ->handleError(StackOverflow()
2142 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002143 return false;
2144 }
2145
Geoff Lange102fee2015-12-10 11:23:30 -05002146 return true;
2147}
2148
2149bool ValidatePopDebugGroupKHR(Context *context)
2150{
2151 if (!context->getExtensions().debug)
2152 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002153 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002154 return false;
2155 }
2156
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002157 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002158 if (currentStackSize <= 1)
2159 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002160 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002161 return false;
2162 }
2163
2164 return true;
2165}
2166
2167static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2168{
2169 switch (identifier)
2170 {
2171 case GL_BUFFER:
2172 if (context->getBuffer(name) == nullptr)
2173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002174 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002175 return false;
2176 }
2177 return true;
2178
2179 case GL_SHADER:
2180 if (context->getShader(name) == nullptr)
2181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002182 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002183 return false;
2184 }
2185 return true;
2186
2187 case GL_PROGRAM:
2188 if (context->getProgram(name) == nullptr)
2189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002190 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002191 return false;
2192 }
2193 return true;
2194
2195 case GL_VERTEX_ARRAY:
2196 if (context->getVertexArray(name) == nullptr)
2197 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002198 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 return false;
2200 }
2201 return true;
2202
2203 case GL_QUERY:
2204 if (context->getQuery(name) == nullptr)
2205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002206 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002207 return false;
2208 }
2209 return true;
2210
2211 case GL_TRANSFORM_FEEDBACK:
2212 if (context->getTransformFeedback(name) == nullptr)
2213 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002214 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002215 return false;
2216 }
2217 return true;
2218
2219 case GL_SAMPLER:
2220 if (context->getSampler(name) == nullptr)
2221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002222 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002223 return false;
2224 }
2225 return true;
2226
2227 case GL_TEXTURE:
2228 if (context->getTexture(name) == nullptr)
2229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002230 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 return false;
2232 }
2233 return true;
2234
2235 case GL_RENDERBUFFER:
2236 if (context->getRenderbuffer(name) == nullptr)
2237 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002238 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002239 return false;
2240 }
2241 return true;
2242
2243 case GL_FRAMEBUFFER:
2244 if (context->getFramebuffer(name) == nullptr)
2245 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002246 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002247 return false;
2248 }
2249 return true;
2250
2251 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002252 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002253 return false;
2254 }
Geoff Lange102fee2015-12-10 11:23:30 -05002255}
2256
Martin Radev9d901792016-07-15 15:58:58 +03002257static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2258{
2259 size_t labelLength = 0;
2260
2261 if (length < 0)
2262 {
2263 if (label != nullptr)
2264 {
2265 labelLength = strlen(label);
2266 }
2267 }
2268 else
2269 {
2270 labelLength = static_cast<size_t>(length);
2271 }
2272
2273 if (labelLength > context->getExtensions().maxLabelLength)
2274 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002275 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002276 return false;
2277 }
2278
2279 return true;
2280}
2281
Geoff Lange102fee2015-12-10 11:23:30 -05002282bool ValidateObjectLabelKHR(Context *context,
2283 GLenum identifier,
2284 GLuint name,
2285 GLsizei length,
2286 const GLchar *label)
2287{
2288 if (!context->getExtensions().debug)
2289 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002290 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002291 return false;
2292 }
2293
Geoff Lang70d0f492015-12-10 17:45:46 -05002294 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2295 {
2296 return false;
2297 }
2298
Martin Radev9d901792016-07-15 15:58:58 +03002299 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002300 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002301 return false;
2302 }
2303
Geoff Lange102fee2015-12-10 11:23:30 -05002304 return true;
2305}
2306
2307bool ValidateGetObjectLabelKHR(Context *context,
2308 GLenum identifier,
2309 GLuint name,
2310 GLsizei bufSize,
2311 GLsizei *length,
2312 GLchar *label)
2313{
2314 if (!context->getExtensions().debug)
2315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002317 return false;
2318 }
2319
Geoff Lang70d0f492015-12-10 17:45:46 -05002320 if (bufSize < 0)
2321 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002322 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002323 return false;
2324 }
2325
2326 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2327 {
2328 return false;
2329 }
2330
Martin Radev9d901792016-07-15 15:58:58 +03002331 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002332}
2333
2334static bool ValidateObjectPtrName(Context *context, const void *ptr)
2335{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002336 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002337 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002338 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002339 return false;
2340 }
2341
Geoff Lange102fee2015-12-10 11:23:30 -05002342 return true;
2343}
2344
2345bool ValidateObjectPtrLabelKHR(Context *context,
2346 const void *ptr,
2347 GLsizei length,
2348 const GLchar *label)
2349{
2350 if (!context->getExtensions().debug)
2351 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002352 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002353 return false;
2354 }
2355
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 if (!ValidateObjectPtrName(context, ptr))
2357 {
2358 return false;
2359 }
2360
Martin Radev9d901792016-07-15 15:58:58 +03002361 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002362 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002363 return false;
2364 }
2365
Geoff Lange102fee2015-12-10 11:23:30 -05002366 return true;
2367}
2368
2369bool ValidateGetObjectPtrLabelKHR(Context *context,
2370 const void *ptr,
2371 GLsizei bufSize,
2372 GLsizei *length,
2373 GLchar *label)
2374{
2375 if (!context->getExtensions().debug)
2376 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002377 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002378 return false;
2379 }
2380
Geoff Lang70d0f492015-12-10 17:45:46 -05002381 if (bufSize < 0)
2382 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002383 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002384 return false;
2385 }
2386
2387 if (!ValidateObjectPtrName(context, ptr))
2388 {
2389 return false;
2390 }
2391
Martin Radev9d901792016-07-15 15:58:58 +03002392 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002393}
2394
2395bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2396{
2397 if (!context->getExtensions().debug)
2398 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002400 return false;
2401 }
2402
Geoff Lang70d0f492015-12-10 17:45:46 -05002403 // TODO: represent this in Context::getQueryParameterInfo.
2404 switch (pname)
2405 {
2406 case GL_DEBUG_CALLBACK_FUNCTION:
2407 case GL_DEBUG_CALLBACK_USER_PARAM:
2408 break;
2409
2410 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002411 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002412 return false;
2413 }
2414
Geoff Lange102fee2015-12-10 11:23:30 -05002415 return true;
2416}
Jamie Madillc29968b2016-01-20 11:17:23 -05002417
2418bool ValidateBlitFramebufferANGLE(Context *context,
2419 GLint srcX0,
2420 GLint srcY0,
2421 GLint srcX1,
2422 GLint srcY1,
2423 GLint dstX0,
2424 GLint dstY0,
2425 GLint dstX1,
2426 GLint dstY1,
2427 GLbitfield mask,
2428 GLenum filter)
2429{
2430 if (!context->getExtensions().framebufferBlit)
2431 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002432 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002433 return false;
2434 }
2435
2436 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2437 {
2438 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002439 context->handleError(InvalidOperation() << "Scaling and flipping in "
2440 "BlitFramebufferANGLE not supported by this "
2441 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002442 return false;
2443 }
2444
2445 if (filter == GL_LINEAR)
2446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002447 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002448 return false;
2449 }
2450
Jamie Madill51f40ec2016-06-15 14:06:00 -04002451 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2452 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002453
2454 if (mask & GL_COLOR_BUFFER_BIT)
2455 {
2456 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2457 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2458
2459 if (readColorAttachment && drawColorAttachment)
2460 {
2461 if (!(readColorAttachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002462 readColorAttachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002463 readColorAttachment->type() != GL_RENDERBUFFER &&
2464 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002466 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002467 return false;
2468 }
2469
Geoff Langa15472a2015-08-11 11:48:03 -04002470 for (size_t drawbufferIdx = 0;
2471 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002472 {
Geoff Langa15472a2015-08-11 11:48:03 -04002473 const FramebufferAttachment *attachment =
2474 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2475 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002476 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002477 if (!(attachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002478 attachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002479 attachment->type() != GL_RENDERBUFFER &&
2480 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002482 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 return false;
2484 }
2485
2486 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002487 if (!Format::EquivalentForBlit(attachment->getFormat(),
2488 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002490 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 return false;
2492 }
2493 }
2494 }
2495
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002496 if (readFramebuffer->getSamples(context) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002497 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2498 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2499 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002500 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002501 return false;
2502 }
2503 }
2504 }
2505
2506 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2507 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2508 for (size_t i = 0; i < 2; i++)
2509 {
2510 if (mask & masks[i])
2511 {
2512 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002513 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002514 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002515 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002516
2517 if (readBuffer && drawBuffer)
2518 {
2519 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2520 dstX0, dstY0, dstX1, dstY1))
2521 {
2522 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002523 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2524 "stencil blits are supported by "
2525 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002526 return false;
2527 }
2528
2529 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2530 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002531 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002532 return false;
2533 }
2534 }
2535 }
2536 }
2537
2538 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2539 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002540}
Jamie Madillc29968b2016-01-20 11:17:23 -05002541
Jamie Madill5b772312018-03-08 20:28:32 -05002542bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002543{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002544 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002545 if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002546 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002547 context->handleError(InvalidFramebufferOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002548 return false;
2549 }
2550
2551 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002553 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002554 return false;
2555 }
2556
Geoff Lang76e65652017-03-27 14:58:02 -04002557 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2558 {
2559 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2560 GL_SIGNED_NORMALIZED};
2561
Corentin Wallez59c41592017-07-11 13:19:54 -04002562 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002563 drawBufferIdx++)
2564 {
2565 if (!ValidateWebGLFramebufferAttachmentClearType(
2566 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2567 {
2568 return false;
2569 }
2570 }
2571 }
2572
Jamie Madillc29968b2016-01-20 11:17:23 -05002573 return true;
2574}
2575
Jamie Madill5b772312018-03-08 20:28:32 -05002576bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002577{
2578 if (!context->getExtensions().drawBuffers)
2579 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002580 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002581 return false;
2582 }
2583
2584 return ValidateDrawBuffersBase(context, n, bufs);
2585}
2586
Jamie Madill73a84962016-02-12 09:27:23 -05002587bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002588 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002589 GLint level,
2590 GLint internalformat,
2591 GLsizei width,
2592 GLsizei height,
2593 GLint border,
2594 GLenum format,
2595 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002596 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002597{
Martin Radev1be913c2016-07-11 17:59:16 +03002598 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002599 {
2600 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002601 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002602 }
2603
Martin Radev1be913c2016-07-11 17:59:16 +03002604 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002605 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002606 0, 0, width, height, 1, border, format, type, -1,
2607 pixels);
2608}
2609
2610bool ValidateTexImage2DRobust(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002611 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04002612 GLint level,
2613 GLint internalformat,
2614 GLsizei width,
2615 GLsizei height,
2616 GLint border,
2617 GLenum format,
2618 GLenum type,
2619 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002620 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002621{
2622 if (!ValidateRobustEntryPoint(context, bufSize))
2623 {
2624 return false;
2625 }
2626
2627 if (context->getClientMajorVersion() < 3)
2628 {
2629 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2630 0, 0, width, height, border, format, type, bufSize,
2631 pixels);
2632 }
2633
2634 ASSERT(context->getClientMajorVersion() >= 3);
2635 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2636 0, 0, width, height, 1, border, format, type, bufSize,
2637 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002638}
2639
2640bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002641 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002642 GLint level,
2643 GLint xoffset,
2644 GLint yoffset,
2645 GLsizei width,
2646 GLsizei height,
2647 GLenum format,
2648 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002649 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002650{
2651
Martin Radev1be913c2016-07-11 17:59:16 +03002652 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002653 {
2654 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002655 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002656 }
2657
Martin Radev1be913c2016-07-11 17:59:16 +03002658 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002659 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002660 yoffset, 0, width, height, 1, 0, format, type, -1,
2661 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002662}
2663
Geoff Langc52f6f12016-10-14 10:18:00 -04002664bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002665 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002666 GLint level,
2667 GLint xoffset,
2668 GLint yoffset,
2669 GLsizei width,
2670 GLsizei height,
2671 GLenum format,
2672 GLenum type,
2673 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002674 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002675{
2676 if (!ValidateRobustEntryPoint(context, bufSize))
2677 {
2678 return false;
2679 }
2680
2681 if (context->getClientMajorVersion() < 3)
2682 {
2683 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2684 yoffset, width, height, 0, format, type, bufSize,
2685 pixels);
2686 }
2687
2688 ASSERT(context->getClientMajorVersion() >= 3);
2689 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2690 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2691 pixels);
2692}
2693
Jamie Madill73a84962016-02-12 09:27:23 -05002694bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002695 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002696 GLint level,
2697 GLenum internalformat,
2698 GLsizei width,
2699 GLsizei height,
2700 GLint border,
2701 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002702 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002703{
Martin Radev1be913c2016-07-11 17:59:16 +03002704 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002705 {
2706 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002707 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002708 {
2709 return false;
2710 }
2711 }
2712 else
2713 {
Martin Radev1be913c2016-07-11 17:59:16 +03002714 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002715 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002716 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002717 data))
2718 {
2719 return false;
2720 }
2721 }
2722
Geoff Langca271392017-04-05 12:30:00 -04002723 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002724 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002725 if (blockSizeOrErr.isError())
2726 {
2727 context->handleError(blockSizeOrErr.getError());
2728 return false;
2729 }
2730
2731 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002732 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002733 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002734 return false;
2735 }
2736
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002737 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002738 {
2739 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2740 return false;
2741 }
2742
Jamie Madill73a84962016-02-12 09:27:23 -05002743 return true;
2744}
2745
Corentin Wallezb2931602017-04-11 15:58:57 -04002746bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002747 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002748 GLint level,
2749 GLenum internalformat,
2750 GLsizei width,
2751 GLsizei height,
2752 GLint border,
2753 GLsizei imageSize,
2754 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002755 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002756{
2757 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2758 {
2759 return false;
2760 }
2761
2762 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2763 border, imageSize, data);
2764}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002765
Corentin Wallezb2931602017-04-11 15:58:57 -04002766bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002767 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002768 GLint level,
2769 GLint xoffset,
2770 GLint yoffset,
2771 GLsizei width,
2772 GLsizei height,
2773 GLenum format,
2774 GLsizei imageSize,
2775 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002776 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002777{
2778 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2779 {
2780 return false;
2781 }
2782
2783 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2784 format, imageSize, data);
2785}
2786
Jamie Madill73a84962016-02-12 09:27:23 -05002787bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002788 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002789 GLint level,
2790 GLint xoffset,
2791 GLint yoffset,
2792 GLsizei width,
2793 GLsizei height,
2794 GLenum format,
2795 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002796 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002797{
Martin Radev1be913c2016-07-11 17:59:16 +03002798 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002799 {
2800 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002801 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002802 {
2803 return false;
2804 }
2805 }
2806 else
2807 {
Martin Radev1be913c2016-07-11 17:59:16 +03002808 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002809 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002810 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002811 data))
2812 {
2813 return false;
2814 }
2815 }
2816
Geoff Langca271392017-04-05 12:30:00 -04002817 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002818 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002819 if (blockSizeOrErr.isError())
2820 {
2821 context->handleError(blockSizeOrErr.getError());
2822 return false;
2823 }
2824
2825 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002826 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002827 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002828 return false;
2829 }
2830
2831 return true;
2832}
2833
Corentin Wallez336129f2017-10-17 15:55:40 -04002834bool ValidateGetBufferPointervOES(Context *context,
2835 BufferBinding target,
2836 GLenum pname,
2837 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002838{
Geoff Lang496c02d2016-10-20 11:38:11 -07002839 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002840}
2841
Corentin Wallez336129f2017-10-17 15:55:40 -04002842bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002843{
2844 if (!context->getExtensions().mapBuffer)
2845 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002846 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002847 return false;
2848 }
2849
Corentin Walleze4477002017-12-01 14:39:58 -05002850 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002851 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002852 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002853 return false;
2854 }
2855
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002856 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002857
2858 if (buffer == nullptr)
2859 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002860 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002861 return false;
2862 }
2863
2864 if (access != GL_WRITE_ONLY_OES)
2865 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002866 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002867 return false;
2868 }
2869
2870 if (buffer->isMapped())
2871 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002872 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002873 return false;
2874 }
2875
Geoff Lang79f71042017-08-14 16:43:43 -04002876 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002877}
2878
Corentin Wallez336129f2017-10-17 15:55:40 -04002879bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002880{
2881 if (!context->getExtensions().mapBuffer)
2882 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002883 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002884 return false;
2885 }
2886
2887 return ValidateUnmapBufferBase(context, target);
2888}
2889
2890bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002891 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002892 GLintptr offset,
2893 GLsizeiptr length,
2894 GLbitfield access)
2895{
2896 if (!context->getExtensions().mapBufferRange)
2897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002898 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002899 return false;
2900 }
2901
2902 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2903}
2904
Corentin Wallez336129f2017-10-17 15:55:40 -04002905bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002906{
2907 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2908 ASSERT(buffer != nullptr);
2909
2910 // Check if this buffer is currently being used as a transform feedback output buffer
2911 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2912 if (transformFeedback != nullptr && transformFeedback->isActive())
2913 {
2914 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2915 {
2916 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2917 if (transformFeedbackBuffer.get() == buffer)
2918 {
2919 context->handleError(InvalidOperation()
2920 << "Buffer is currently bound for transform feedback.");
2921 return false;
2922 }
2923 }
2924 }
2925
James Darpiniane8a93c62018-01-04 18:02:24 -08002926 if (context->getExtensions().webglCompatibility &&
2927 buffer->isBoundForTransformFeedbackAndOtherUse())
2928 {
2929 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2930 return false;
2931 }
2932
Geoff Lang79f71042017-08-14 16:43:43 -04002933 return true;
2934}
2935
Olli Etuaho4f667482016-03-30 15:56:35 +03002936bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002937 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002938 GLintptr offset,
2939 GLsizeiptr length)
2940{
2941 if (!context->getExtensions().mapBufferRange)
2942 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002943 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002944 return false;
2945 }
2946
2947 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2948}
2949
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002950bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002951{
2952 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002953 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002954 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002955 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002956 return false;
2957 }
2958
Geoff Langf41a7152016-09-19 15:11:17 -04002959 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2960 !context->isTextureGenerated(texture))
2961 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002962 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002963 return false;
2964 }
2965
Ian Ewell54f87462016-03-10 13:47:21 -05002966 switch (target)
2967 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002968 case TextureType::_2D:
2969 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002970 break;
2971
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002972 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002973 if (!context->getExtensions().textureRectangle)
2974 {
2975 context->handleError(InvalidEnum()
2976 << "Context does not support GL_ANGLE_texture_rectangle");
2977 return false;
2978 }
2979 break;
2980
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002981 case TextureType::_3D:
2982 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002983 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002984 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002986 return false;
2987 }
2988 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002989
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002990 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04002991 if (context->getClientVersion() < Version(3, 1))
2992 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002993 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002994 return false;
2995 }
Geoff Lang3b573612016-10-31 14:08:10 -04002996 break;
2997
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002998 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04002999 if (!context->getExtensions().eglImageExternal &&
3000 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003001 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003002 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003003 return false;
3004 }
3005 break;
3006 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003007 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003008 return false;
3009 }
3010
3011 return true;
3012}
3013
Geoff Langd8605522016-04-13 10:19:12 -04003014bool ValidateBindUniformLocationCHROMIUM(Context *context,
3015 GLuint program,
3016 GLint location,
3017 const GLchar *name)
3018{
3019 if (!context->getExtensions().bindUniformLocation)
3020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003021 context->handleError(InvalidOperation()
3022 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003023 return false;
3024 }
3025
3026 Program *programObject = GetValidProgram(context, program);
3027 if (!programObject)
3028 {
3029 return false;
3030 }
3031
3032 if (location < 0)
3033 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003034 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003035 return false;
3036 }
3037
3038 const Caps &caps = context->getCaps();
3039 if (static_cast<size_t>(location) >=
3040 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003042 context->handleError(InvalidValue() << "Location must be less than "
3043 "(MAX_VERTEX_UNIFORM_VECTORS + "
3044 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003045 return false;
3046 }
3047
Geoff Langfc32e8b2017-05-31 14:16:59 -04003048 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3049 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003050 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003051 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003052 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003053 return false;
3054 }
3055
Geoff Langd8605522016-04-13 10:19:12 -04003056 if (strncmp(name, "gl_", 3) == 0)
3057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003058 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003059 return false;
3060 }
3061
3062 return true;
3063}
3064
Jamie Madille2e406c2016-06-02 13:04:10 -04003065bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003066{
3067 if (!context->getExtensions().framebufferMixedSamples)
3068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003069 context->handleError(InvalidOperation()
3070 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003071 return false;
3072 }
3073 switch (components)
3074 {
3075 case GL_RGB:
3076 case GL_RGBA:
3077 case GL_ALPHA:
3078 case GL_NONE:
3079 break;
3080 default:
3081 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003082 InvalidEnum()
3083 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003084 return false;
3085 }
3086
3087 return true;
3088}
3089
Sami Väisänene45e53b2016-05-25 10:36:04 +03003090// CHROMIUM_path_rendering
3091
Jamie Madill007530e2017-12-28 14:27:04 -05003092bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003093{
Jamie Madill007530e2017-12-28 14:27:04 -05003094 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003095 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003096 return false;
3097 }
Jamie Madill007530e2017-12-28 14:27:04 -05003098
Sami Väisänene45e53b2016-05-25 10:36:04 +03003099 if (matrix == nullptr)
3100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003101 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003102 return false;
3103 }
Jamie Madill007530e2017-12-28 14:27:04 -05003104
Sami Väisänene45e53b2016-05-25 10:36:04 +03003105 return true;
3106}
3107
Jamie Madill007530e2017-12-28 14:27:04 -05003108bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003109{
Jamie Madill007530e2017-12-28 14:27:04 -05003110 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111}
3112
Jamie Madill007530e2017-12-28 14:27:04 -05003113bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003114{
3115 if (!context->getExtensions().pathRendering)
3116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003117 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003118 return false;
3119 }
3120
3121 // range = 0 is undefined in NV_path_rendering.
3122 // we add stricter semantic check here and require a non zero positive range.
3123 if (range <= 0)
3124 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003125 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003126 return false;
3127 }
3128
3129 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3130 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003131 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003132 return false;
3133 }
3134
3135 return true;
3136}
3137
Jamie Madill007530e2017-12-28 14:27:04 -05003138bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003139{
3140 if (!context->getExtensions().pathRendering)
3141 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003142 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003143 return false;
3144 }
3145
3146 // range = 0 is undefined in NV_path_rendering.
3147 // we add stricter semantic check here and require a non zero positive range.
3148 if (range <= 0)
3149 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003150 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003151 return false;
3152 }
3153
3154 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3155 checkedRange += range;
3156
3157 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003160 return false;
3161 }
3162 return true;
3163}
3164
Jamie Madill007530e2017-12-28 14:27:04 -05003165bool ValidatePathCommandsCHROMIUM(Context *context,
3166 GLuint path,
3167 GLsizei numCommands,
3168 const GLubyte *commands,
3169 GLsizei numCoords,
3170 GLenum coordType,
3171 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003172{
3173 if (!context->getExtensions().pathRendering)
3174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003175 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003176 return false;
3177 }
3178 if (!context->hasPath(path))
3179 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003180 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181 return false;
3182 }
3183
3184 if (numCommands < 0)
3185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003186 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003187 return false;
3188 }
3189 else if (numCommands > 0)
3190 {
3191 if (!commands)
3192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003193 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003194 return false;
3195 }
3196 }
3197
3198 if (numCoords < 0)
3199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003200 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003201 return false;
3202 }
3203 else if (numCoords > 0)
3204 {
3205 if (!coords)
3206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003207 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003208 return false;
3209 }
3210 }
3211
3212 std::uint32_t coordTypeSize = 0;
3213 switch (coordType)
3214 {
3215 case GL_BYTE:
3216 coordTypeSize = sizeof(GLbyte);
3217 break;
3218
3219 case GL_UNSIGNED_BYTE:
3220 coordTypeSize = sizeof(GLubyte);
3221 break;
3222
3223 case GL_SHORT:
3224 coordTypeSize = sizeof(GLshort);
3225 break;
3226
3227 case GL_UNSIGNED_SHORT:
3228 coordTypeSize = sizeof(GLushort);
3229 break;
3230
3231 case GL_FLOAT:
3232 coordTypeSize = sizeof(GLfloat);
3233 break;
3234
3235 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003236 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003237 return false;
3238 }
3239
3240 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3241 checkedSize += (coordTypeSize * numCoords);
3242 if (!checkedSize.IsValid())
3243 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003244 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003245 return false;
3246 }
3247
3248 // early return skips command data validation when it doesn't exist.
3249 if (!commands)
3250 return true;
3251
3252 GLsizei expectedNumCoords = 0;
3253 for (GLsizei i = 0; i < numCommands; ++i)
3254 {
3255 switch (commands[i])
3256 {
3257 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3258 break;
3259 case GL_MOVE_TO_CHROMIUM:
3260 case GL_LINE_TO_CHROMIUM:
3261 expectedNumCoords += 2;
3262 break;
3263 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3264 expectedNumCoords += 4;
3265 break;
3266 case GL_CUBIC_CURVE_TO_CHROMIUM:
3267 expectedNumCoords += 6;
3268 break;
3269 case GL_CONIC_CURVE_TO_CHROMIUM:
3270 expectedNumCoords += 5;
3271 break;
3272 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003273 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003274 return false;
3275 }
3276 }
3277 if (expectedNumCoords != numCoords)
3278 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003279 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280 return false;
3281 }
3282
3283 return true;
3284}
3285
Jamie Madill007530e2017-12-28 14:27:04 -05003286bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003287{
3288 if (!context->getExtensions().pathRendering)
3289 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003290 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003291 return false;
3292 }
3293 if (!context->hasPath(path))
3294 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003296 return false;
3297 }
3298
3299 switch (pname)
3300 {
3301 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3302 if (value < 0.0f)
3303 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003304 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003305 return false;
3306 }
3307 break;
3308 case GL_PATH_END_CAPS_CHROMIUM:
3309 switch (static_cast<GLenum>(value))
3310 {
3311 case GL_FLAT_CHROMIUM:
3312 case GL_SQUARE_CHROMIUM:
3313 case GL_ROUND_CHROMIUM:
3314 break;
3315 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003316 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317 return false;
3318 }
3319 break;
3320 case GL_PATH_JOIN_STYLE_CHROMIUM:
3321 switch (static_cast<GLenum>(value))
3322 {
3323 case GL_MITER_REVERT_CHROMIUM:
3324 case GL_BEVEL_CHROMIUM:
3325 case GL_ROUND_CHROMIUM:
3326 break;
3327 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003328 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003329 return false;
3330 }
Nico Weber41b072b2018-02-09 10:01:32 -05003331 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003332 case GL_PATH_MITER_LIMIT_CHROMIUM:
3333 if (value < 0.0f)
3334 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003335 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003336 return false;
3337 }
3338 break;
3339
3340 case GL_PATH_STROKE_BOUND_CHROMIUM:
3341 // no errors, only clamping.
3342 break;
3343
3344 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003345 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003346 return false;
3347 }
3348 return true;
3349}
3350
Jamie Madill007530e2017-12-28 14:27:04 -05003351bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3352{
3353 // TODO(jmadill): Use proper clamping cast.
3354 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3355}
3356
3357bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003358{
3359 if (!context->getExtensions().pathRendering)
3360 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003361 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003362 return false;
3363 }
3364
3365 if (!context->hasPath(path))
3366 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003367 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003368 return false;
3369 }
3370 if (!value)
3371 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003372 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003373 return false;
3374 }
3375
3376 switch (pname)
3377 {
3378 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3379 case GL_PATH_END_CAPS_CHROMIUM:
3380 case GL_PATH_JOIN_STYLE_CHROMIUM:
3381 case GL_PATH_MITER_LIMIT_CHROMIUM:
3382 case GL_PATH_STROKE_BOUND_CHROMIUM:
3383 break;
3384
3385 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003386 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003387 return false;
3388 }
3389
3390 return true;
3391}
3392
Jamie Madill007530e2017-12-28 14:27:04 -05003393bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3394{
3395 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3396 reinterpret_cast<GLfloat *>(value));
3397}
3398
3399bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003400{
3401 if (!context->getExtensions().pathRendering)
3402 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003403 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003404 return false;
3405 }
3406
3407 switch (func)
3408 {
3409 case GL_NEVER:
3410 case GL_ALWAYS:
3411 case GL_LESS:
3412 case GL_LEQUAL:
3413 case GL_EQUAL:
3414 case GL_GEQUAL:
3415 case GL_GREATER:
3416 case GL_NOTEQUAL:
3417 break;
3418 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003419 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003420 return false;
3421 }
3422
3423 return true;
3424}
3425
3426// Note that the spec specifies that for the path drawing commands
3427// if the path object is not an existing path object the command
3428// does nothing and no error is generated.
3429// However if the path object exists but has not been specified any
3430// commands then an error is generated.
3431
Jamie Madill007530e2017-12-28 14:27:04 -05003432bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003433{
3434 if (!context->getExtensions().pathRendering)
3435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003436 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003437 return false;
3438 }
3439 if (context->hasPath(path) && !context->hasPathData(path))
3440 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003441 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003442 return false;
3443 }
3444
3445 switch (fillMode)
3446 {
3447 case GL_COUNT_UP_CHROMIUM:
3448 case GL_COUNT_DOWN_CHROMIUM:
3449 break;
3450 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003451 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003452 return false;
3453 }
3454
3455 if (!isPow2(mask + 1))
3456 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003457 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458 return false;
3459 }
3460
3461 return true;
3462}
3463
Jamie Madill007530e2017-12-28 14:27:04 -05003464bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003465{
3466 if (!context->getExtensions().pathRendering)
3467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003468 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003469 return false;
3470 }
3471 if (context->hasPath(path) && !context->hasPathData(path))
3472 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003473 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474 return false;
3475 }
3476
3477 return true;
3478}
3479
Jamie Madill007530e2017-12-28 14:27:04 -05003480bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003481{
3482 if (!context->getExtensions().pathRendering)
3483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003484 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003485 return false;
3486 }
3487 if (context->hasPath(path) && !context->hasPathData(path))
3488 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003489 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003490 return false;
3491 }
3492
3493 switch (coverMode)
3494 {
3495 case GL_CONVEX_HULL_CHROMIUM:
3496 case GL_BOUNDING_BOX_CHROMIUM:
3497 break;
3498 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003499 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003500 return false;
3501 }
3502 return true;
3503}
3504
Jamie Madill007530e2017-12-28 14:27:04 -05003505bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3506 GLuint path,
3507 GLenum fillMode,
3508 GLuint mask,
3509 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510{
Jamie Madill007530e2017-12-28 14:27:04 -05003511 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3512 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003513}
3514
Jamie Madill007530e2017-12-28 14:27:04 -05003515bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3516 GLuint path,
3517 GLint reference,
3518 GLuint mask,
3519 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003520{
Jamie Madill007530e2017-12-28 14:27:04 -05003521 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3522 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003523}
3524
Jamie Madill007530e2017-12-28 14:27:04 -05003525bool ValidateIsPathCHROMIUM(Context *context)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003526{
3527 if (!context->getExtensions().pathRendering)
3528 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003529 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003530 return false;
3531 }
3532 return true;
3533}
3534
Jamie Madill007530e2017-12-28 14:27:04 -05003535bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3536 GLsizei numPaths,
3537 GLenum pathNameType,
3538 const void *paths,
3539 GLuint pathBase,
3540 GLenum coverMode,
3541 GLenum transformType,
3542 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003543{
3544 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3545 transformType, transformValues))
3546 return false;
3547
3548 switch (coverMode)
3549 {
3550 case GL_CONVEX_HULL_CHROMIUM:
3551 case GL_BOUNDING_BOX_CHROMIUM:
3552 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3553 break;
3554 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003555 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003556 return false;
3557 }
3558
3559 return true;
3560}
3561
Jamie Madill007530e2017-12-28 14:27:04 -05003562bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3563 GLsizei numPaths,
3564 GLenum pathNameType,
3565 const void *paths,
3566 GLuint pathBase,
3567 GLenum coverMode,
3568 GLenum transformType,
3569 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003570{
3571 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3572 transformType, transformValues))
3573 return false;
3574
3575 switch (coverMode)
3576 {
3577 case GL_CONVEX_HULL_CHROMIUM:
3578 case GL_BOUNDING_BOX_CHROMIUM:
3579 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3580 break;
3581 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003582 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003583 return false;
3584 }
3585
3586 return true;
3587}
3588
Jamie Madill007530e2017-12-28 14:27:04 -05003589bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3590 GLsizei numPaths,
3591 GLenum pathNameType,
3592 const void *paths,
3593 GLuint pathBase,
3594 GLenum fillMode,
3595 GLuint mask,
3596 GLenum transformType,
3597 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003598{
3599
3600 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3601 transformType, transformValues))
3602 return false;
3603
3604 switch (fillMode)
3605 {
3606 case GL_COUNT_UP_CHROMIUM:
3607 case GL_COUNT_DOWN_CHROMIUM:
3608 break;
3609 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003610 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003611 return false;
3612 }
3613 if (!isPow2(mask + 1))
3614 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003615 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003616 return false;
3617 }
3618 return true;
3619}
3620
Jamie Madill007530e2017-12-28 14:27:04 -05003621bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3622 GLsizei numPaths,
3623 GLenum pathNameType,
3624 const void *paths,
3625 GLuint pathBase,
3626 GLint reference,
3627 GLuint mask,
3628 GLenum transformType,
3629 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003630{
3631 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3632 transformType, transformValues))
3633 return false;
3634
3635 // no more validation here.
3636
3637 return true;
3638}
3639
Jamie Madill007530e2017-12-28 14:27:04 -05003640bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3641 GLsizei numPaths,
3642 GLenum pathNameType,
3643 const void *paths,
3644 GLuint pathBase,
3645 GLenum fillMode,
3646 GLuint mask,
3647 GLenum coverMode,
3648 GLenum transformType,
3649 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003650{
3651 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3652 transformType, transformValues))
3653 return false;
3654
3655 switch (coverMode)
3656 {
3657 case GL_CONVEX_HULL_CHROMIUM:
3658 case GL_BOUNDING_BOX_CHROMIUM:
3659 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3660 break;
3661 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003662 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003663 return false;
3664 }
3665
3666 switch (fillMode)
3667 {
3668 case GL_COUNT_UP_CHROMIUM:
3669 case GL_COUNT_DOWN_CHROMIUM:
3670 break;
3671 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003672 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003673 return false;
3674 }
3675 if (!isPow2(mask + 1))
3676 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003677 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003678 return false;
3679 }
3680
3681 return true;
3682}
3683
Jamie Madill007530e2017-12-28 14:27:04 -05003684bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3685 GLsizei numPaths,
3686 GLenum pathNameType,
3687 const void *paths,
3688 GLuint pathBase,
3689 GLint reference,
3690 GLuint mask,
3691 GLenum coverMode,
3692 GLenum transformType,
3693 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003694{
3695 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3696 transformType, transformValues))
3697 return false;
3698
3699 switch (coverMode)
3700 {
3701 case GL_CONVEX_HULL_CHROMIUM:
3702 case GL_BOUNDING_BOX_CHROMIUM:
3703 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3704 break;
3705 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003706 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003707 return false;
3708 }
3709
3710 return true;
3711}
3712
Jamie Madill007530e2017-12-28 14:27:04 -05003713bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3714 GLuint program,
3715 GLint location,
3716 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003717{
3718 if (!context->getExtensions().pathRendering)
3719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003720 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003721 return false;
3722 }
3723
3724 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3725 if (location >= MaxLocation)
3726 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003727 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003728 return false;
3729 }
3730
3731 const auto *programObject = context->getProgram(program);
3732 if (!programObject)
3733 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003734 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003735 return false;
3736 }
3737
3738 if (!name)
3739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003740 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003741 return false;
3742 }
3743
3744 if (angle::BeginsWith(name, "gl_"))
3745 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003746 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003747 return false;
3748 }
3749
3750 return true;
3751}
3752
Jamie Madill007530e2017-12-28 14:27:04 -05003753bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3754 GLuint program,
3755 GLint location,
3756 GLenum genMode,
3757 GLint components,
3758 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003759{
3760 if (!context->getExtensions().pathRendering)
3761 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003762 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003763 return false;
3764 }
3765
3766 const auto *programObject = context->getProgram(program);
3767 if (!programObject || programObject->isFlaggedForDeletion())
3768 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003769 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003770 return false;
3771 }
3772
3773 if (!programObject->isLinked())
3774 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003775 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003776 return false;
3777 }
3778
3779 switch (genMode)
3780 {
3781 case GL_NONE:
3782 if (components != 0)
3783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003784 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003785 return false;
3786 }
3787 break;
3788
3789 case GL_OBJECT_LINEAR_CHROMIUM:
3790 case GL_EYE_LINEAR_CHROMIUM:
3791 case GL_CONSTANT_CHROMIUM:
3792 if (components < 1 || components > 4)
3793 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003794 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003795 return false;
3796 }
3797 if (!coeffs)
3798 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003799 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003800 return false;
3801 }
3802 break;
3803
3804 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003805 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003806 return false;
3807 }
3808
3809 // If the location is -1 then the command is silently ignored
3810 // and no further validation is needed.
3811 if (location == -1)
3812 return true;
3813
Jamie Madillbd044ed2017-06-05 12:59:21 -04003814 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003815
3816 if (!binding.valid)
3817 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003818 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003819 return false;
3820 }
3821
3822 if (binding.type != GL_NONE)
3823 {
3824 GLint expectedComponents = 0;
3825 switch (binding.type)
3826 {
3827 case GL_FLOAT:
3828 expectedComponents = 1;
3829 break;
3830 case GL_FLOAT_VEC2:
3831 expectedComponents = 2;
3832 break;
3833 case GL_FLOAT_VEC3:
3834 expectedComponents = 3;
3835 break;
3836 case GL_FLOAT_VEC4:
3837 expectedComponents = 4;
3838 break;
3839 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003840 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003841 InvalidOperation()
3842 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003843 return false;
3844 }
3845 if (expectedComponents != components && genMode != GL_NONE)
3846 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003847 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003848 return false;
3849 }
3850 }
3851 return true;
3852}
3853
Geoff Lang97073d12016-04-20 10:42:34 -07003854bool ValidateCopyTextureCHROMIUM(Context *context,
3855 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003856 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003857 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003858 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003859 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003860 GLint internalFormat,
3861 GLenum destType,
3862 GLboolean unpackFlipY,
3863 GLboolean unpackPremultiplyAlpha,
3864 GLboolean unpackUnmultiplyAlpha)
3865{
3866 if (!context->getExtensions().copyTexture)
3867 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003868 context->handleError(InvalidOperation()
3869 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003870 return false;
3871 }
3872
Geoff Lang4f0e0032017-05-01 16:04:35 -04003873 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003874 if (source == nullptr)
3875 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003876 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003877 return false;
3878 }
3879
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003880 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003881 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003882 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003883 return false;
3884 }
3885
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003886 TextureType sourceType = source->getType();
3887 ASSERT(sourceType != TextureType::CubeMap);
3888 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003889
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003890 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003892 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003893 return false;
3894 }
3895
Geoff Lang4f0e0032017-05-01 16:04:35 -04003896 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3897 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3898 if (sourceWidth == 0 || sourceHeight == 0)
3899 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003900 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003901 return false;
3902 }
3903
3904 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3905 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003906 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003907 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003908 return false;
3909 }
3910
Geoff Lang63458a32017-10-30 15:16:53 -04003911 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3912 {
3913 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3914 return false;
3915 }
3916
Geoff Lang4f0e0032017-05-01 16:04:35 -04003917 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003918 if (dest == nullptr)
3919 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003920 context->handleError(InvalidValue()
3921 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003922 return false;
3923 }
3924
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003925 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003926 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003927 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003928 return false;
3929 }
3930
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003931 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003932 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003933 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003934 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003935 return false;
3936 }
3937
Geoff Lang97073d12016-04-20 10:42:34 -07003938 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3939 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003940 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003941 return false;
3942 }
3943
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003944 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003945 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003946 context->handleError(
3947 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003948 return false;
3949 }
3950
Geoff Lang97073d12016-04-20 10:42:34 -07003951 if (dest->getImmutableFormat())
3952 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003953 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003954 return false;
3955 }
3956
3957 return true;
3958}
3959
3960bool ValidateCopySubTextureCHROMIUM(Context *context,
3961 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003962 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003963 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003964 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003965 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003966 GLint xoffset,
3967 GLint yoffset,
3968 GLint x,
3969 GLint y,
3970 GLsizei width,
3971 GLsizei height,
3972 GLboolean unpackFlipY,
3973 GLboolean unpackPremultiplyAlpha,
3974 GLboolean unpackUnmultiplyAlpha)
3975{
3976 if (!context->getExtensions().copyTexture)
3977 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003978 context->handleError(InvalidOperation()
3979 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003980 return false;
3981 }
3982
Geoff Lang4f0e0032017-05-01 16:04:35 -04003983 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003984 if (source == nullptr)
3985 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003986 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003987 return false;
3988 }
3989
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003990 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003991 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003992 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003993 return false;
3994 }
3995
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003996 TextureType sourceType = source->getType();
3997 ASSERT(sourceType != TextureType::CubeMap);
3998 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003999
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004000 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004001 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004002 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004003 return false;
4004 }
4005
4006 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4007 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004008 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004009 context->handleError(InvalidValue()
4010 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004011 return false;
4012 }
4013
4014 if (x < 0 || y < 0)
4015 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004016 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004017 return false;
4018 }
4019
4020 if (width < 0 || height < 0)
4021 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004022 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004023 return false;
4024 }
4025
Geoff Lang4f0e0032017-05-01 16:04:35 -04004026 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4027 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004028 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004029 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004030 return false;
4031 }
4032
Geoff Lang4f0e0032017-05-01 16:04:35 -04004033 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4034 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004035 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004036 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004037 return false;
4038 }
4039
Geoff Lang63458a32017-10-30 15:16:53 -04004040 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4041 {
4042 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4043 return false;
4044 }
4045
Geoff Lang4f0e0032017-05-01 16:04:35 -04004046 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004047 if (dest == nullptr)
4048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004049 context->handleError(InvalidValue()
4050 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004051 return false;
4052 }
4053
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004054 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004055 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004056 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004057 return false;
4058 }
4059
Brandon Jones28783792018-03-05 09:37:32 -08004060 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4061 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004062 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004063 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004064 return false;
4065 }
4066
Geoff Lang4f0e0032017-05-01 16:04:35 -04004067 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4068 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004069 context
4070 ->handleError(InvalidOperation()
4071 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004072 return false;
4073 }
4074
4075 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4076 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004077 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004078 context->handleError(InvalidOperation()
4079 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004080 return false;
4081 }
4082
4083 if (xoffset < 0 || yoffset < 0)
4084 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004085 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004086 return false;
4087 }
4088
Geoff Lang4f0e0032017-05-01 16:04:35 -04004089 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4090 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004091 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004092 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004093 return false;
4094 }
4095
4096 return true;
4097}
4098
Geoff Lang47110bf2016-04-20 11:13:22 -07004099bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4100{
4101 if (!context->getExtensions().copyCompressedTexture)
4102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004103 context->handleError(InvalidOperation()
4104 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004105 return false;
4106 }
4107
4108 const gl::Texture *source = context->getTexture(sourceId);
4109 if (source == nullptr)
4110 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004111 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004112 return false;
4113 }
4114
Corentin Wallez99d492c2018-02-27 15:17:10 -05004115 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004117 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004118 return false;
4119 }
4120
Corentin Wallez99d492c2018-02-27 15:17:10 -05004121 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4122 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004124 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004125 return false;
4126 }
4127
Corentin Wallez99d492c2018-02-27 15:17:10 -05004128 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004129 if (!sourceFormat.info->compressed)
4130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004131 context->handleError(InvalidOperation()
4132 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004133 return false;
4134 }
4135
4136 const gl::Texture *dest = context->getTexture(destId);
4137 if (dest == nullptr)
4138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004139 context->handleError(InvalidValue()
4140 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004141 return false;
4142 }
4143
Corentin Wallez99d492c2018-02-27 15:17:10 -05004144 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004145 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004146 context->handleError(InvalidValue()
4147 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004148 return false;
4149 }
4150
4151 if (dest->getImmutableFormat())
4152 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004153 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004154 return false;
4155 }
4156
4157 return true;
4158}
4159
Martin Radev4c4c8e72016-08-04 12:25:34 +03004160bool ValidateCreateShader(Context *context, GLenum type)
4161{
4162 switch (type)
4163 {
4164 case GL_VERTEX_SHADER:
4165 case GL_FRAGMENT_SHADER:
4166 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004167
Martin Radev4c4c8e72016-08-04 12:25:34 +03004168 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004169 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004170 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004171 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004172 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004173 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004174 break;
4175
Jiawei Shao89be29a2017-11-06 14:36:45 +08004176 case GL_GEOMETRY_SHADER_EXT:
4177 if (!context->getExtensions().geometryShader)
4178 {
4179 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4180 return false;
4181 }
4182 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004183 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004184 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004185 return false;
4186 }
Jamie Madill29639852016-09-02 15:00:09 -04004187
4188 return true;
4189}
4190
Jamie Madill5b772312018-03-08 20:28:32 -05004191bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004192 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004193 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004194 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004195 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004196{
4197 if (size < 0)
4198 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004199 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004200 return false;
4201 }
4202
4203 switch (usage)
4204 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004205 case BufferUsage::StreamDraw:
4206 case BufferUsage::StaticDraw:
4207 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004208 break;
4209
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004210 case BufferUsage::StreamRead:
4211 case BufferUsage::StaticRead:
4212 case BufferUsage::DynamicRead:
4213 case BufferUsage::StreamCopy:
4214 case BufferUsage::StaticCopy:
4215 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004216 if (context->getClientMajorVersion() < 3)
4217 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004218 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004219 return false;
4220 }
4221 break;
4222
4223 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004224 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004225 return false;
4226 }
4227
Corentin Walleze4477002017-12-01 14:39:58 -05004228 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004229 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004230 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004231 return false;
4232 }
4233
4234 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4235
4236 if (!buffer)
4237 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004238 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004239 return false;
4240 }
4241
James Darpiniane8a93c62018-01-04 18:02:24 -08004242 if (context->getExtensions().webglCompatibility &&
4243 buffer->isBoundForTransformFeedbackAndOtherUse())
4244 {
4245 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4246 return false;
4247 }
4248
Jamie Madill29639852016-09-02 15:00:09 -04004249 return true;
4250}
4251
Jamie Madill5b772312018-03-08 20:28:32 -05004252bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004253 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004254 GLintptr offset,
4255 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004256 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004257{
Brandon Jones6cad5662017-06-14 13:25:13 -07004258 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004259 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004260 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4261 return false;
4262 }
4263
4264 if (offset < 0)
4265 {
4266 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004267 return false;
4268 }
4269
Corentin Walleze4477002017-12-01 14:39:58 -05004270 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004271 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004272 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004273 return false;
4274 }
4275
4276 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4277
4278 if (!buffer)
4279 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004280 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004281 return false;
4282 }
4283
4284 if (buffer->isMapped())
4285 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004286 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004287 return false;
4288 }
4289
James Darpiniane8a93c62018-01-04 18:02:24 -08004290 if (context->getExtensions().webglCompatibility &&
4291 buffer->isBoundForTransformFeedbackAndOtherUse())
4292 {
4293 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4294 return false;
4295 }
4296
Jamie Madill29639852016-09-02 15:00:09 -04004297 // Check for possible overflow of size + offset
4298 angle::CheckedNumeric<size_t> checkedSize(size);
4299 checkedSize += offset;
4300 if (!checkedSize.IsValid())
4301 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004302 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004303 return false;
4304 }
4305
4306 if (size + offset > buffer->getSize())
4307 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004308 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004309 return false;
4310 }
4311
Martin Radev4c4c8e72016-08-04 12:25:34 +03004312 return true;
4313}
4314
Geoff Lang111a99e2017-10-17 10:58:41 -04004315bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004316{
Geoff Langc339c4e2016-11-29 10:37:36 -05004317 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004318 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004319 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004320 return false;
4321 }
4322
Geoff Lang111a99e2017-10-17 10:58:41 -04004323 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004324 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004325 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004326 return false;
4327 }
4328
4329 return true;
4330}
4331
Jamie Madill5b772312018-03-08 20:28:32 -05004332bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004333{
4334 if (texture < GL_TEXTURE0 ||
4335 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4336 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004337 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004338 return false;
4339 }
4340
4341 return true;
4342}
4343
Jamie Madill5b772312018-03-08 20:28:32 -05004344bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004345{
4346 Program *programObject = GetValidProgram(context, program);
4347 if (!programObject)
4348 {
4349 return false;
4350 }
4351
4352 Shader *shaderObject = GetValidShader(context, shader);
4353 if (!shaderObject)
4354 {
4355 return false;
4356 }
4357
4358 switch (shaderObject->getType())
4359 {
4360 case GL_VERTEX_SHADER:
4361 {
4362 if (programObject->getAttachedVertexShader())
4363 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004365 return false;
4366 }
4367 break;
4368 }
4369 case GL_FRAGMENT_SHADER:
4370 {
4371 if (programObject->getAttachedFragmentShader())
4372 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004373 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004374 return false;
4375 }
4376 break;
4377 }
4378 case GL_COMPUTE_SHADER:
4379 {
4380 if (programObject->getAttachedComputeShader())
4381 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004383 return false;
4384 }
4385 break;
4386 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004387 case GL_GEOMETRY_SHADER_EXT:
4388 {
4389 if (programObject->getAttachedGeometryShader())
4390 {
4391 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4392 return false;
4393 }
4394 break;
4395 }
Jamie Madillef300b12016-10-07 15:12:09 -04004396 default:
4397 UNREACHABLE();
4398 break;
4399 }
4400
4401 return true;
4402}
4403
Jamie Madill5b772312018-03-08 20:28:32 -05004404bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004405{
4406 if (index >= MAX_VERTEX_ATTRIBS)
4407 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004408 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004409 return false;
4410 }
4411
4412 if (strncmp(name, "gl_", 3) == 0)
4413 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004414 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004415 return false;
4416 }
4417
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004418 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004419 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004420 const size_t length = strlen(name);
4421
4422 if (!IsValidESSLString(name, length))
4423 {
4424 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4425 // for shader-related entry points
4426 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4427 return false;
4428 }
4429
4430 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4431 {
4432 return false;
4433 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004434 }
4435
Jamie Madill01a80ee2016-11-07 12:06:18 -05004436 return GetValidProgram(context, program) != nullptr;
4437}
4438
Jamie Madill5b772312018-03-08 20:28:32 -05004439bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004440{
Corentin Walleze4477002017-12-01 14:39:58 -05004441 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004442 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004443 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444 return false;
4445 }
4446
4447 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4448 !context->isBufferGenerated(buffer))
4449 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004450 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004451 return false;
4452 }
4453
4454 return true;
4455}
4456
Jamie Madill5b772312018-03-08 20:28:32 -05004457bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004458{
Geoff Lange8afa902017-09-27 15:00:43 -04004459 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004460 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004461 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004462 return false;
4463 }
4464
4465 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4466 !context->isFramebufferGenerated(framebuffer))
4467 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004468 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004469 return false;
4470 }
4471
4472 return true;
4473}
4474
Jamie Madill5b772312018-03-08 20:28:32 -05004475bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004476{
4477 if (target != GL_RENDERBUFFER)
4478 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004479 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004480 return false;
4481 }
4482
4483 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4484 !context->isRenderbufferGenerated(renderbuffer))
4485 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004486 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004487 return false;
4488 }
4489
4490 return true;
4491}
4492
Jamie Madill5b772312018-03-08 20:28:32 -05004493static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004494{
4495 switch (mode)
4496 {
4497 case GL_FUNC_ADD:
4498 case GL_FUNC_SUBTRACT:
4499 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004500 return true;
4501
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004502 case GL_MIN:
4503 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004504 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004505
4506 default:
4507 return false;
4508 }
4509}
4510
Jamie Madill5b772312018-03-08 20:28:32 -05004511bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004512{
4513 return true;
4514}
4515
Jamie Madill5b772312018-03-08 20:28:32 -05004516bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004517{
Geoff Lang50cac572017-09-26 17:37:43 -04004518 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004519 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004520 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004521 return false;
4522 }
4523
4524 return true;
4525}
4526
Jamie Madill5b772312018-03-08 20:28:32 -05004527bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004528{
Geoff Lang50cac572017-09-26 17:37:43 -04004529 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004530 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004531 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004532 return false;
4533 }
4534
Geoff Lang50cac572017-09-26 17:37:43 -04004535 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004537 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004538 return false;
4539 }
4540
4541 return true;
4542}
4543
Jamie Madill5b772312018-03-08 20:28:32 -05004544bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004545{
4546 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4547}
4548
4549static bool ValidSrcBlendFunc(GLenum srcBlend)
4550{
4551 switch (srcBlend)
4552 {
4553 case GL_ZERO:
4554 case GL_ONE:
4555 case GL_SRC_COLOR:
4556 case GL_ONE_MINUS_SRC_COLOR:
4557 case GL_DST_COLOR:
4558 case GL_ONE_MINUS_DST_COLOR:
4559 case GL_SRC_ALPHA:
4560 case GL_ONE_MINUS_SRC_ALPHA:
4561 case GL_DST_ALPHA:
4562 case GL_ONE_MINUS_DST_ALPHA:
4563 case GL_CONSTANT_COLOR:
4564 case GL_ONE_MINUS_CONSTANT_COLOR:
4565 case GL_CONSTANT_ALPHA:
4566 case GL_ONE_MINUS_CONSTANT_ALPHA:
4567 case GL_SRC_ALPHA_SATURATE:
4568 return true;
4569
4570 default:
4571 return false;
4572 }
4573}
4574
4575static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4576{
4577 switch (dstBlend)
4578 {
4579 case GL_ZERO:
4580 case GL_ONE:
4581 case GL_SRC_COLOR:
4582 case GL_ONE_MINUS_SRC_COLOR:
4583 case GL_DST_COLOR:
4584 case GL_ONE_MINUS_DST_COLOR:
4585 case GL_SRC_ALPHA:
4586 case GL_ONE_MINUS_SRC_ALPHA:
4587 case GL_DST_ALPHA:
4588 case GL_ONE_MINUS_DST_ALPHA:
4589 case GL_CONSTANT_COLOR:
4590 case GL_ONE_MINUS_CONSTANT_COLOR:
4591 case GL_CONSTANT_ALPHA:
4592 case GL_ONE_MINUS_CONSTANT_ALPHA:
4593 return true;
4594
4595 case GL_SRC_ALPHA_SATURATE:
4596 return (contextMajorVersion >= 3);
4597
4598 default:
4599 return false;
4600 }
4601}
4602
Jamie Madill5b772312018-03-08 20:28:32 -05004603bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004604 GLenum srcRGB,
4605 GLenum dstRGB,
4606 GLenum srcAlpha,
4607 GLenum dstAlpha)
4608{
4609 if (!ValidSrcBlendFunc(srcRGB))
4610 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004611 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004612 return false;
4613 }
4614
4615 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4616 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004617 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004618 return false;
4619 }
4620
4621 if (!ValidSrcBlendFunc(srcAlpha))
4622 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004623 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004624 return false;
4625 }
4626
4627 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4628 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004629 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004630 return false;
4631 }
4632
Frank Henigman146e8a12017-03-02 23:22:37 -05004633 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4634 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004635 {
4636 bool constantColorUsed =
4637 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4638 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4639
4640 bool constantAlphaUsed =
4641 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4642 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4643
4644 if (constantColorUsed && constantAlphaUsed)
4645 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004646 const char *msg;
4647 if (context->getExtensions().webglCompatibility)
4648 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004649 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004650 }
4651 else
4652 {
4653 msg =
4654 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4655 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4656 "implementation.";
4657 ERR() << msg;
4658 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004659 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004660 return false;
4661 }
4662 }
4663
4664 return true;
4665}
4666
Geoff Langc339c4e2016-11-29 10:37:36 -05004667bool ValidateGetString(Context *context, GLenum name)
4668{
4669 switch (name)
4670 {
4671 case GL_VENDOR:
4672 case GL_RENDERER:
4673 case GL_VERSION:
4674 case GL_SHADING_LANGUAGE_VERSION:
4675 case GL_EXTENSIONS:
4676 break;
4677
4678 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4679 if (!context->getExtensions().requestExtension)
4680 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004682 return false;
4683 }
4684 break;
4685
4686 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004687 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004688 return false;
4689 }
4690
4691 return true;
4692}
4693
Jamie Madill5b772312018-03-08 20:28:32 -05004694bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004695{
4696 if (width <= 0.0f || isNaN(width))
4697 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004698 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004699 return false;
4700 }
4701
4702 return true;
4703}
4704
Jamie Madill5b772312018-03-08 20:28:32 -05004705bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004706 GLuint index,
4707 GLint size,
4708 GLenum type,
4709 GLboolean normalized,
4710 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004711 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004712{
Shao80957d92017-02-20 21:25:59 +08004713 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004714 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004715 return false;
4716 }
4717
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004718 if (stride < 0)
4719 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004720 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004721 return false;
4722 }
4723
Shao80957d92017-02-20 21:25:59 +08004724 const Caps &caps = context->getCaps();
4725 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004726 {
Shao80957d92017-02-20 21:25:59 +08004727 if (stride > caps.maxVertexAttribStride)
4728 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004729 context->handleError(InvalidValue()
4730 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004731 return false;
4732 }
4733
4734 if (index >= caps.maxVertexAttribBindings)
4735 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004736 context->handleError(InvalidValue()
4737 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004738 return false;
4739 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004740 }
4741
4742 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4743 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4744 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4745 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004746 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4747 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004748 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4749 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004751 context
4752 ->handleError(InvalidOperation()
4753 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004754 return false;
4755 }
4756
4757 if (context->getExtensions().webglCompatibility)
4758 {
4759 // WebGL 1.0 [Section 6.14] Fixed point support
4760 // The WebGL API does not support the GL_FIXED data type.
4761 if (type == GL_FIXED)
4762 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004763 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004764 return false;
4765 }
4766
Geoff Lang2d62ab72017-03-23 16:54:40 -04004767 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004768 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004769 return false;
4770 }
4771 }
4772
4773 return true;
4774}
4775
Jamie Madill5b772312018-03-08 20:28:32 -05004776bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004777{
4778 if (context->getExtensions().webglCompatibility && zNear > zFar)
4779 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004780 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004781 return false;
4782 }
4783
4784 return true;
4785}
4786
Jamie Madill5b772312018-03-08 20:28:32 -05004787bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004788 GLenum target,
4789 GLenum internalformat,
4790 GLsizei width,
4791 GLsizei height)
4792{
4793 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4794 height);
4795}
4796
Jamie Madill5b772312018-03-08 20:28:32 -05004797bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004798 GLenum target,
4799 GLsizei samples,
4800 GLenum internalformat,
4801 GLsizei width,
4802 GLsizei height)
4803{
4804 if (!context->getExtensions().framebufferMultisample)
4805 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004806 context->handleError(InvalidOperation()
4807 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004808 return false;
4809 }
4810
4811 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4812 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4813 // generated.
4814 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4815 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004816 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004817 return false;
4818 }
4819
4820 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4821 // the specified storage. This is different than ES 3.0 in which a sample number higher
4822 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4823 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4824 if (context->getClientMajorVersion() >= 3)
4825 {
4826 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4827 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4828 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004829 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004830 return false;
4831 }
4832 }
4833
4834 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4835 width, height);
4836}
4837
Jamie Madill5b772312018-03-08 20:28:32 -05004838bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004839{
Geoff Lange8afa902017-09-27 15:00:43 -04004840 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004841 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004842 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004843 return false;
4844 }
4845
4846 return true;
4847}
4848
Jamie Madill5b772312018-03-08 20:28:32 -05004849bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004850{
4851 return true;
4852}
4853
Jamie Madill5b772312018-03-08 20:28:32 -05004854bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004855{
4856 return true;
4857}
4858
Jamie Madill5b772312018-03-08 20:28:32 -05004859bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004860{
4861 return true;
4862}
4863
Jamie Madill5b772312018-03-08 20:28:32 -05004864bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004865 GLboolean red,
4866 GLboolean green,
4867 GLboolean blue,
4868 GLboolean alpha)
4869{
4870 return true;
4871}
4872
Jamie Madill5b772312018-03-08 20:28:32 -05004873bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004874{
4875 return true;
4876}
4877
Jamie Madill5b772312018-03-08 20:28:32 -05004878bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004879{
4880 return true;
4881}
4882
Jamie Madill5b772312018-03-08 20:28:32 -05004883bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004884{
4885 switch (mode)
4886 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004887 case CullFaceMode::Front:
4888 case CullFaceMode::Back:
4889 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004890 break;
4891
4892 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004893 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894 return false;
4895 }
4896
4897 return true;
4898}
4899
Jamie Madill5b772312018-03-08 20:28:32 -05004900bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004901{
4902 if (program == 0)
4903 {
4904 return false;
4905 }
4906
4907 if (!context->getProgram(program))
4908 {
4909 if (context->getShader(program))
4910 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004911 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004912 return false;
4913 }
4914 else
4915 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004916 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004917 return false;
4918 }
4919 }
4920
4921 return true;
4922}
4923
Jamie Madill5b772312018-03-08 20:28:32 -05004924bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004925{
4926 if (shader == 0)
4927 {
4928 return false;
4929 }
4930
4931 if (!context->getShader(shader))
4932 {
4933 if (context->getProgram(shader))
4934 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004935 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004936 return false;
4937 }
4938 else
4939 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004940 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004941 return false;
4942 }
4943 }
4944
4945 return true;
4946}
4947
Jamie Madill5b772312018-03-08 20:28:32 -05004948bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004949{
4950 switch (func)
4951 {
4952 case GL_NEVER:
4953 case GL_ALWAYS:
4954 case GL_LESS:
4955 case GL_LEQUAL:
4956 case GL_EQUAL:
4957 case GL_GREATER:
4958 case GL_GEQUAL:
4959 case GL_NOTEQUAL:
4960 break;
4961
4962 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004963 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004964 return false;
4965 }
4966
4967 return true;
4968}
4969
Jamie Madill5b772312018-03-08 20:28:32 -05004970bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004971{
4972 return true;
4973}
4974
Jamie Madill5b772312018-03-08 20:28:32 -05004975bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004976{
4977 Program *programObject = GetValidProgram(context, program);
4978 if (!programObject)
4979 {
4980 return false;
4981 }
4982
4983 Shader *shaderObject = GetValidShader(context, shader);
4984 if (!shaderObject)
4985 {
4986 return false;
4987 }
4988
4989 const Shader *attachedShader = nullptr;
4990
4991 switch (shaderObject->getType())
4992 {
4993 case GL_VERTEX_SHADER:
4994 {
4995 attachedShader = programObject->getAttachedVertexShader();
4996 break;
4997 }
4998 case GL_FRAGMENT_SHADER:
4999 {
5000 attachedShader = programObject->getAttachedFragmentShader();
5001 break;
5002 }
5003 case GL_COMPUTE_SHADER:
5004 {
5005 attachedShader = programObject->getAttachedComputeShader();
5006 break;
5007 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08005008 case GL_GEOMETRY_SHADER_EXT:
5009 {
5010 attachedShader = programObject->getAttachedGeometryShader();
5011 break;
5012 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04005013 default:
5014 UNREACHABLE();
5015 return false;
5016 }
5017
5018 if (attachedShader != shaderObject)
5019 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005020 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005021 return false;
5022 }
5023
5024 return true;
5025}
5026
Jamie Madill5b772312018-03-08 20:28:32 -05005027bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005028{
5029 if (index >= MAX_VERTEX_ATTRIBS)
5030 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005031 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005032 return false;
5033 }
5034
5035 return true;
5036}
5037
Jamie Madill5b772312018-03-08 20:28:32 -05005038bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005039{
5040 if (index >= MAX_VERTEX_ATTRIBS)
5041 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005042 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005043 return false;
5044 }
5045
5046 return true;
5047}
5048
Jamie Madill5b772312018-03-08 20:28:32 -05005049bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005050{
5051 return true;
5052}
5053
Jamie Madill5b772312018-03-08 20:28:32 -05005054bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005055{
5056 return true;
5057}
5058
Jamie Madill5b772312018-03-08 20:28:32 -05005059bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005060{
5061 switch (mode)
5062 {
5063 case GL_CW:
5064 case GL_CCW:
5065 break;
5066 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005067 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005068 return false;
5069 }
5070
5071 return true;
5072}
5073
Jamie Madill5b772312018-03-08 20:28:32 -05005074bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005075 GLuint program,
5076 GLuint index,
5077 GLsizei bufsize,
5078 GLsizei *length,
5079 GLint *size,
5080 GLenum *type,
5081 GLchar *name)
5082{
5083 if (bufsize < 0)
5084 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005085 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
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 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5097 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005098 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005099 return false;
5100 }
5101
5102 return true;
5103}
5104
Jamie Madill5b772312018-03-08 20:28:32 -05005105bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005106 GLuint program,
5107 GLuint index,
5108 GLsizei bufsize,
5109 GLsizei *length,
5110 GLint *size,
5111 GLenum *type,
5112 GLchar *name)
5113{
5114 if (bufsize < 0)
5115 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005116 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005117 return false;
5118 }
5119
5120 Program *programObject = GetValidProgram(context, program);
5121
5122 if (!programObject)
5123 {
5124 return false;
5125 }
5126
5127 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5128 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005129 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005130 return false;
5131 }
5132
5133 return true;
5134}
5135
Jamie Madill5b772312018-03-08 20:28:32 -05005136bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005137 GLuint program,
5138 GLsizei maxcount,
5139 GLsizei *count,
5140 GLuint *shaders)
5141{
5142 if (maxcount < 0)
5143 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005144 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005145 return false;
5146 }
5147
5148 Program *programObject = GetValidProgram(context, program);
5149
5150 if (!programObject)
5151 {
5152 return false;
5153 }
5154
5155 return true;
5156}
5157
Jamie Madill5b772312018-03-08 20:28:32 -05005158bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005159{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005160 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5161 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005162 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005163 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005164 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005165 return false;
5166 }
5167
Jamie Madillc1d770e2017-04-13 17:31:24 -04005168 Program *programObject = GetValidProgram(context, program);
5169
5170 if (!programObject)
5171 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005172 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005173 return false;
5174 }
5175
5176 if (!programObject->isLinked())
5177 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005178 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005179 return false;
5180 }
5181
5182 return true;
5183}
5184
Jamie Madill5b772312018-03-08 20:28:32 -05005185bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005186{
5187 GLenum nativeType;
5188 unsigned int numParams = 0;
5189 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5190}
5191
Jamie Madill5b772312018-03-08 20:28:32 -05005192bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005193{
5194 return true;
5195}
5196
Jamie Madill5b772312018-03-08 20:28:32 -05005197bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005198{
5199 GLenum nativeType;
5200 unsigned int numParams = 0;
5201 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5202}
5203
Jamie Madill5b772312018-03-08 20:28:32 -05005204bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005205{
5206 GLenum nativeType;
5207 unsigned int numParams = 0;
5208 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5209}
5210
Jamie Madill5b772312018-03-08 20:28:32 -05005211bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005212 GLuint program,
5213 GLsizei bufsize,
5214 GLsizei *length,
5215 GLchar *infolog)
5216{
5217 if (bufsize < 0)
5218 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005219 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005220 return false;
5221 }
5222
5223 Program *programObject = GetValidProgram(context, program);
5224 if (!programObject)
5225 {
5226 return false;
5227 }
5228
5229 return true;
5230}
5231
Jamie Madill5b772312018-03-08 20:28:32 -05005232bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005233 GLuint shader,
5234 GLsizei bufsize,
5235 GLsizei *length,
5236 GLchar *infolog)
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 ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005254 GLenum shadertype,
5255 GLenum precisiontype,
5256 GLint *range,
5257 GLint *precision)
5258{
5259 switch (shadertype)
5260 {
5261 case GL_VERTEX_SHADER:
5262 case GL_FRAGMENT_SHADER:
5263 break;
5264 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005265 context->handleError(InvalidOperation()
5266 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005267 return false;
5268 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005269 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005270 return false;
5271 }
5272
5273 switch (precisiontype)
5274 {
5275 case GL_LOW_FLOAT:
5276 case GL_MEDIUM_FLOAT:
5277 case GL_HIGH_FLOAT:
5278 case GL_LOW_INT:
5279 case GL_MEDIUM_INT:
5280 case GL_HIGH_INT:
5281 break;
5282
5283 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005284 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005285 return false;
5286 }
5287
5288 return true;
5289}
5290
Jamie Madill5b772312018-03-08 20:28:32 -05005291bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005292 GLuint shader,
5293 GLsizei bufsize,
5294 GLsizei *length,
5295 GLchar *source)
5296{
5297 if (bufsize < 0)
5298 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005299 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005300 return false;
5301 }
5302
5303 Shader *shaderObject = GetValidShader(context, shader);
5304 if (!shaderObject)
5305 {
5306 return false;
5307 }
5308
5309 return true;
5310}
5311
Jamie Madill5b772312018-03-08 20:28:32 -05005312bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005313{
5314 if (strstr(name, "gl_") == name)
5315 {
5316 return false;
5317 }
5318
Geoff Langfc32e8b2017-05-31 14:16:59 -04005319 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5320 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005321 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005322 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005323 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005324 return false;
5325 }
5326
Jamie Madillc1d770e2017-04-13 17:31:24 -04005327 Program *programObject = GetValidProgram(context, program);
5328
5329 if (!programObject)
5330 {
5331 return false;
5332 }
5333
5334 if (!programObject->isLinked())
5335 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005336 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005337 return false;
5338 }
5339
5340 return true;
5341}
5342
Jamie Madill5b772312018-03-08 20:28:32 -05005343bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005344{
5345 switch (mode)
5346 {
5347 case GL_FASTEST:
5348 case GL_NICEST:
5349 case GL_DONT_CARE:
5350 break;
5351
5352 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005353 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005354 return false;
5355 }
5356
5357 switch (target)
5358 {
5359 case GL_GENERATE_MIPMAP_HINT:
5360 break;
5361
Geoff Lange7bd2182017-06-16 16:13:13 -04005362 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5363 if (context->getClientVersion() < ES_3_0 &&
5364 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005365 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005366 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005367 return false;
5368 }
5369 break;
5370
5371 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005372 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005373 return false;
5374 }
5375
5376 return true;
5377}
5378
Jamie Madill5b772312018-03-08 20:28:32 -05005379bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005380{
5381 return true;
5382}
5383
Jamie Madill5b772312018-03-08 20:28:32 -05005384bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385{
5386 return true;
5387}
5388
Jamie Madill5b772312018-03-08 20:28:32 -05005389bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005390{
5391 return true;
5392}
5393
Jamie Madill5b772312018-03-08 20:28:32 -05005394bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005395{
5396 return true;
5397}
5398
Jamie Madill5b772312018-03-08 20:28:32 -05005399bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005400{
5401 return true;
5402}
5403
Jamie Madill5b772312018-03-08 20:28:32 -05005404bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005405{
5406 return true;
5407}
5408
Jamie Madill5b772312018-03-08 20:28:32 -05005409bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005410{
5411 if (context->getClientMajorVersion() < 3)
5412 {
5413 switch (pname)
5414 {
5415 case GL_UNPACK_IMAGE_HEIGHT:
5416 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005417 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005418 return false;
5419
5420 case GL_UNPACK_ROW_LENGTH:
5421 case GL_UNPACK_SKIP_ROWS:
5422 case GL_UNPACK_SKIP_PIXELS:
5423 if (!context->getExtensions().unpackSubimage)
5424 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005425 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005426 return false;
5427 }
5428 break;
5429
5430 case GL_PACK_ROW_LENGTH:
5431 case GL_PACK_SKIP_ROWS:
5432 case GL_PACK_SKIP_PIXELS:
5433 if (!context->getExtensions().packSubimage)
5434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005435 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005436 return false;
5437 }
5438 break;
5439 }
5440 }
5441
5442 if (param < 0)
5443 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005444 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005445 return false;
5446 }
5447
5448 switch (pname)
5449 {
5450 case GL_UNPACK_ALIGNMENT:
5451 if (param != 1 && param != 2 && param != 4 && param != 8)
5452 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005453 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005454 return false;
5455 }
5456 break;
5457
5458 case GL_PACK_ALIGNMENT:
5459 if (param != 1 && param != 2 && param != 4 && param != 8)
5460 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005461 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005462 return false;
5463 }
5464 break;
5465
5466 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005467 if (!context->getExtensions().packReverseRowOrder)
5468 {
5469 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5470 }
5471 break;
5472
Jamie Madillc1d770e2017-04-13 17:31:24 -04005473 case GL_UNPACK_ROW_LENGTH:
5474 case GL_UNPACK_IMAGE_HEIGHT:
5475 case GL_UNPACK_SKIP_IMAGES:
5476 case GL_UNPACK_SKIP_ROWS:
5477 case GL_UNPACK_SKIP_PIXELS:
5478 case GL_PACK_ROW_LENGTH:
5479 case GL_PACK_SKIP_ROWS:
5480 case GL_PACK_SKIP_PIXELS:
5481 break;
5482
5483 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005484 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485 return false;
5486 }
5487
5488 return true;
5489}
5490
Jamie Madill5b772312018-03-08 20:28:32 -05005491bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005492{
5493 return true;
5494}
5495
Jamie Madill5b772312018-03-08 20:28:32 -05005496bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005497{
5498 return true;
5499}
5500
Jamie Madill5b772312018-03-08 20:28:32 -05005501bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005502{
5503 return true;
5504}
5505
Jamie Madill5b772312018-03-08 20:28:32 -05005506bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005507{
5508 if (width < 0 || height < 0)
5509 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005510 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005511 return false;
5512 }
5513
5514 return true;
5515}
5516
Jamie Madill5b772312018-03-08 20:28:32 -05005517bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005518 GLsizei n,
5519 const GLuint *shaders,
5520 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005521 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005522 GLsizei length)
5523{
5524 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5525 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5526 shaderBinaryFormats.end())
5527 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005528 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005529 return false;
5530 }
5531
5532 return true;
5533}
5534
Jamie Madill5b772312018-03-08 20:28:32 -05005535bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005536 GLuint shader,
5537 GLsizei count,
5538 const GLchar *const *string,
5539 const GLint *length)
5540{
5541 if (count < 0)
5542 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005543 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005544 return false;
5545 }
5546
Geoff Langfc32e8b2017-05-31 14:16:59 -04005547 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5548 // shader-related entry points
5549 if (context->getExtensions().webglCompatibility)
5550 {
5551 for (GLsizei i = 0; i < count; i++)
5552 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005553 size_t len =
5554 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005555
5556 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005557 if (!IsValidESSLShaderSourceString(string[i], len,
5558 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005559 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005560 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005561 return false;
5562 }
5563 }
5564 }
5565
Jamie Madillc1d770e2017-04-13 17:31:24 -04005566 Shader *shaderObject = GetValidShader(context, shader);
5567 if (!shaderObject)
5568 {
5569 return false;
5570 }
5571
5572 return true;
5573}
5574
Jamie Madill5b772312018-03-08 20:28:32 -05005575bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005576{
5577 if (!IsValidStencilFunc(func))
5578 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005579 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580 return false;
5581 }
5582
5583 return true;
5584}
5585
Jamie Madill5b772312018-03-08 20:28:32 -05005586bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005587{
5588 if (!IsValidStencilFace(face))
5589 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005590 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005591 return false;
5592 }
5593
5594 if (!IsValidStencilFunc(func))
5595 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005596 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005597 return false;
5598 }
5599
5600 return true;
5601}
5602
Jamie Madill5b772312018-03-08 20:28:32 -05005603bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005604{
5605 return true;
5606}
5607
Jamie Madill5b772312018-03-08 20:28:32 -05005608bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005609{
5610 if (!IsValidStencilFace(face))
5611 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005612 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005613 return false;
5614 }
5615
5616 return true;
5617}
5618
Jamie Madill5b772312018-03-08 20:28:32 -05005619bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005620{
5621 if (!IsValidStencilOp(fail))
5622 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005623 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005624 return false;
5625 }
5626
5627 if (!IsValidStencilOp(zfail))
5628 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005629 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005630 return false;
5631 }
5632
5633 if (!IsValidStencilOp(zpass))
5634 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005635 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005636 return false;
5637 }
5638
5639 return true;
5640}
5641
Jamie Madill5b772312018-03-08 20:28:32 -05005642bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005643 GLenum face,
5644 GLenum fail,
5645 GLenum zfail,
5646 GLenum zpass)
5647{
5648 if (!IsValidStencilFace(face))
5649 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005650 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005651 return false;
5652 }
5653
5654 return ValidateStencilOp(context, fail, zfail, zpass);
5655}
5656
Jamie Madill5b772312018-03-08 20:28:32 -05005657bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005658{
5659 return ValidateUniform(context, GL_FLOAT, location, 1);
5660}
5661
Jamie Madill5b772312018-03-08 20:28:32 -05005662bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005663{
5664 return ValidateUniform(context, GL_FLOAT, location, count);
5665}
5666
Jamie Madill5b772312018-03-08 20:28:32 -05005667bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005668{
5669 return ValidateUniform1iv(context, location, 1, &x);
5670}
5671
Jamie Madill5b772312018-03-08 20:28:32 -05005672bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005673{
5674 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5675}
5676
Jamie Madill5b772312018-03-08 20:28:32 -05005677bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005678{
5679 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5680}
5681
Jamie Madill5b772312018-03-08 20:28:32 -05005682bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005683{
5684 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5685}
5686
Jamie Madill5b772312018-03-08 20:28:32 -05005687bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005688{
5689 return ValidateUniform(context, GL_INT_VEC2, location, count);
5690}
5691
Jamie Madill5b772312018-03-08 20:28:32 -05005692bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005693{
5694 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5695}
5696
Jamie Madill5b772312018-03-08 20:28:32 -05005697bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005698{
5699 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5700}
5701
Jamie Madill5b772312018-03-08 20:28:32 -05005702bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005703{
5704 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5705}
5706
Jamie Madill5b772312018-03-08 20:28:32 -05005707bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005708{
5709 return ValidateUniform(context, GL_INT_VEC3, location, count);
5710}
5711
Jamie Madill5b772312018-03-08 20:28:32 -05005712bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005713{
5714 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5715}
5716
Jamie Madill5b772312018-03-08 20:28:32 -05005717bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005718{
5719 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5720}
5721
Jamie Madill5b772312018-03-08 20:28:32 -05005722bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005723{
5724 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5725}
5726
Jamie Madill5b772312018-03-08 20:28:32 -05005727bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005728{
5729 return ValidateUniform(context, GL_INT_VEC4, location, count);
5730}
5731
Jamie Madill5b772312018-03-08 20:28:32 -05005732bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005733 GLint location,
5734 GLsizei count,
5735 GLboolean transpose,
5736 const GLfloat *value)
5737{
5738 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5739}
5740
Jamie Madill5b772312018-03-08 20:28:32 -05005741bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005742 GLint location,
5743 GLsizei count,
5744 GLboolean transpose,
5745 const GLfloat *value)
5746{
5747 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5748}
5749
Jamie Madill5b772312018-03-08 20:28:32 -05005750bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005751 GLint location,
5752 GLsizei count,
5753 GLboolean transpose,
5754 const GLfloat *value)
5755{
5756 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5757}
5758
Jamie Madill5b772312018-03-08 20:28:32 -05005759bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005760{
5761 Program *programObject = GetValidProgram(context, program);
5762
5763 if (!programObject)
5764 {
5765 return false;
5766 }
5767
5768 return true;
5769}
5770
Jamie Madill5b772312018-03-08 20:28:32 -05005771bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005772{
5773 return ValidateVertexAttribIndex(context, index);
5774}
5775
Jamie Madill5b772312018-03-08 20:28:32 -05005776bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005777{
5778 return ValidateVertexAttribIndex(context, index);
5779}
5780
Jamie Madill5b772312018-03-08 20:28:32 -05005781bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005782{
5783 return ValidateVertexAttribIndex(context, index);
5784}
5785
Jamie Madill5b772312018-03-08 20:28:32 -05005786bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005787{
5788 return ValidateVertexAttribIndex(context, index);
5789}
5790
Jamie Madill5b772312018-03-08 20:28:32 -05005791bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005792{
5793 return ValidateVertexAttribIndex(context, index);
5794}
5795
Jamie Madill5b772312018-03-08 20:28:32 -05005796bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005797{
5798 return ValidateVertexAttribIndex(context, index);
5799}
5800
Jamie Madill5b772312018-03-08 20:28:32 -05005801bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005802 GLuint index,
5803 GLfloat x,
5804 GLfloat y,
5805 GLfloat z,
5806 GLfloat w)
5807{
5808 return ValidateVertexAttribIndex(context, index);
5809}
5810
Jamie Madill5b772312018-03-08 20:28:32 -05005811bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005812{
5813 return ValidateVertexAttribIndex(context, index);
5814}
5815
Jamie Madill5b772312018-03-08 20:28:32 -05005816bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005817{
5818 if (width < 0 || height < 0)
5819 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005820 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005821 return false;
5822 }
5823
5824 return true;
5825}
5826
Jamie Madill5b772312018-03-08 20:28:32 -05005827bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005828{
5829 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5830}
5831
Jamie Madill5b772312018-03-08 20:28:32 -05005832bool ValidateDrawElements(Context *context,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005833 GLenum mode,
5834 GLsizei count,
5835 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005836 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005837{
5838 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5839}
5840
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005841bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005842 GLenum target,
5843 GLenum attachment,
5844 GLenum pname,
5845 GLint *params)
5846{
5847 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5848 nullptr);
5849}
5850
Jamie Madill5b772312018-03-08 20:28:32 -05005851bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005852{
5853 return ValidateGetProgramivBase(context, program, pname, nullptr);
5854}
5855
Jamie Madill5b772312018-03-08 20:28:32 -05005856bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005857 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005858 GLint level,
5859 GLenum internalformat,
5860 GLint x,
5861 GLint y,
5862 GLsizei width,
5863 GLsizei height,
5864 GLint border)
5865{
5866 if (context->getClientMajorVersion() < 3)
5867 {
5868 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5869 0, x, y, width, height, border);
5870 }
5871
5872 ASSERT(context->getClientMajorVersion() == 3);
5873 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5874 0, x, y, width, height, border);
5875}
5876
5877bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005878 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005879 GLint level,
5880 GLint xoffset,
5881 GLint yoffset,
5882 GLint x,
5883 GLint y,
5884 GLsizei width,
5885 GLsizei height)
5886{
5887 if (context->getClientMajorVersion() < 3)
5888 {
5889 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5890 yoffset, x, y, width, height, 0);
5891 }
5892
5893 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5894 yoffset, 0, x, y, width, height, 0);
5895}
5896
5897bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5898{
5899 return ValidateGenOrDelete(context, n);
5900}
5901
5902bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5903{
5904 return ValidateGenOrDelete(context, n);
5905}
5906
5907bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5908{
5909 return ValidateGenOrDelete(context, n);
5910}
5911
5912bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5913{
5914 return ValidateGenOrDelete(context, n);
5915}
5916
5917bool ValidateDisable(Context *context, GLenum cap)
5918{
5919 if (!ValidCap(context, cap, false))
5920 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005921 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005922 return false;
5923 }
5924
5925 return true;
5926}
5927
5928bool ValidateEnable(Context *context, GLenum cap)
5929{
5930 if (!ValidCap(context, cap, false))
5931 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005932 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005933 return false;
5934 }
5935
5936 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5937 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5938 {
5939 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005940 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005941
5942 // We also output an error message to the debugger window if tracing is active, so that
5943 // developers can see the error message.
5944 ERR() << errorMessage;
5945 return false;
5946 }
5947
5948 return true;
5949}
5950
5951bool ValidateFramebufferRenderbuffer(Context *context,
5952 GLenum target,
5953 GLenum attachment,
5954 GLenum renderbuffertarget,
5955 GLuint renderbuffer)
5956{
Geoff Lange8afa902017-09-27 15:00:43 -04005957 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005958 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005959 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5960 return false;
5961 }
5962
5963 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5964 {
5965 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005966 return false;
5967 }
5968
5969 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5970 renderbuffertarget, renderbuffer);
5971}
5972
5973bool ValidateFramebufferTexture2D(Context *context,
5974 GLenum target,
5975 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005976 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005977 GLuint texture,
5978 GLint level)
5979{
5980 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5981 // extension
5982 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5983 level != 0)
5984 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005985 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005986 return false;
5987 }
5988
5989 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5990 {
5991 return false;
5992 }
5993
5994 if (texture != 0)
5995 {
5996 gl::Texture *tex = context->getTexture(texture);
5997 ASSERT(tex);
5998
5999 const gl::Caps &caps = context->getCaps();
6000
6001 switch (textarget)
6002 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006003 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006004 {
6005 if (level > gl::log2(caps.max2DTextureSize))
6006 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006007 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006008 return false;
6009 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006010 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006011 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006012 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 return false;
6014 }
6015 }
6016 break;
6017
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006018 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006019 {
6020 if (level != 0)
6021 {
6022 context->handleError(InvalidValue());
6023 return false;
6024 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006025 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006026 {
6027 context->handleError(InvalidOperation()
6028 << "Textarget must match the texture target type.");
6029 return false;
6030 }
6031 }
6032 break;
6033
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006034 case TextureTarget::CubeMapNegativeX:
6035 case TextureTarget::CubeMapNegativeY:
6036 case TextureTarget::CubeMapNegativeZ:
6037 case TextureTarget::CubeMapPositiveX:
6038 case TextureTarget::CubeMapPositiveY:
6039 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006040 {
6041 if (level > gl::log2(caps.maxCubeMapTextureSize))
6042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006043 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006044 return false;
6045 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006046 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006047 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006048 context->handleError(InvalidOperation()
6049 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006050 return false;
6051 }
6052 }
6053 break;
6054
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006055 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006056 {
6057 if (context->getClientVersion() < ES_3_1)
6058 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006059 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006060 return false;
6061 }
6062
6063 if (level != 0)
6064 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006065 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006066 return false;
6067 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006068 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006069 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006070 context->handleError(InvalidOperation()
6071 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006072 return false;
6073 }
6074 }
6075 break;
6076
6077 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006078 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006079 return false;
6080 }
6081
6082 const Format &format = tex->getFormat(textarget, level);
6083 if (format.info->compressed)
6084 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006085 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006086 return false;
6087 }
6088 }
6089
6090 return true;
6091}
6092
6093bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6094{
6095 return ValidateGenOrDelete(context, n);
6096}
6097
6098bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6099{
6100 return ValidateGenOrDelete(context, n);
6101}
6102
6103bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6104{
6105 return ValidateGenOrDelete(context, n);
6106}
6107
6108bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6109{
6110 return ValidateGenOrDelete(context, n);
6111}
6112
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006113bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006114{
6115 if (!ValidTextureTarget(context, target))
6116 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006117 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006118 return false;
6119 }
6120
6121 Texture *texture = context->getTargetTexture(target);
6122
6123 if (texture == nullptr)
6124 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006125 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006126 return false;
6127 }
6128
6129 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6130
6131 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6132 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6133 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006135 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006136 return false;
6137 }
6138
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006139 TextureTarget baseTarget = (target == TextureType::CubeMap)
6140 ? TextureTarget::CubeMapPositiveX
6141 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006142 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6143 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6144 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006145 {
6146 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6147 return false;
6148 }
6149
Geoff Lang536eca12017-09-13 11:23:35 -04006150 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6151 bool formatUnsized = !format.sized;
6152 bool formatColorRenderableAndFilterable =
6153 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6154 format.renderSupport(context->getClientVersion(), context->getExtensions());
6155 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006156 {
Geoff Lang536eca12017-09-13 11:23:35 -04006157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006158 return false;
6159 }
6160
Geoff Lang536eca12017-09-13 11:23:35 -04006161 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6162 // generation
6163 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6164 {
6165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6166 return false;
6167 }
6168
6169 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6170 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006171 bool supportsSRGBMipmapGeneration =
6172 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006173 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006174 {
Geoff Lang536eca12017-09-13 11:23:35 -04006175 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006176 return false;
6177 }
6178
6179 // Non-power of 2 ES2 check
6180 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6181 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6182 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6183 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006184 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6185 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006186 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006187 return false;
6188 }
6189
6190 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006191 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006192 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006193 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006194 return false;
6195 }
6196
6197 return true;
6198}
6199
Jamie Madill5b772312018-03-08 20:28:32 -05006200bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006201 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006202 GLenum pname,
6203 GLint *params)
6204{
6205 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6206}
6207
6208bool ValidateGetRenderbufferParameteriv(Context *context,
6209 GLenum target,
6210 GLenum pname,
6211 GLint *params)
6212{
6213 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6214}
6215
6216bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6217{
6218 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6219}
6220
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006221bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006222{
6223 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6224}
6225
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006226bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006227{
6228 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6229}
6230
6231bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6232{
6233 return ValidateGetUniformBase(context, program, location);
6234}
6235
6236bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6237{
6238 return ValidateGetUniformBase(context, program, location);
6239}
6240
6241bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6242{
6243 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6244}
6245
6246bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6247{
6248 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6249}
6250
6251bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6252{
6253 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6254}
6255
6256bool ValidateIsEnabled(Context *context, GLenum cap)
6257{
6258 if (!ValidCap(context, cap, true))
6259 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006260 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006261 return false;
6262 }
6263
6264 return true;
6265}
6266
6267bool ValidateLinkProgram(Context *context, GLuint program)
6268{
6269 if (context->hasActiveTransformFeedback(program))
6270 {
6271 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006272 context->handleError(InvalidOperation() << "Cannot link program while program is "
6273 "associated with an active transform "
6274 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006275 return false;
6276 }
6277
6278 Program *programObject = GetValidProgram(context, program);
6279 if (!programObject)
6280 {
6281 return false;
6282 }
6283
6284 return true;
6285}
6286
Jamie Madill4928b7c2017-06-20 12:57:39 -04006287bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006288 GLint x,
6289 GLint y,
6290 GLsizei width,
6291 GLsizei height,
6292 GLenum format,
6293 GLenum type,
6294 void *pixels)
6295{
6296 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6297 nullptr, pixels);
6298}
6299
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006300bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006301{
6302 return ValidateTexParameterBase(context, target, pname, -1, &param);
6303}
6304
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006305bool ValidateTexParameterfv(Context *context,
6306 TextureType target,
6307 GLenum pname,
6308 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006309{
6310 return ValidateTexParameterBase(context, target, pname, -1, params);
6311}
6312
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006313bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006314{
6315 return ValidateTexParameterBase(context, target, pname, -1, &param);
6316}
6317
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006318bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006319{
6320 return ValidateTexParameterBase(context, target, pname, -1, params);
6321}
6322
6323bool ValidateUseProgram(Context *context, GLuint program)
6324{
6325 if (program != 0)
6326 {
6327 Program *programObject = context->getProgram(program);
6328 if (!programObject)
6329 {
6330 // ES 3.1.0 section 7.3 page 72
6331 if (context->getShader(program))
6332 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006333 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006334 return false;
6335 }
6336 else
6337 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006338 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006339 return false;
6340 }
6341 }
6342 if (!programObject->isLinked())
6343 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006345 return false;
6346 }
6347 }
6348 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6349 {
6350 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006351 context
6352 ->handleError(InvalidOperation()
6353 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006354 return false;
6355 }
6356
6357 return true;
6358}
6359
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006360bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6361{
6362 if (!context->getExtensions().fence)
6363 {
6364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6365 return false;
6366 }
6367
6368 if (n < 0)
6369 {
6370 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6371 return false;
6372 }
6373
6374 return true;
6375}
6376
6377bool ValidateFinishFenceNV(Context *context, GLuint fence)
6378{
6379 if (!context->getExtensions().fence)
6380 {
6381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6382 return false;
6383 }
6384
6385 FenceNV *fenceObject = context->getFenceNV(fence);
6386
6387 if (fenceObject == nullptr)
6388 {
6389 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6390 return false;
6391 }
6392
6393 if (!fenceObject->isSet())
6394 {
6395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6396 return false;
6397 }
6398
6399 return true;
6400}
6401
6402bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6403{
6404 if (!context->getExtensions().fence)
6405 {
6406 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6407 return false;
6408 }
6409
6410 if (n < 0)
6411 {
6412 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6413 return false;
6414 }
6415
6416 return true;
6417}
6418
6419bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6420{
6421 if (!context->getExtensions().fence)
6422 {
6423 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6424 return false;
6425 }
6426
6427 FenceNV *fenceObject = context->getFenceNV(fence);
6428
6429 if (fenceObject == nullptr)
6430 {
6431 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6432 return false;
6433 }
6434
6435 if (!fenceObject->isSet())
6436 {
6437 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6438 return false;
6439 }
6440
6441 switch (pname)
6442 {
6443 case GL_FENCE_STATUS_NV:
6444 case GL_FENCE_CONDITION_NV:
6445 break;
6446
6447 default:
6448 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6449 return false;
6450 }
6451
6452 return true;
6453}
6454
6455bool ValidateGetGraphicsResetStatusEXT(Context *context)
6456{
6457 if (!context->getExtensions().robustness)
6458 {
6459 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6460 return false;
6461 }
6462
6463 return true;
6464}
6465
6466bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6467 GLuint shader,
6468 GLsizei bufsize,
6469 GLsizei *length,
6470 GLchar *source)
6471{
6472 if (!context->getExtensions().translatedShaderSource)
6473 {
6474 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6475 return false;
6476 }
6477
6478 if (bufsize < 0)
6479 {
6480 context->handleError(InvalidValue());
6481 return false;
6482 }
6483
6484 Shader *shaderObject = context->getShader(shader);
6485
6486 if (!shaderObject)
6487 {
6488 context->handleError(InvalidOperation());
6489 return false;
6490 }
6491
6492 return true;
6493}
6494
6495bool ValidateIsFenceNV(Context *context, GLuint fence)
6496{
6497 if (!context->getExtensions().fence)
6498 {
6499 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6500 return false;
6501 }
6502
6503 return true;
6504}
6505
Jamie Madill007530e2017-12-28 14:27:04 -05006506bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6507{
6508 if (!context->getExtensions().fence)
6509 {
6510 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6511 return false;
6512 }
6513
6514 if (condition != GL_ALL_COMPLETED_NV)
6515 {
6516 context->handleError(InvalidEnum());
6517 return false;
6518 }
6519
6520 FenceNV *fenceObject = context->getFenceNV(fence);
6521
6522 if (fenceObject == nullptr)
6523 {
6524 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6525 return false;
6526 }
6527
6528 return true;
6529}
6530
6531bool ValidateTestFenceNV(Context *context, GLuint fence)
6532{
6533 if (!context->getExtensions().fence)
6534 {
6535 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6536 return false;
6537 }
6538
6539 FenceNV *fenceObject = context->getFenceNV(fence);
6540
6541 if (fenceObject == nullptr)
6542 {
6543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6544 return false;
6545 }
6546
6547 if (fenceObject->isSet() != GL_TRUE)
6548 {
6549 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6550 return false;
6551 }
6552
6553 return true;
6554}
6555
6556bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006557 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006558 GLsizei levels,
6559 GLenum internalformat,
6560 GLsizei width,
6561 GLsizei height)
6562{
6563 if (!context->getExtensions().textureStorage)
6564 {
6565 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6566 return false;
6567 }
6568
6569 if (context->getClientMajorVersion() < 3)
6570 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006571 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006572 height);
6573 }
6574
6575 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006576 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006577 1);
6578}
6579
6580bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6581{
6582 if (!context->getExtensions().instancedArrays)
6583 {
6584 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6585 return false;
6586 }
6587
6588 if (index >= MAX_VERTEX_ATTRIBS)
6589 {
6590 context->handleError(InvalidValue());
6591 return false;
6592 }
6593
6594 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6595 {
6596 if (index == 0 && divisor != 0)
6597 {
6598 const char *errorMessage =
6599 "The current context doesn't support setting a non-zero divisor on the "
6600 "attribute with index zero. "
6601 "Please reorder the attributes in your vertex shader so that attribute zero "
6602 "can have a zero divisor.";
6603 context->handleError(InvalidOperation() << errorMessage);
6604
6605 // We also output an error message to the debugger window if tracing is active, so
6606 // that developers can see the error message.
6607 ERR() << errorMessage;
6608 return false;
6609 }
6610 }
6611
6612 return true;
6613}
6614
6615bool ValidateTexImage3DOES(Context *context,
6616 GLenum target,
6617 GLint level,
6618 GLenum internalformat,
6619 GLsizei width,
6620 GLsizei height,
6621 GLsizei depth,
6622 GLint border,
6623 GLenum format,
6624 GLenum type,
6625 const void *pixels)
6626{
6627 UNIMPLEMENTED(); // FIXME
6628 return false;
6629}
6630
6631bool ValidatePopGroupMarkerEXT(Context *context)
6632{
6633 if (!context->getExtensions().debugMarker)
6634 {
6635 // The debug marker calls should not set error state
6636 // However, it seems reasonable to set an error state if the extension is not enabled
6637 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6638 return false;
6639 }
6640
6641 return true;
6642}
6643
Jamie Madillfa920eb2018-01-04 11:45:50 -05006644bool ValidateTexStorage1DEXT(Context *context,
6645 GLenum target,
6646 GLsizei levels,
6647 GLenum internalformat,
6648 GLsizei width)
6649{
6650 UNIMPLEMENTED();
6651 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6652 return false;
6653}
6654
6655bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006656 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006657 GLsizei levels,
6658 GLenum internalformat,
6659 GLsizei width,
6660 GLsizei height,
6661 GLsizei depth)
6662{
6663 if (!context->getExtensions().textureStorage)
6664 {
6665 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6666 return false;
6667 }
6668
6669 if (context->getClientMajorVersion() < 3)
6670 {
6671 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6672 return false;
6673 }
6674
6675 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6676 depth);
6677}
6678
Jamie Madillc29968b2016-01-20 11:17:23 -05006679} // namespace gl