blob: 30b82513f7408a7a96f3e2c6351968e71ddd588f [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070078 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030079 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madill5b772312018-03-08 20:28:32 -0500458bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700795 // GLES1 emulation: GLES1-specific caps
796 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700797 case GL_VERTEX_ARRAY:
798 case GL_NORMAL_ARRAY:
799 case GL_COLOR_ARRAY:
800 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700801 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700802 case GL_LIGHTING:
803 case GL_LIGHT0:
804 case GL_LIGHT1:
805 case GL_LIGHT2:
806 case GL_LIGHT3:
807 case GL_LIGHT4:
808 case GL_LIGHT5:
809 case GL_LIGHT6:
810 case GL_LIGHT7:
811 case GL_NORMALIZE:
812 case GL_RESCALE_NORMAL:
813 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700814 case GL_CLIP_PLANE0:
815 case GL_CLIP_PLANE1:
816 case GL_CLIP_PLANE2:
817 case GL_CLIP_PLANE3:
818 case GL_CLIP_PLANE4:
819 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700820 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700821 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700822 case GL_LINE_SMOOTH:
823 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700824 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700825 case GL_POINT_SIZE_ARRAY_OES:
826 return context->getClientVersion() < Version(2, 0) &&
827 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700828 case GL_TEXTURE_CUBE_MAP:
829 return context->getClientVersion() < Version(2, 0) &&
830 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700831 case GL_POINT_SPRITE_OES:
832 return context->getClientVersion() < Version(2, 0) &&
833 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400834 default:
835 return false;
836 }
837}
838
Geoff Langfc32e8b2017-05-31 14:16:59 -0400839// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
840// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400841bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400842{
843 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400844 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
845 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400846 {
847 return true;
848 }
849
850 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
851 if (c >= 9 && c <= 13)
852 {
853 return true;
854 }
855
856 return false;
857}
858
Geoff Langcab92ee2017-07-19 17:32:07 -0400859bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400860{
Geoff Langa71a98e2017-06-19 15:15:00 -0400861 for (size_t i = 0; i < len; i++)
862 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400863 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400864 {
865 return false;
866 }
867 }
868
869 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400870}
871
Geoff Langcab92ee2017-07-19 17:32:07 -0400872bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
873{
874 enum class ParseState
875 {
876 // Have not seen an ASCII non-whitespace character yet on
877 // this line. Possible that we might see a preprocessor
878 // directive.
879 BEGINING_OF_LINE,
880
881 // Have seen at least one ASCII non-whitespace character
882 // on this line.
883 MIDDLE_OF_LINE,
884
885 // Handling a preprocessor directive. Passes through all
886 // characters up to the end of the line. Disables comment
887 // processing.
888 IN_PREPROCESSOR_DIRECTIVE,
889
890 // Handling a single-line comment. The comment text is
891 // replaced with a single space.
892 IN_SINGLE_LINE_COMMENT,
893
894 // Handling a multi-line comment. Newlines are passed
895 // through to preserve line numbers.
896 IN_MULTI_LINE_COMMENT
897 };
898
899 ParseState state = ParseState::BEGINING_OF_LINE;
900 size_t pos = 0;
901
902 while (pos < len)
903 {
904 char c = str[pos];
905 char next = pos + 1 < len ? str[pos + 1] : 0;
906
907 // Check for newlines
908 if (c == '\n' || c == '\r')
909 {
910 if (state != ParseState::IN_MULTI_LINE_COMMENT)
911 {
912 state = ParseState::BEGINING_OF_LINE;
913 }
914
915 pos++;
916 continue;
917 }
918
919 switch (state)
920 {
921 case ParseState::BEGINING_OF_LINE:
922 if (c == ' ')
923 {
924 // Maintain the BEGINING_OF_LINE state until a non-space is seen
925 pos++;
926 }
927 else if (c == '#')
928 {
929 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
930 pos++;
931 }
932 else
933 {
934 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
935 state = ParseState::MIDDLE_OF_LINE;
936 }
937 break;
938
939 case ParseState::MIDDLE_OF_LINE:
940 if (c == '/' && next == '/')
941 {
942 state = ParseState::IN_SINGLE_LINE_COMMENT;
943 pos++;
944 }
945 else if (c == '/' && next == '*')
946 {
947 state = ParseState::IN_MULTI_LINE_COMMENT;
948 pos++;
949 }
950 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
951 {
952 // Skip line continuation characters
953 }
954 else if (!IsValidESSLCharacter(c))
955 {
956 return false;
957 }
958 pos++;
959 break;
960
961 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700962 // Line-continuation characters may not be permitted.
963 // Otherwise, just pass it through. Do not parse comments in this state.
964 if (!lineContinuationAllowed && c == '\\')
965 {
966 return false;
967 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400968 pos++;
969 break;
970
971 case ParseState::IN_SINGLE_LINE_COMMENT:
972 // Line-continuation characters are processed before comment processing.
973 // Advance string if a new line character is immediately behind
974 // line-continuation character.
975 if (c == '\\' && (next == '\n' || next == '\r'))
976 {
977 pos++;
978 }
979 pos++;
980 break;
981
982 case ParseState::IN_MULTI_LINE_COMMENT:
983 if (c == '*' && next == '/')
984 {
985 state = ParseState::MIDDLE_OF_LINE;
986 pos++;
987 }
988 pos++;
989 break;
990 }
991 }
992
993 return true;
994}
995
Jamie Madill5b772312018-03-08 20:28:32 -0500996bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700997{
998 ASSERT(context->isWebGL());
999
1000 // WebGL 1.0 [Section 6.16] GLSL Constructs
1001 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1002 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1003 {
1004 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1005 return false;
1006 }
1007
1008 return true;
1009}
1010
Jamie Madill5b772312018-03-08 20:28:32 -05001011bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001012{
1013 ASSERT(context->isWebGL());
1014
1015 if (context->isWebGL1() && length > 256)
1016 {
1017 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1018 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1019 // locations.
1020 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1021
1022 return false;
1023 }
1024 else if (length > 1024)
1025 {
1026 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1027 // uniform and attribute locations.
1028 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1029 return false;
1030 }
1031
1032 return true;
1033}
1034
Jamie Madill007530e2017-12-28 14:27:04 -05001035bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1036{
1037 if (!context->getExtensions().pathRendering)
1038 {
1039 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1040 return false;
1041 }
1042
1043 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1044 {
1045 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1046 return false;
1047 }
1048 return true;
1049}
Jamie Madillc29968b2016-01-20 11:17:23 -05001050} // anonymous namespace
1051
Geoff Langff5b2d52016-09-07 11:32:23 -04001052bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001053 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001054 GLint level,
1055 GLenum internalformat,
1056 bool isCompressed,
1057 bool isSubImage,
1058 GLint xoffset,
1059 GLint yoffset,
1060 GLsizei width,
1061 GLsizei height,
1062 GLint border,
1063 GLenum format,
1064 GLenum type,
1065 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001066 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001067{
Jamie Madill6f38f822014-06-06 17:12:20 -04001068 if (!ValidTexture2DDestinationTarget(context, target))
1069 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001070 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001071 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001072 }
1073
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001074 TextureType texType = TextureTargetToType(target);
1075 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001076 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001077 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001078 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001079 }
1080
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001081 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001082 {
1083 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1084 return false;
1085 }
1086
1087 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001088 std::numeric_limits<GLsizei>::max() - yoffset < height)
1089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001090 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001091 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001092 }
1093
Geoff Lang6e898aa2017-06-02 11:17:26 -04001094 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1095 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1096 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1097 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1098 // case.
1099 bool nonEqualFormatsAllowed =
1100 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1101 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1102
1103 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001104 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001105 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001106 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001107 }
1108
Geoff Langaae65a42014-05-26 12:43:44 -04001109 const gl::Caps &caps = context->getCaps();
1110
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001111 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001112 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001113 case TextureType::_2D:
1114 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1115 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1116 {
1117 context->handleError(InvalidValue());
1118 return false;
1119 }
1120 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001121
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001122 case TextureType::Rectangle:
1123 ASSERT(level == 0);
1124 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1125 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1126 {
1127 context->handleError(InvalidValue());
1128 return false;
1129 }
1130 if (isCompressed)
1131 {
1132 context->handleError(InvalidEnum()
1133 << "Rectangle texture cannot have a compressed format.");
1134 return false;
1135 }
1136 break;
1137
1138 case TextureType::CubeMap:
1139 if (!isSubImage && width != height)
1140 {
1141 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1142 return false;
1143 }
1144
1145 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1146 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1147 {
1148 context->handleError(InvalidValue());
1149 return false;
1150 }
1151 break;
1152
1153 default:
1154 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001155 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001156 }
1157
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001158 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001159 if (!texture)
1160 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001161 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001162 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001163 }
1164
Geoff Langa9be0dc2014-12-17 12:34:40 -05001165 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001166 {
Geoff Langca271392017-04-05 12:30:00 -04001167 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1168 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001169 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001170 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001171 return false;
1172 }
1173
Geoff Langa9be0dc2014-12-17 12:34:40 -05001174 if (format != GL_NONE)
1175 {
Geoff Langca271392017-04-05 12:30:00 -04001176 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1177 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001178 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001179 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001180 return false;
1181 }
1182 }
1183
1184 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1185 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1186 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001187 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001188 return false;
1189 }
Geoff Langfb052642017-10-24 13:42:09 -04001190
1191 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001192 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001193 {
1194 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1195 return false;
1196 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001197 }
1198 else
1199 {
Geoff Lang69cce582015-09-17 13:20:36 -04001200 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001201 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001202 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001203 return false;
1204 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001205 }
1206
1207 // Verify zero border
1208 if (border != 0)
1209 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001210 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001211 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001212 }
1213
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001214 if (isCompressed)
1215 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001216 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001217 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1218 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001219
1220 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1221
1222 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001223 {
Geoff Lange88e4542018-05-03 15:05:57 -04001224 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1225 return false;
1226 }
1227
1228 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1229 context->getExtensions()))
1230 {
1231 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1232 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001233 }
Geoff Lang966c9402017-04-18 12:38:27 -04001234
1235 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001236 {
Geoff Lange88e4542018-05-03 15:05:57 -04001237 // From the OES_compressed_ETC1_RGB8_texture spec:
1238 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1239 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1240 // ETC1_RGB8_OES.
1241 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1242 {
1243 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1244 return false;
1245 }
1246
Geoff Lang966c9402017-04-18 12:38:27 -04001247 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1248 height, texture->getWidth(target, level),
1249 texture->getHeight(target, level)))
1250 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001251 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001252 return false;
1253 }
1254
1255 if (format != actualInternalFormat)
1256 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001257 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001258 return false;
1259 }
1260 }
1261 else
1262 {
1263 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1264 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001265 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001266 return false;
1267 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001268 }
1269 }
1270 else
1271 {
1272 // validate <type> by itself (used as secondary key below)
1273 switch (type)
1274 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001275 case GL_UNSIGNED_BYTE:
1276 case GL_UNSIGNED_SHORT_5_6_5:
1277 case GL_UNSIGNED_SHORT_4_4_4_4:
1278 case GL_UNSIGNED_SHORT_5_5_5_1:
1279 case GL_UNSIGNED_SHORT:
1280 case GL_UNSIGNED_INT:
1281 case GL_UNSIGNED_INT_24_8_OES:
1282 case GL_HALF_FLOAT_OES:
1283 case GL_FLOAT:
1284 break;
1285 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001286 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001287 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001288 }
1289
1290 // validate <format> + <type> combinations
1291 // - invalid <format> -> sets INVALID_ENUM
1292 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1293 switch (format)
1294 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001295 case GL_ALPHA:
1296 case GL_LUMINANCE:
1297 case GL_LUMINANCE_ALPHA:
1298 switch (type)
1299 {
1300 case GL_UNSIGNED_BYTE:
1301 case GL_FLOAT:
1302 case GL_HALF_FLOAT_OES:
1303 break;
1304 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001306 return false;
1307 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001308 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001309 case GL_RED:
1310 case GL_RG:
1311 if (!context->getExtensions().textureRG)
1312 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001313 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001314 return false;
1315 }
1316 switch (type)
1317 {
1318 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001319 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001320 case GL_FLOAT:
1321 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001322 if (!context->getExtensions().textureFloat)
1323 {
1324 context->handleError(InvalidEnum());
1325 return false;
1326 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001327 break;
1328 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001329 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001330 return false;
1331 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001332 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001333 case GL_RGB:
1334 switch (type)
1335 {
1336 case GL_UNSIGNED_BYTE:
1337 case GL_UNSIGNED_SHORT_5_6_5:
1338 case GL_FLOAT:
1339 case GL_HALF_FLOAT_OES:
1340 break;
1341 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001342 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001343 return false;
1344 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001345 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001346 case GL_RGBA:
1347 switch (type)
1348 {
1349 case GL_UNSIGNED_BYTE:
1350 case GL_UNSIGNED_SHORT_4_4_4_4:
1351 case GL_UNSIGNED_SHORT_5_5_5_1:
1352 case GL_FLOAT:
1353 case GL_HALF_FLOAT_OES:
1354 break;
1355 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001356 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001357 return false;
1358 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001359 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001360 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001361 if (!context->getExtensions().textureFormatBGRA8888)
1362 {
1363 context->handleError(InvalidEnum());
1364 return false;
1365 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001366 switch (type)
1367 {
1368 case GL_UNSIGNED_BYTE:
1369 break;
1370 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001371 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001372 return false;
1373 }
1374 break;
1375 case GL_SRGB_EXT:
1376 case GL_SRGB_ALPHA_EXT:
1377 if (!context->getExtensions().sRGB)
1378 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001379 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001380 return false;
1381 }
1382 switch (type)
1383 {
1384 case GL_UNSIGNED_BYTE:
1385 break;
1386 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001387 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001388 return false;
1389 }
1390 break;
1391 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1392 // handled below
1393 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1394 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1395 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1396 break;
1397 case GL_DEPTH_COMPONENT:
1398 switch (type)
1399 {
1400 case GL_UNSIGNED_SHORT:
1401 case GL_UNSIGNED_INT:
1402 break;
1403 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001404 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001405 return false;
1406 }
1407 break;
1408 case GL_DEPTH_STENCIL_OES:
1409 switch (type)
1410 {
1411 case GL_UNSIGNED_INT_24_8_OES:
1412 break;
1413 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001414 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001415 return false;
1416 }
1417 break;
1418 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001419 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001420 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001421 }
1422
1423 switch (format)
1424 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001425 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1426 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1427 if (context->getExtensions().textureCompressionDXT1)
1428 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001429 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001430 return false;
1431 }
1432 else
1433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001434 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001435 return false;
1436 }
1437 break;
1438 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1439 if (context->getExtensions().textureCompressionDXT3)
1440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001441 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001442 return false;
1443 }
1444 else
1445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001446 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001447 return false;
1448 }
1449 break;
1450 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1451 if (context->getExtensions().textureCompressionDXT5)
1452 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001453 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001454 return false;
1455 }
1456 else
1457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001458 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001459 return false;
1460 }
1461 break;
1462 case GL_ETC1_RGB8_OES:
1463 if (context->getExtensions().compressedETC1RGB8Texture)
1464 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001465 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001466 return false;
1467 }
1468 else
1469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001470 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001471 return false;
1472 }
1473 break;
1474 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001475 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1476 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1477 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1478 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001479 if (context->getExtensions().lossyETCDecode)
1480 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001481 context->handleError(InvalidOperation()
1482 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001483 return false;
1484 }
1485 else
1486 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001487 context->handleError(InvalidEnum()
1488 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001489 return false;
1490 }
1491 break;
1492 case GL_DEPTH_COMPONENT:
1493 case GL_DEPTH_STENCIL_OES:
1494 if (!context->getExtensions().depthTextures)
1495 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001496 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 return false;
1498 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001499 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001500 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001502 return false;
1503 }
1504 // OES_depth_texture supports loading depth data and multiple levels,
1505 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001506 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001507 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1509 return false;
1510 }
1511 if (level != 0)
1512 {
1513 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001514 return false;
1515 }
1516 break;
1517 default:
1518 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001519 }
1520
Geoff Lang6e898aa2017-06-02 11:17:26 -04001521 if (!isSubImage)
1522 {
1523 switch (internalformat)
1524 {
1525 case GL_RGBA32F:
1526 if (!context->getExtensions().colorBufferFloatRGBA)
1527 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001528 context->handleError(InvalidValue()
1529 << "Sized GL_RGBA32F internal format requires "
1530 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001531 return false;
1532 }
1533 if (type != GL_FLOAT)
1534 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001535 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001536 return false;
1537 }
1538 if (format != GL_RGBA)
1539 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001540 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001541 return false;
1542 }
1543 break;
1544
1545 case GL_RGB32F:
1546 if (!context->getExtensions().colorBufferFloatRGB)
1547 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001548 context->handleError(InvalidValue()
1549 << "Sized GL_RGB32F internal format requires "
1550 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001551 return false;
1552 }
1553 if (type != GL_FLOAT)
1554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001555 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001556 return false;
1557 }
1558 if (format != GL_RGB)
1559 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001560 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001561 return false;
1562 }
1563 break;
1564
1565 default:
1566 break;
1567 }
1568 }
1569
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001570 if (type == GL_FLOAT)
1571 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001572 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001573 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001574 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001575 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001576 }
1577 }
1578 else if (type == GL_HALF_FLOAT_OES)
1579 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001580 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001581 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001582 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001583 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001584 }
1585 }
1586 }
1587
Geoff Langdbcced82017-06-06 15:55:54 -04001588 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001589 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001590 imageSize))
1591 {
1592 return false;
1593 }
1594
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001595 return true;
1596}
1597
He Yunchaoced53ae2016-11-29 15:00:51 +08001598bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001599 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001600 GLsizei levels,
1601 GLenum internalformat,
1602 GLsizei width,
1603 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001604{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001605 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1606 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001607 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001608 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001609 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001610 }
1611
1612 if (width < 1 || height < 1 || levels < 1)
1613 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001614 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001615 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001616 }
1617
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001618 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001619 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001620 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001621 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001622 }
1623
1624 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1625 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001626 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001627 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001628 }
1629
Geoff Langca271392017-04-05 12:30:00 -04001630 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001631 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001632 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001633 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001634 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001635 }
1636
Geoff Langaae65a42014-05-26 12:43:44 -04001637 const gl::Caps &caps = context->getCaps();
1638
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001639 switch (target)
1640 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001641 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001642 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1643 static_cast<GLuint>(height) > caps.max2DTextureSize)
1644 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001645 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001646 return false;
1647 }
1648 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001649 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001650 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1651 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1652 {
1653 context->handleError(InvalidValue());
1654 return false;
1655 }
1656 if (formatInfo.compressed)
1657 {
1658 context->handleError(InvalidEnum()
1659 << "Rectangle texture cannot have a compressed format.");
1660 return false;
1661 }
1662 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001663 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001664 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1665 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1666 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001667 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001668 return false;
1669 }
1670 break;
1671 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001672 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001673 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001674 }
1675
Geoff Langc0b9ef42014-07-02 10:02:37 -04001676 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001677 {
1678 if (!gl::isPow2(width) || !gl::isPow2(height))
1679 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001680 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001681 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001682 }
1683 }
1684
1685 switch (internalformat)
1686 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001687 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1688 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1689 if (!context->getExtensions().textureCompressionDXT1)
1690 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001691 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001692 return false;
1693 }
1694 break;
1695 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1696 if (!context->getExtensions().textureCompressionDXT3)
1697 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001698 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001699 return false;
1700 }
1701 break;
1702 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1703 if (!context->getExtensions().textureCompressionDXT5)
1704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001705 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001706 return false;
1707 }
1708 break;
1709 case GL_ETC1_RGB8_OES:
1710 if (!context->getExtensions().compressedETC1RGB8Texture)
1711 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001712 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001713 return false;
1714 }
1715 break;
1716 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001717 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1718 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1719 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1720 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001721 if (!context->getExtensions().lossyETCDecode)
1722 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001723 context->handleError(InvalidEnum()
1724 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001725 return false;
1726 }
1727 break;
1728 case GL_RGBA32F_EXT:
1729 case GL_RGB32F_EXT:
1730 case GL_ALPHA32F_EXT:
1731 case GL_LUMINANCE32F_EXT:
1732 case GL_LUMINANCE_ALPHA32F_EXT:
1733 if (!context->getExtensions().textureFloat)
1734 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001735 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001736 return false;
1737 }
1738 break;
1739 case GL_RGBA16F_EXT:
1740 case GL_RGB16F_EXT:
1741 case GL_ALPHA16F_EXT:
1742 case GL_LUMINANCE16F_EXT:
1743 case GL_LUMINANCE_ALPHA16F_EXT:
1744 if (!context->getExtensions().textureHalfFloat)
1745 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001746 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001747 return false;
1748 }
1749 break;
1750 case GL_R8_EXT:
1751 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001752 if (!context->getExtensions().textureRG)
1753 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001754 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001755 return false;
1756 }
1757 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001758 case GL_R16F_EXT:
1759 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001760 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1761 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001762 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001763 return false;
1764 }
1765 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001766 case GL_R32F_EXT:
1767 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001768 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001770 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001771 return false;
1772 }
1773 break;
1774 case GL_DEPTH_COMPONENT16:
1775 case GL_DEPTH_COMPONENT32_OES:
1776 case GL_DEPTH24_STENCIL8_OES:
1777 if (!context->getExtensions().depthTextures)
1778 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001779 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001780 return false;
1781 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001782 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001784 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001785 return false;
1786 }
1787 // ANGLE_depth_texture only supports 1-level textures
1788 if (levels != 1)
1789 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001790 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001791 return false;
1792 }
1793 break;
1794 default:
1795 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001796 }
1797
Geoff Lang691e58c2014-12-19 17:03:25 -05001798 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001799 if (!texture || texture->id() == 0)
1800 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001801 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001802 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001803 }
1804
Geoff Lang69cce582015-09-17 13:20:36 -04001805 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001806 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001807 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001808 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001809 }
1810
1811 return true;
1812}
1813
He Yunchaoced53ae2016-11-29 15:00:51 +08001814bool ValidateDiscardFramebufferEXT(Context *context,
1815 GLenum target,
1816 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001817 const GLenum *attachments)
1818{
Jamie Madillc29968b2016-01-20 11:17:23 -05001819 if (!context->getExtensions().discardFramebuffer)
1820 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001821 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001822 return false;
1823 }
1824
Austin Kinross08332632015-05-05 13:35:47 -07001825 bool defaultFramebuffer = false;
1826
1827 switch (target)
1828 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001829 case GL_FRAMEBUFFER:
1830 defaultFramebuffer =
1831 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1832 break;
1833 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001834 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001835 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001836 }
1837
He Yunchaoced53ae2016-11-29 15:00:51 +08001838 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1839 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001840}
1841
Austin Kinrossbc781f32015-10-26 09:27:38 -07001842bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1843{
1844 if (!context->getExtensions().vertexArrayObject)
1845 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001846 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001847 return false;
1848 }
1849
1850 return ValidateBindVertexArrayBase(context, array);
1851}
1852
Jamie Madilld7576732017-08-26 18:49:50 -04001853bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001854{
1855 if (!context->getExtensions().vertexArrayObject)
1856 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001857 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001858 return false;
1859 }
1860
Olli Etuaho41997e72016-03-10 13:38:39 +02001861 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001862}
1863
Jamie Madilld7576732017-08-26 18:49:50 -04001864bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001865{
1866 if (!context->getExtensions().vertexArrayObject)
1867 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001868 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001869 return false;
1870 }
1871
Olli Etuaho41997e72016-03-10 13:38:39 +02001872 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001873}
1874
Jamie Madilld7576732017-08-26 18:49:50 -04001875bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001876{
1877 if (!context->getExtensions().vertexArrayObject)
1878 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001879 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001880 return false;
1881 }
1882
1883 return true;
1884}
Geoff Langc5629752015-12-07 16:29:04 -05001885
1886bool ValidateProgramBinaryOES(Context *context,
1887 GLuint program,
1888 GLenum binaryFormat,
1889 const void *binary,
1890 GLint length)
1891{
1892 if (!context->getExtensions().getProgramBinary)
1893 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001894 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001895 return false;
1896 }
1897
1898 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1899}
1900
1901bool ValidateGetProgramBinaryOES(Context *context,
1902 GLuint program,
1903 GLsizei bufSize,
1904 GLsizei *length,
1905 GLenum *binaryFormat,
1906 void *binary)
1907{
1908 if (!context->getExtensions().getProgramBinary)
1909 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001910 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001911 return false;
1912 }
1913
1914 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1915}
Geoff Lange102fee2015-12-10 11:23:30 -05001916
Geoff Lang70d0f492015-12-10 17:45:46 -05001917static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1918{
1919 switch (source)
1920 {
1921 case GL_DEBUG_SOURCE_API:
1922 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1923 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1924 case GL_DEBUG_SOURCE_OTHER:
1925 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1926 return !mustBeThirdPartyOrApplication;
1927
1928 case GL_DEBUG_SOURCE_THIRD_PARTY:
1929 case GL_DEBUG_SOURCE_APPLICATION:
1930 return true;
1931
1932 default:
1933 return false;
1934 }
1935}
1936
1937static bool ValidDebugType(GLenum type)
1938{
1939 switch (type)
1940 {
1941 case GL_DEBUG_TYPE_ERROR:
1942 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1943 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1944 case GL_DEBUG_TYPE_PERFORMANCE:
1945 case GL_DEBUG_TYPE_PORTABILITY:
1946 case GL_DEBUG_TYPE_OTHER:
1947 case GL_DEBUG_TYPE_MARKER:
1948 case GL_DEBUG_TYPE_PUSH_GROUP:
1949 case GL_DEBUG_TYPE_POP_GROUP:
1950 return true;
1951
1952 default:
1953 return false;
1954 }
1955}
1956
1957static bool ValidDebugSeverity(GLenum severity)
1958{
1959 switch (severity)
1960 {
1961 case GL_DEBUG_SEVERITY_HIGH:
1962 case GL_DEBUG_SEVERITY_MEDIUM:
1963 case GL_DEBUG_SEVERITY_LOW:
1964 case GL_DEBUG_SEVERITY_NOTIFICATION:
1965 return true;
1966
1967 default:
1968 return false;
1969 }
1970}
1971
Geoff Lange102fee2015-12-10 11:23:30 -05001972bool ValidateDebugMessageControlKHR(Context *context,
1973 GLenum source,
1974 GLenum type,
1975 GLenum severity,
1976 GLsizei count,
1977 const GLuint *ids,
1978 GLboolean enabled)
1979{
1980 if (!context->getExtensions().debug)
1981 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001982 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001983 return false;
1984 }
1985
Geoff Lang70d0f492015-12-10 17:45:46 -05001986 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1987 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001988 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001989 return false;
1990 }
1991
1992 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1993 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001994 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001995 return false;
1996 }
1997
1998 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1999 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002000 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002001 return false;
2002 }
2003
2004 if (count > 0)
2005 {
2006 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002008 context->handleError(
2009 InvalidOperation()
2010 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002011 return false;
2012 }
2013
2014 if (severity != GL_DONT_CARE)
2015 {
Jamie Madill437fa652016-05-03 15:13:24 -04002016 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002017 InvalidOperation()
2018 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002019 return false;
2020 }
2021 }
2022
Geoff Lange102fee2015-12-10 11:23:30 -05002023 return true;
2024}
2025
2026bool ValidateDebugMessageInsertKHR(Context *context,
2027 GLenum source,
2028 GLenum type,
2029 GLuint id,
2030 GLenum severity,
2031 GLsizei length,
2032 const GLchar *buf)
2033{
2034 if (!context->getExtensions().debug)
2035 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002036 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002037 return false;
2038 }
2039
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002040 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002041 {
2042 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2043 // not generate an error.
2044 return false;
2045 }
2046
2047 if (!ValidDebugSeverity(severity))
2048 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002049 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002050 return false;
2051 }
2052
2053 if (!ValidDebugType(type))
2054 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002055 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002056 return false;
2057 }
2058
2059 if (!ValidDebugSource(source, true))
2060 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002061 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002062 return false;
2063 }
2064
2065 size_t messageLength = (length < 0) ? strlen(buf) : length;
2066 if (messageLength > context->getExtensions().maxDebugMessageLength)
2067 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002068 context->handleError(InvalidValue()
2069 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002070 return false;
2071 }
2072
Geoff Lange102fee2015-12-10 11:23:30 -05002073 return true;
2074}
2075
2076bool ValidateDebugMessageCallbackKHR(Context *context,
2077 GLDEBUGPROCKHR callback,
2078 const void *userParam)
2079{
2080 if (!context->getExtensions().debug)
2081 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002082 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002083 return false;
2084 }
2085
Geoff Lange102fee2015-12-10 11:23:30 -05002086 return true;
2087}
2088
2089bool ValidateGetDebugMessageLogKHR(Context *context,
2090 GLuint count,
2091 GLsizei bufSize,
2092 GLenum *sources,
2093 GLenum *types,
2094 GLuint *ids,
2095 GLenum *severities,
2096 GLsizei *lengths,
2097 GLchar *messageLog)
2098{
2099 if (!context->getExtensions().debug)
2100 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002101 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002102 return false;
2103 }
2104
Geoff Lang70d0f492015-12-10 17:45:46 -05002105 if (bufSize < 0 && messageLog != nullptr)
2106 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002107 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002108 return false;
2109 }
2110
Geoff Lange102fee2015-12-10 11:23:30 -05002111 return true;
2112}
2113
2114bool ValidatePushDebugGroupKHR(Context *context,
2115 GLenum source,
2116 GLuint id,
2117 GLsizei length,
2118 const GLchar *message)
2119{
2120 if (!context->getExtensions().debug)
2121 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002122 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002123 return false;
2124 }
2125
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 if (!ValidDebugSource(source, true))
2127 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002128 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002129 return false;
2130 }
2131
2132 size_t messageLength = (length < 0) ? strlen(message) : length;
2133 if (messageLength > context->getExtensions().maxDebugMessageLength)
2134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002135 context->handleError(InvalidValue()
2136 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002137 return false;
2138 }
2139
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002140 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002141 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002143 context
2144 ->handleError(StackOverflow()
2145 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002146 return false;
2147 }
2148
Geoff Lange102fee2015-12-10 11:23:30 -05002149 return true;
2150}
2151
2152bool ValidatePopDebugGroupKHR(Context *context)
2153{
2154 if (!context->getExtensions().debug)
2155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002156 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002157 return false;
2158 }
2159
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002160 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002161 if (currentStackSize <= 1)
2162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002163 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002164 return false;
2165 }
2166
2167 return true;
2168}
2169
2170static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2171{
2172 switch (identifier)
2173 {
2174 case GL_BUFFER:
2175 if (context->getBuffer(name) == nullptr)
2176 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002177 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002178 return false;
2179 }
2180 return true;
2181
2182 case GL_SHADER:
2183 if (context->getShader(name) == nullptr)
2184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002185 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002186 return false;
2187 }
2188 return true;
2189
2190 case GL_PROGRAM:
2191 if (context->getProgram(name) == nullptr)
2192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002193 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002194 return false;
2195 }
2196 return true;
2197
2198 case GL_VERTEX_ARRAY:
2199 if (context->getVertexArray(name) == nullptr)
2200 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002201 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002202 return false;
2203 }
2204 return true;
2205
2206 case GL_QUERY:
2207 if (context->getQuery(name) == nullptr)
2208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002209 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002210 return false;
2211 }
2212 return true;
2213
2214 case GL_TRANSFORM_FEEDBACK:
2215 if (context->getTransformFeedback(name) == nullptr)
2216 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002217 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002218 return false;
2219 }
2220 return true;
2221
2222 case GL_SAMPLER:
2223 if (context->getSampler(name) == nullptr)
2224 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002225 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002226 return false;
2227 }
2228 return true;
2229
2230 case GL_TEXTURE:
2231 if (context->getTexture(name) == nullptr)
2232 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002233 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002234 return false;
2235 }
2236 return true;
2237
2238 case GL_RENDERBUFFER:
2239 if (context->getRenderbuffer(name) == nullptr)
2240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002241 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002242 return false;
2243 }
2244 return true;
2245
2246 case GL_FRAMEBUFFER:
2247 if (context->getFramebuffer(name) == nullptr)
2248 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002249 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002250 return false;
2251 }
2252 return true;
2253
2254 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002255 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002256 return false;
2257 }
Geoff Lange102fee2015-12-10 11:23:30 -05002258}
2259
Martin Radev9d901792016-07-15 15:58:58 +03002260static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2261{
2262 size_t labelLength = 0;
2263
2264 if (length < 0)
2265 {
2266 if (label != nullptr)
2267 {
2268 labelLength = strlen(label);
2269 }
2270 }
2271 else
2272 {
2273 labelLength = static_cast<size_t>(length);
2274 }
2275
2276 if (labelLength > context->getExtensions().maxLabelLength)
2277 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002278 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002279 return false;
2280 }
2281
2282 return true;
2283}
2284
Geoff Lange102fee2015-12-10 11:23:30 -05002285bool ValidateObjectLabelKHR(Context *context,
2286 GLenum identifier,
2287 GLuint name,
2288 GLsizei length,
2289 const GLchar *label)
2290{
2291 if (!context->getExtensions().debug)
2292 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002293 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002294 return false;
2295 }
2296
Geoff Lang70d0f492015-12-10 17:45:46 -05002297 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2298 {
2299 return false;
2300 }
2301
Martin Radev9d901792016-07-15 15:58:58 +03002302 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002303 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002304 return false;
2305 }
2306
Geoff Lange102fee2015-12-10 11:23:30 -05002307 return true;
2308}
2309
2310bool ValidateGetObjectLabelKHR(Context *context,
2311 GLenum identifier,
2312 GLuint name,
2313 GLsizei bufSize,
2314 GLsizei *length,
2315 GLchar *label)
2316{
2317 if (!context->getExtensions().debug)
2318 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002319 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002320 return false;
2321 }
2322
Geoff Lang70d0f492015-12-10 17:45:46 -05002323 if (bufSize < 0)
2324 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002325 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002326 return false;
2327 }
2328
2329 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2330 {
2331 return false;
2332 }
2333
Martin Radev9d901792016-07-15 15:58:58 +03002334 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002335}
2336
2337static bool ValidateObjectPtrName(Context *context, const void *ptr)
2338{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002339 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002340 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002341 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002342 return false;
2343 }
2344
Geoff Lange102fee2015-12-10 11:23:30 -05002345 return true;
2346}
2347
2348bool ValidateObjectPtrLabelKHR(Context *context,
2349 const void *ptr,
2350 GLsizei length,
2351 const GLchar *label)
2352{
2353 if (!context->getExtensions().debug)
2354 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002355 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002356 return false;
2357 }
2358
Geoff Lang70d0f492015-12-10 17:45:46 -05002359 if (!ValidateObjectPtrName(context, ptr))
2360 {
2361 return false;
2362 }
2363
Martin Radev9d901792016-07-15 15:58:58 +03002364 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002365 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002366 return false;
2367 }
2368
Geoff Lange102fee2015-12-10 11:23:30 -05002369 return true;
2370}
2371
2372bool ValidateGetObjectPtrLabelKHR(Context *context,
2373 const void *ptr,
2374 GLsizei bufSize,
2375 GLsizei *length,
2376 GLchar *label)
2377{
2378 if (!context->getExtensions().debug)
2379 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002380 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002381 return false;
2382 }
2383
Geoff Lang70d0f492015-12-10 17:45:46 -05002384 if (bufSize < 0)
2385 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002386 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002387 return false;
2388 }
2389
2390 if (!ValidateObjectPtrName(context, ptr))
2391 {
2392 return false;
2393 }
2394
Martin Radev9d901792016-07-15 15:58:58 +03002395 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002396}
2397
2398bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2399{
2400 if (!context->getExtensions().debug)
2401 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002402 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002403 return false;
2404 }
2405
Geoff Lang70d0f492015-12-10 17:45:46 -05002406 // TODO: represent this in Context::getQueryParameterInfo.
2407 switch (pname)
2408 {
2409 case GL_DEBUG_CALLBACK_FUNCTION:
2410 case GL_DEBUG_CALLBACK_USER_PARAM:
2411 break;
2412
2413 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002414 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002415 return false;
2416 }
2417
Geoff Lange102fee2015-12-10 11:23:30 -05002418 return true;
2419}
Jamie Madillc29968b2016-01-20 11:17:23 -05002420
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002421bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2422 GLenum pname,
2423 GLsizei bufSize,
2424 GLsizei *length,
2425 void **params)
2426{
2427 UNIMPLEMENTED();
2428 return false;
2429}
2430
Jamie Madillc29968b2016-01-20 11:17:23 -05002431bool ValidateBlitFramebufferANGLE(Context *context,
2432 GLint srcX0,
2433 GLint srcY0,
2434 GLint srcX1,
2435 GLint srcY1,
2436 GLint dstX0,
2437 GLint dstY0,
2438 GLint dstX1,
2439 GLint dstY1,
2440 GLbitfield mask,
2441 GLenum filter)
2442{
2443 if (!context->getExtensions().framebufferBlit)
2444 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002445 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002446 return false;
2447 }
2448
2449 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2450 {
2451 // TODO(jmadill): Determine if this should be available on other implementations.
Olli Etuahof0e3c192018-08-15 13:37:21 +03002452 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002453 return false;
2454 }
2455
2456 if (filter == GL_LINEAR)
2457 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002458 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002459 return false;
2460 }
2461
Jamie Madill51f40ec2016-06-15 14:06:00 -04002462 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2463 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002464
2465 if (mask & GL_COLOR_BUFFER_BIT)
2466 {
2467 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2468 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2469
2470 if (readColorAttachment && drawColorAttachment)
2471 {
2472 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002473 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002474 readColorAttachment->type() != GL_RENDERBUFFER &&
2475 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2476 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002477 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2478 BlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002479 return false;
2480 }
2481
Geoff Langa15472a2015-08-11 11:48:03 -04002482 for (size_t drawbufferIdx = 0;
2483 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002484 {
Geoff Langa15472a2015-08-11 11:48:03 -04002485 const FramebufferAttachment *attachment =
2486 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2487 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002488 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002489 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002490 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 attachment->type() != GL_RENDERBUFFER &&
2492 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2493 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002494 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2495 BlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002496 return false;
2497 }
2498
2499 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002500 if (!Format::EquivalentForBlit(attachment->getFormat(),
2501 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002502 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002503 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2504 BlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002505 return false;
2506 }
2507 }
2508 }
2509
Jamie Madill427064d2018-04-13 16:20:34 -04002510 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002511 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002512 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2513 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2514 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002515 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2516 BlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002517 return false;
2518 }
2519 }
2520 }
2521
2522 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2523 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2524 for (size_t i = 0; i < 2; i++)
2525 {
2526 if (mask & masks[i])
2527 {
2528 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002529 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002530 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002531 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002532
2533 if (readBuffer && drawBuffer)
2534 {
2535 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2536 dstX0, dstY0, dstX1, dstY1))
2537 {
2538 // only whole-buffer copies are permitted
Olli Etuahof0e3c192018-08-15 13:37:21 +03002539 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2540 BlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002541 return false;
2542 }
2543
2544 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2545 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002546 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2547 BlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002548 return false;
2549 }
2550 }
2551 }
2552 }
2553
2554 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2555 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002556}
Jamie Madillc29968b2016-01-20 11:17:23 -05002557
Jamie Madill5b772312018-03-08 20:28:32 -05002558bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002559{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002560 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002561 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002562
Jamie Madill427064d2018-04-13 16:20:34 -04002563 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002564 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002565 return false;
2566 }
2567
2568 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2569 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002570 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002571 return false;
2572 }
2573
Olli Etuaho94c91a92018-07-19 15:10:24 +03002574 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002575 {
2576 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2577 GL_SIGNED_NORMALIZED};
2578
Corentin Wallez59c41592017-07-11 13:19:54 -04002579 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002580 drawBufferIdx++)
2581 {
2582 if (!ValidateWebGLFramebufferAttachmentClearType(
2583 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2584 {
2585 return false;
2586 }
2587 }
2588 }
2589
Olli Etuaho94c91a92018-07-19 15:10:24 +03002590 if (extensions.multiview && extensions.disjointTimerQuery)
2591 {
2592 const State &state = context->getGLState();
2593 Framebuffer *framebuffer = state.getDrawFramebuffer();
2594 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2595 {
2596 context->handleError(InvalidOperation() << "There is an active query for target "
2597 "GL_TIME_ELAPSED_EXT when the number of "
2598 "views in the active draw framebuffer is "
2599 "greater than 1.");
2600 return false;
2601 }
2602 }
2603
Jamie Madillc29968b2016-01-20 11:17:23 -05002604 return true;
2605}
2606
Jamie Madill5b772312018-03-08 20:28:32 -05002607bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002608{
2609 if (!context->getExtensions().drawBuffers)
2610 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002611 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002612 return false;
2613 }
2614
2615 return ValidateDrawBuffersBase(context, n, bufs);
2616}
2617
Jamie Madill73a84962016-02-12 09:27:23 -05002618bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002619 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002620 GLint level,
2621 GLint internalformat,
2622 GLsizei width,
2623 GLsizei height,
2624 GLint border,
2625 GLenum format,
2626 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002627 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002628{
Martin Radev1be913c2016-07-11 17:59:16 +03002629 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002630 {
2631 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002632 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002633 }
2634
Martin Radev1be913c2016-07-11 17:59:16 +03002635 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002636 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002637 0, 0, width, height, 1, border, format, type, -1,
2638 pixels);
2639}
2640
Brandon Jones416aaf92018-04-10 08:10:16 -07002641bool ValidateTexImage2DRobustANGLE(Context *context,
2642 TextureTarget target,
2643 GLint level,
2644 GLint internalformat,
2645 GLsizei width,
2646 GLsizei height,
2647 GLint border,
2648 GLenum format,
2649 GLenum type,
2650 GLsizei bufSize,
2651 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002652{
2653 if (!ValidateRobustEntryPoint(context, bufSize))
2654 {
2655 return false;
2656 }
2657
2658 if (context->getClientMajorVersion() < 3)
2659 {
2660 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2661 0, 0, width, height, border, format, type, bufSize,
2662 pixels);
2663 }
2664
2665 ASSERT(context->getClientMajorVersion() >= 3);
2666 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2667 0, 0, width, height, 1, border, format, type, bufSize,
2668 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002669}
2670
2671bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002672 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002673 GLint level,
2674 GLint xoffset,
2675 GLint yoffset,
2676 GLsizei width,
2677 GLsizei height,
2678 GLenum format,
2679 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002680 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002681{
2682
Martin Radev1be913c2016-07-11 17:59:16 +03002683 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002684 {
2685 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002686 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002687 }
2688
Martin Radev1be913c2016-07-11 17:59:16 +03002689 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002690 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002691 yoffset, 0, width, height, 1, 0, format, type, -1,
2692 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002693}
2694
Geoff Langc52f6f12016-10-14 10:18:00 -04002695bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002696 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002697 GLint level,
2698 GLint xoffset,
2699 GLint yoffset,
2700 GLsizei width,
2701 GLsizei height,
2702 GLenum format,
2703 GLenum type,
2704 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002705 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002706{
2707 if (!ValidateRobustEntryPoint(context, bufSize))
2708 {
2709 return false;
2710 }
2711
2712 if (context->getClientMajorVersion() < 3)
2713 {
2714 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2715 yoffset, width, height, 0, format, type, bufSize,
2716 pixels);
2717 }
2718
2719 ASSERT(context->getClientMajorVersion() >= 3);
2720 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2721 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2722 pixels);
2723}
2724
Jamie Madill73a84962016-02-12 09:27:23 -05002725bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002726 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002727 GLint level,
2728 GLenum internalformat,
2729 GLsizei width,
2730 GLsizei height,
2731 GLint border,
2732 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002733 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002734{
Martin Radev1be913c2016-07-11 17:59:16 +03002735 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002736 {
2737 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002738 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002739 {
2740 return false;
2741 }
2742 }
2743 else
2744 {
Martin Radev1be913c2016-07-11 17:59:16 +03002745 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002746 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002747 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002748 data))
2749 {
2750 return false;
2751 }
2752 }
2753
Geoff Langca271392017-04-05 12:30:00 -04002754 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002755
2756 GLuint blockSize = 0;
2757 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002758 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002759 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002760 return false;
2761 }
2762
Jamie Madillca2ff382018-07-11 09:01:17 -04002763 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002764 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002765 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002766 return false;
2767 }
2768
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002769 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002770 {
2771 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2772 return false;
2773 }
2774
Jamie Madill73a84962016-02-12 09:27:23 -05002775 return true;
2776}
2777
Corentin Wallezb2931602017-04-11 15:58:57 -04002778bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002779 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002780 GLint level,
2781 GLenum internalformat,
2782 GLsizei width,
2783 GLsizei height,
2784 GLint border,
2785 GLsizei imageSize,
2786 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002787 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002788{
2789 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2790 {
2791 return false;
2792 }
2793
2794 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2795 border, imageSize, data);
2796}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002797
Corentin Wallezb2931602017-04-11 15:58:57 -04002798bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002799 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002800 GLint level,
2801 GLint xoffset,
2802 GLint yoffset,
2803 GLsizei width,
2804 GLsizei height,
2805 GLenum format,
2806 GLsizei imageSize,
2807 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002808 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002809{
2810 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2811 {
2812 return false;
2813 }
2814
2815 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2816 format, imageSize, data);
2817}
2818
Jamie Madill73a84962016-02-12 09:27:23 -05002819bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002820 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002821 GLint level,
2822 GLint xoffset,
2823 GLint yoffset,
2824 GLsizei width,
2825 GLsizei height,
2826 GLenum format,
2827 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002828 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002829{
Martin Radev1be913c2016-07-11 17:59:16 +03002830 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002831 {
2832 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002833 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002834 {
2835 return false;
2836 }
2837 }
2838 else
2839 {
Martin Radev1be913c2016-07-11 17:59:16 +03002840 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002841 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002842 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002843 data))
2844 {
2845 return false;
2846 }
2847 }
2848
Geoff Langca271392017-04-05 12:30:00 -04002849 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002850 GLuint blockSize = 0;
2851 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002852 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002853 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002854 return false;
2855 }
2856
Jamie Madillca2ff382018-07-11 09:01:17 -04002857 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002858 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002859 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002860 return false;
2861 }
2862
2863 return true;
2864}
2865
Corentin Wallez336129f2017-10-17 15:55:40 -04002866bool ValidateGetBufferPointervOES(Context *context,
2867 BufferBinding target,
2868 GLenum pname,
2869 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002870{
Geoff Lang496c02d2016-10-20 11:38:11 -07002871 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002872}
2873
Corentin Wallez336129f2017-10-17 15:55:40 -04002874bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002875{
2876 if (!context->getExtensions().mapBuffer)
2877 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002878 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002879 return false;
2880 }
2881
Corentin Walleze4477002017-12-01 14:39:58 -05002882 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002884 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002885 return false;
2886 }
2887
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002888 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002889
2890 if (buffer == nullptr)
2891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002892 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002893 return false;
2894 }
2895
2896 if (access != GL_WRITE_ONLY_OES)
2897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002898 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002899 return false;
2900 }
2901
2902 if (buffer->isMapped())
2903 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002904 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002905 return false;
2906 }
2907
Geoff Lang79f71042017-08-14 16:43:43 -04002908 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002909}
2910
Corentin Wallez336129f2017-10-17 15:55:40 -04002911bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002912{
2913 if (!context->getExtensions().mapBuffer)
2914 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002915 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002916 return false;
2917 }
2918
2919 return ValidateUnmapBufferBase(context, target);
2920}
2921
2922bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002923 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002924 GLintptr offset,
2925 GLsizeiptr length,
2926 GLbitfield access)
2927{
2928 if (!context->getExtensions().mapBufferRange)
2929 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002930 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002931 return false;
2932 }
2933
2934 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2935}
2936
Corentin Wallez336129f2017-10-17 15:55:40 -04002937bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002938{
2939 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2940 ASSERT(buffer != nullptr);
2941
2942 // Check if this buffer is currently being used as a transform feedback output buffer
2943 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2944 if (transformFeedback != nullptr && transformFeedback->isActive())
2945 {
2946 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2947 {
2948 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2949 if (transformFeedbackBuffer.get() == buffer)
2950 {
2951 context->handleError(InvalidOperation()
2952 << "Buffer is currently bound for transform feedback.");
2953 return false;
2954 }
2955 }
2956 }
2957
James Darpiniane8a93c62018-01-04 18:02:24 -08002958 if (context->getExtensions().webglCompatibility &&
2959 buffer->isBoundForTransformFeedbackAndOtherUse())
2960 {
2961 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2962 return false;
2963 }
2964
Geoff Lang79f71042017-08-14 16:43:43 -04002965 return true;
2966}
2967
Olli Etuaho4f667482016-03-30 15:56:35 +03002968bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002969 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002970 GLintptr offset,
2971 GLsizeiptr length)
2972{
2973 if (!context->getExtensions().mapBufferRange)
2974 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002975 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002976 return false;
2977 }
2978
2979 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2980}
2981
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002982bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002983{
Ian Ewell54f87462016-03-10 13:47:21 -05002984 switch (target)
2985 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002986 case TextureType::_2D:
2987 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002988 break;
2989
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002990 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002991 if (!context->getExtensions().textureRectangle)
2992 {
2993 context->handleError(InvalidEnum()
2994 << "Context does not support GL_ANGLE_texture_rectangle");
2995 return false;
2996 }
2997 break;
2998
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002999 case TextureType::_3D:
3000 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03003001 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003002 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003003 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003004 return false;
3005 }
3006 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003007
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003008 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003009 if (context->getClientVersion() < Version(3, 1))
3010 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003011 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003012 return false;
3013 }
Geoff Lang3b573612016-10-31 14:08:10 -04003014 break;
Olli Etuahod310a432018-08-24 15:40:23 +03003015 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +03003016 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03003017 {
3018 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
3019 return false;
3020 }
3021 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003022 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003023 if (!context->getExtensions().eglImageExternal &&
3024 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003025 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003026 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003027 return false;
3028 }
3029 break;
3030 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003031 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003032 return false;
3033 }
3034
Jamie Madill0fdb9562018-09-17 17:18:43 -04003035 if (texture == 0)
3036 {
3037 return true;
3038 }
3039
3040 Texture *textureObject = context->getTexture(texture);
3041 if (textureObject && textureObject->getType() != target)
3042 {
3043 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
3044 return false;
3045 }
3046
3047 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3048 !context->isTextureGenerated(texture))
3049 {
3050 context->handleError(InvalidOperation() << "Texture was not generated");
3051 return false;
3052 }
3053
Ian Ewell54f87462016-03-10 13:47:21 -05003054 return true;
3055}
3056
Geoff Langd8605522016-04-13 10:19:12 -04003057bool ValidateBindUniformLocationCHROMIUM(Context *context,
3058 GLuint program,
3059 GLint location,
3060 const GLchar *name)
3061{
3062 if (!context->getExtensions().bindUniformLocation)
3063 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003064 context->handleError(InvalidOperation()
3065 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003066 return false;
3067 }
3068
3069 Program *programObject = GetValidProgram(context, program);
3070 if (!programObject)
3071 {
3072 return false;
3073 }
3074
3075 if (location < 0)
3076 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003077 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003078 return false;
3079 }
3080
3081 const Caps &caps = context->getCaps();
3082 if (static_cast<size_t>(location) >=
3083 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3084 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003085 context->handleError(InvalidValue() << "Location must be less than "
3086 "(MAX_VERTEX_UNIFORM_VECTORS + "
3087 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003088 return false;
3089 }
3090
Geoff Langfc32e8b2017-05-31 14:16:59 -04003091 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3092 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003093 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003094 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003095 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003096 return false;
3097 }
3098
Geoff Langd8605522016-04-13 10:19:12 -04003099 if (strncmp(name, "gl_", 3) == 0)
3100 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003101 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003102 return false;
3103 }
3104
3105 return true;
3106}
3107
Jamie Madille2e406c2016-06-02 13:04:10 -04003108bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003109{
3110 if (!context->getExtensions().framebufferMixedSamples)
3111 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003112 context->handleError(InvalidOperation()
3113 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003114 return false;
3115 }
3116 switch (components)
3117 {
3118 case GL_RGB:
3119 case GL_RGBA:
3120 case GL_ALPHA:
3121 case GL_NONE:
3122 break;
3123 default:
3124 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003125 InvalidEnum()
3126 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003127 return false;
3128 }
3129
3130 return true;
3131}
3132
Sami Väisänene45e53b2016-05-25 10:36:04 +03003133// CHROMIUM_path_rendering
3134
Jamie Madill007530e2017-12-28 14:27:04 -05003135bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003136{
Jamie Madill007530e2017-12-28 14:27:04 -05003137 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003138 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003139 return false;
3140 }
Jamie Madill007530e2017-12-28 14:27:04 -05003141
Sami Väisänene45e53b2016-05-25 10:36:04 +03003142 if (matrix == nullptr)
3143 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003144 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003145 return false;
3146 }
Jamie Madill007530e2017-12-28 14:27:04 -05003147
Sami Väisänene45e53b2016-05-25 10:36:04 +03003148 return true;
3149}
3150
Jamie Madill007530e2017-12-28 14:27:04 -05003151bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003152{
Jamie Madill007530e2017-12-28 14:27:04 -05003153 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003154}
3155
Jamie Madill007530e2017-12-28 14:27:04 -05003156bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003157{
3158 if (!context->getExtensions().pathRendering)
3159 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003160 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003161 return false;
3162 }
3163
3164 // range = 0 is undefined in NV_path_rendering.
3165 // we add stricter semantic check here and require a non zero positive range.
3166 if (range <= 0)
3167 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003168 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003169 return false;
3170 }
3171
3172 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3173 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003174 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003175 return false;
3176 }
3177
3178 return true;
3179}
3180
Jamie Madill007530e2017-12-28 14:27:04 -05003181bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003182{
3183 if (!context->getExtensions().pathRendering)
3184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003185 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003186 return false;
3187 }
3188
3189 // range = 0 is undefined in NV_path_rendering.
3190 // we add stricter semantic check here and require a non zero positive range.
3191 if (range <= 0)
3192 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003193 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003194 return false;
3195 }
3196
3197 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3198 checkedRange += range;
3199
3200 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3201 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003202 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003203 return false;
3204 }
3205 return true;
3206}
3207
Jamie Madill007530e2017-12-28 14:27:04 -05003208bool ValidatePathCommandsCHROMIUM(Context *context,
3209 GLuint path,
3210 GLsizei numCommands,
3211 const GLubyte *commands,
3212 GLsizei numCoords,
3213 GLenum coordType,
3214 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003215{
3216 if (!context->getExtensions().pathRendering)
3217 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003218 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003219 return false;
3220 }
Brandon Jones59770802018-04-02 13:18:42 -07003221 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003222 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003223 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003224 return false;
3225 }
3226
3227 if (numCommands < 0)
3228 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003229 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003230 return false;
3231 }
3232 else if (numCommands > 0)
3233 {
3234 if (!commands)
3235 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003236 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003237 return false;
3238 }
3239 }
3240
3241 if (numCoords < 0)
3242 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003243 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003244 return false;
3245 }
3246 else if (numCoords > 0)
3247 {
3248 if (!coords)
3249 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003250 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003251 return false;
3252 }
3253 }
3254
3255 std::uint32_t coordTypeSize = 0;
3256 switch (coordType)
3257 {
3258 case GL_BYTE:
3259 coordTypeSize = sizeof(GLbyte);
3260 break;
3261
3262 case GL_UNSIGNED_BYTE:
3263 coordTypeSize = sizeof(GLubyte);
3264 break;
3265
3266 case GL_SHORT:
3267 coordTypeSize = sizeof(GLshort);
3268 break;
3269
3270 case GL_UNSIGNED_SHORT:
3271 coordTypeSize = sizeof(GLushort);
3272 break;
3273
3274 case GL_FLOAT:
3275 coordTypeSize = sizeof(GLfloat);
3276 break;
3277
3278 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003279 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280 return false;
3281 }
3282
3283 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3284 checkedSize += (coordTypeSize * numCoords);
3285 if (!checkedSize.IsValid())
3286 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003287 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003288 return false;
3289 }
3290
3291 // early return skips command data validation when it doesn't exist.
3292 if (!commands)
3293 return true;
3294
3295 GLsizei expectedNumCoords = 0;
3296 for (GLsizei i = 0; i < numCommands; ++i)
3297 {
3298 switch (commands[i])
3299 {
3300 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3301 break;
3302 case GL_MOVE_TO_CHROMIUM:
3303 case GL_LINE_TO_CHROMIUM:
3304 expectedNumCoords += 2;
3305 break;
3306 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3307 expectedNumCoords += 4;
3308 break;
3309 case GL_CUBIC_CURVE_TO_CHROMIUM:
3310 expectedNumCoords += 6;
3311 break;
3312 case GL_CONIC_CURVE_TO_CHROMIUM:
3313 expectedNumCoords += 5;
3314 break;
3315 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003316 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317 return false;
3318 }
3319 }
3320 if (expectedNumCoords != numCoords)
3321 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003322 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003323 return false;
3324 }
3325
3326 return true;
3327}
3328
Jamie Madill007530e2017-12-28 14:27:04 -05003329bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003330{
3331 if (!context->getExtensions().pathRendering)
3332 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003333 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003334 return false;
3335 }
Brandon Jones59770802018-04-02 13:18:42 -07003336 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003337 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003338 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003339 return false;
3340 }
3341
3342 switch (pname)
3343 {
3344 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3345 if (value < 0.0f)
3346 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003347 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003348 return false;
3349 }
3350 break;
3351 case GL_PATH_END_CAPS_CHROMIUM:
3352 switch (static_cast<GLenum>(value))
3353 {
3354 case GL_FLAT_CHROMIUM:
3355 case GL_SQUARE_CHROMIUM:
3356 case GL_ROUND_CHROMIUM:
3357 break;
3358 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003359 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003360 return false;
3361 }
3362 break;
3363 case GL_PATH_JOIN_STYLE_CHROMIUM:
3364 switch (static_cast<GLenum>(value))
3365 {
3366 case GL_MITER_REVERT_CHROMIUM:
3367 case GL_BEVEL_CHROMIUM:
3368 case GL_ROUND_CHROMIUM:
3369 break;
3370 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003371 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003372 return false;
3373 }
Nico Weber41b072b2018-02-09 10:01:32 -05003374 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003375 case GL_PATH_MITER_LIMIT_CHROMIUM:
3376 if (value < 0.0f)
3377 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003378 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003379 return false;
3380 }
3381 break;
3382
3383 case GL_PATH_STROKE_BOUND_CHROMIUM:
3384 // no errors, only clamping.
3385 break;
3386
3387 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003388 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003389 return false;
3390 }
3391 return true;
3392}
3393
Jamie Madill007530e2017-12-28 14:27:04 -05003394bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3395{
3396 // TODO(jmadill): Use proper clamping cast.
3397 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3398}
3399
3400bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003401{
3402 if (!context->getExtensions().pathRendering)
3403 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003404 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003405 return false;
3406 }
3407
Brandon Jones59770802018-04-02 13:18:42 -07003408 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003409 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003410 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003411 return false;
3412 }
3413 if (!value)
3414 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003415 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003416 return false;
3417 }
3418
3419 switch (pname)
3420 {
3421 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3422 case GL_PATH_END_CAPS_CHROMIUM:
3423 case GL_PATH_JOIN_STYLE_CHROMIUM:
3424 case GL_PATH_MITER_LIMIT_CHROMIUM:
3425 case GL_PATH_STROKE_BOUND_CHROMIUM:
3426 break;
3427
3428 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003429 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003430 return false;
3431 }
3432
3433 return true;
3434}
3435
Jamie Madill007530e2017-12-28 14:27:04 -05003436bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3437{
3438 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3439 reinterpret_cast<GLfloat *>(value));
3440}
3441
3442bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003443{
3444 if (!context->getExtensions().pathRendering)
3445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003446 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003447 return false;
3448 }
3449
3450 switch (func)
3451 {
3452 case GL_NEVER:
3453 case GL_ALWAYS:
3454 case GL_LESS:
3455 case GL_LEQUAL:
3456 case GL_EQUAL:
3457 case GL_GEQUAL:
3458 case GL_GREATER:
3459 case GL_NOTEQUAL:
3460 break;
3461 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003462 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003463 return false;
3464 }
3465
3466 return true;
3467}
3468
3469// Note that the spec specifies that for the path drawing commands
3470// if the path object is not an existing path object the command
3471// does nothing and no error is generated.
3472// However if the path object exists but has not been specified any
3473// commands then an error is generated.
3474
Jamie Madill007530e2017-12-28 14:27:04 -05003475bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003476{
3477 if (!context->getExtensions().pathRendering)
3478 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003479 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003480 return false;
3481 }
Brandon Jones59770802018-04-02 13:18:42 -07003482 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003483 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003484 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003485 return false;
3486 }
3487
3488 switch (fillMode)
3489 {
3490 case GL_COUNT_UP_CHROMIUM:
3491 case GL_COUNT_DOWN_CHROMIUM:
3492 break;
3493 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003494 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003495 return false;
3496 }
3497
3498 if (!isPow2(mask + 1))
3499 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003500 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003501 return false;
3502 }
3503
3504 return true;
3505}
3506
Jamie Madill007530e2017-12-28 14:27:04 -05003507bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003508{
3509 if (!context->getExtensions().pathRendering)
3510 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003511 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003512 return false;
3513 }
Brandon Jones59770802018-04-02 13:18:42 -07003514 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003515 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003516 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003517 return false;
3518 }
3519
3520 return true;
3521}
3522
Brandon Jonesd1049182018-03-28 10:02:20 -07003523bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3524{
3525 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3526}
3527
3528bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3529{
3530 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3531}
3532
Jamie Madill007530e2017-12-28 14:27:04 -05003533bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003534{
3535 if (!context->getExtensions().pathRendering)
3536 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003537 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003538 return false;
3539 }
Brandon Jones59770802018-04-02 13:18:42 -07003540 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003541 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003542 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003543 return false;
3544 }
3545
3546 switch (coverMode)
3547 {
3548 case GL_CONVEX_HULL_CHROMIUM:
3549 case GL_BOUNDING_BOX_CHROMIUM:
3550 break;
3551 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003552 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003553 return false;
3554 }
3555 return true;
3556}
3557
Jamie Madill007530e2017-12-28 14:27:04 -05003558bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3559 GLuint path,
3560 GLenum fillMode,
3561 GLuint mask,
3562 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003563{
Jamie Madill007530e2017-12-28 14:27:04 -05003564 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3565 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003566}
3567
Jamie Madill007530e2017-12-28 14:27:04 -05003568bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3569 GLuint path,
3570 GLint reference,
3571 GLuint mask,
3572 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003573{
Jamie Madill007530e2017-12-28 14:27:04 -05003574 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3575 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003576}
3577
Brandon Jonesd1049182018-03-28 10:02:20 -07003578bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003579{
3580 if (!context->getExtensions().pathRendering)
3581 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003582 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003583 return false;
3584 }
3585 return true;
3586}
3587
Jamie Madill007530e2017-12-28 14:27:04 -05003588bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3589 GLsizei numPaths,
3590 GLenum pathNameType,
3591 const void *paths,
3592 GLuint pathBase,
3593 GLenum coverMode,
3594 GLenum transformType,
3595 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003596{
3597 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3598 transformType, transformValues))
3599 return false;
3600
3601 switch (coverMode)
3602 {
3603 case GL_CONVEX_HULL_CHROMIUM:
3604 case GL_BOUNDING_BOX_CHROMIUM:
3605 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3606 break;
3607 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003609 return false;
3610 }
3611
3612 return true;
3613}
3614
Jamie Madill007530e2017-12-28 14:27:04 -05003615bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3616 GLsizei numPaths,
3617 GLenum pathNameType,
3618 const void *paths,
3619 GLuint pathBase,
3620 GLenum coverMode,
3621 GLenum transformType,
3622 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003623{
3624 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3625 transformType, transformValues))
3626 return false;
3627
3628 switch (coverMode)
3629 {
3630 case GL_CONVEX_HULL_CHROMIUM:
3631 case GL_BOUNDING_BOX_CHROMIUM:
3632 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3633 break;
3634 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003635 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003636 return false;
3637 }
3638
3639 return true;
3640}
3641
Jamie Madill007530e2017-12-28 14:27:04 -05003642bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3643 GLsizei numPaths,
3644 GLenum pathNameType,
3645 const void *paths,
3646 GLuint pathBase,
3647 GLenum fillMode,
3648 GLuint mask,
3649 GLenum transformType,
3650 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003651{
3652
3653 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3654 transformType, transformValues))
3655 return false;
3656
3657 switch (fillMode)
3658 {
3659 case GL_COUNT_UP_CHROMIUM:
3660 case GL_COUNT_DOWN_CHROMIUM:
3661 break;
3662 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003663 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003664 return false;
3665 }
3666 if (!isPow2(mask + 1))
3667 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003668 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003669 return false;
3670 }
3671 return true;
3672}
3673
Jamie Madill007530e2017-12-28 14:27:04 -05003674bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3675 GLsizei numPaths,
3676 GLenum pathNameType,
3677 const void *paths,
3678 GLuint pathBase,
3679 GLint reference,
3680 GLuint mask,
3681 GLenum transformType,
3682 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003683{
3684 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3685 transformType, transformValues))
3686 return false;
3687
3688 // no more validation here.
3689
3690 return true;
3691}
3692
Jamie Madill007530e2017-12-28 14:27:04 -05003693bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3694 GLsizei numPaths,
3695 GLenum pathNameType,
3696 const void *paths,
3697 GLuint pathBase,
3698 GLenum fillMode,
3699 GLuint mask,
3700 GLenum coverMode,
3701 GLenum transformType,
3702 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003703{
3704 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3705 transformType, transformValues))
3706 return false;
3707
3708 switch (coverMode)
3709 {
3710 case GL_CONVEX_HULL_CHROMIUM:
3711 case GL_BOUNDING_BOX_CHROMIUM:
3712 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3713 break;
3714 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003715 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003716 return false;
3717 }
3718
3719 switch (fillMode)
3720 {
3721 case GL_COUNT_UP_CHROMIUM:
3722 case GL_COUNT_DOWN_CHROMIUM:
3723 break;
3724 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003725 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003726 return false;
3727 }
3728 if (!isPow2(mask + 1))
3729 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003730 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003731 return false;
3732 }
3733
3734 return true;
3735}
3736
Jamie Madill007530e2017-12-28 14:27:04 -05003737bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3738 GLsizei numPaths,
3739 GLenum pathNameType,
3740 const void *paths,
3741 GLuint pathBase,
3742 GLint reference,
3743 GLuint mask,
3744 GLenum coverMode,
3745 GLenum transformType,
3746 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003747{
3748 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3749 transformType, transformValues))
3750 return false;
3751
3752 switch (coverMode)
3753 {
3754 case GL_CONVEX_HULL_CHROMIUM:
3755 case GL_BOUNDING_BOX_CHROMIUM:
3756 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3757 break;
3758 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003759 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003760 return false;
3761 }
3762
3763 return true;
3764}
3765
Jamie Madill007530e2017-12-28 14:27:04 -05003766bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3767 GLuint program,
3768 GLint location,
3769 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003770{
3771 if (!context->getExtensions().pathRendering)
3772 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003773 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003774 return false;
3775 }
3776
3777 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3778 if (location >= MaxLocation)
3779 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003780 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003781 return false;
3782 }
3783
3784 const auto *programObject = context->getProgram(program);
3785 if (!programObject)
3786 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003787 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003788 return false;
3789 }
3790
3791 if (!name)
3792 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003793 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003794 return false;
3795 }
3796
3797 if (angle::BeginsWith(name, "gl_"))
3798 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003799 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003800 return false;
3801 }
3802
3803 return true;
3804}
3805
Jamie Madill007530e2017-12-28 14:27:04 -05003806bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3807 GLuint program,
3808 GLint location,
3809 GLenum genMode,
3810 GLint components,
3811 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003812{
3813 if (!context->getExtensions().pathRendering)
3814 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003815 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003816 return false;
3817 }
3818
3819 const auto *programObject = context->getProgram(program);
3820 if (!programObject || programObject->isFlaggedForDeletion())
3821 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003822 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003823 return false;
3824 }
3825
3826 if (!programObject->isLinked())
3827 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003828 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003829 return false;
3830 }
3831
3832 switch (genMode)
3833 {
3834 case GL_NONE:
3835 if (components != 0)
3836 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003837 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003838 return false;
3839 }
3840 break;
3841
3842 case GL_OBJECT_LINEAR_CHROMIUM:
3843 case GL_EYE_LINEAR_CHROMIUM:
3844 case GL_CONSTANT_CHROMIUM:
3845 if (components < 1 || components > 4)
3846 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003847 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003848 return false;
3849 }
3850 if (!coeffs)
3851 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003852 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003853 return false;
3854 }
3855 break;
3856
3857 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003858 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003859 return false;
3860 }
3861
3862 // If the location is -1 then the command is silently ignored
3863 // and no further validation is needed.
3864 if (location == -1)
3865 return true;
3866
jchen103fd614d2018-08-13 12:21:58 +08003867 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003868
3869 if (!binding.valid)
3870 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003871 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003872 return false;
3873 }
3874
3875 if (binding.type != GL_NONE)
3876 {
3877 GLint expectedComponents = 0;
3878 switch (binding.type)
3879 {
3880 case GL_FLOAT:
3881 expectedComponents = 1;
3882 break;
3883 case GL_FLOAT_VEC2:
3884 expectedComponents = 2;
3885 break;
3886 case GL_FLOAT_VEC3:
3887 expectedComponents = 3;
3888 break;
3889 case GL_FLOAT_VEC4:
3890 expectedComponents = 4;
3891 break;
3892 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003893 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003894 InvalidOperation()
3895 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003896 return false;
3897 }
3898 if (expectedComponents != components && genMode != GL_NONE)
3899 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003900 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003901 return false;
3902 }
3903 }
3904 return true;
3905}
3906
Geoff Lang97073d12016-04-20 10:42:34 -07003907bool ValidateCopyTextureCHROMIUM(Context *context,
3908 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003909 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003910 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003911 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003912 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003913 GLint internalFormat,
3914 GLenum destType,
3915 GLboolean unpackFlipY,
3916 GLboolean unpackPremultiplyAlpha,
3917 GLboolean unpackUnmultiplyAlpha)
3918{
3919 if (!context->getExtensions().copyTexture)
3920 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003921 context->handleError(InvalidOperation()
3922 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003923 return false;
3924 }
3925
Geoff Lang4f0e0032017-05-01 16:04:35 -04003926 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003927 if (source == nullptr)
3928 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003929 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003930 return false;
3931 }
3932
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003933 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003934 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003935 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003936 return false;
3937 }
3938
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003939 TextureType sourceType = source->getType();
3940 ASSERT(sourceType != TextureType::CubeMap);
3941 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003942
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003943 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003944 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003945 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003946 return false;
3947 }
3948
Geoff Lang4f0e0032017-05-01 16:04:35 -04003949 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3950 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3951 if (sourceWidth == 0 || sourceHeight == 0)
3952 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003953 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003954 return false;
3955 }
3956
3957 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3958 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003959 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003960 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003961 return false;
3962 }
3963
Geoff Lang63458a32017-10-30 15:16:53 -04003964 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3965 {
3966 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3967 return false;
3968 }
3969
Geoff Lang4f0e0032017-05-01 16:04:35 -04003970 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003971 if (dest == nullptr)
3972 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003973 context->handleError(InvalidValue()
3974 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003975 return false;
3976 }
3977
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003978 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003979 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003980 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003981 return false;
3982 }
3983
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003984 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003985 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003986 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003987 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003988 return false;
3989 }
3990
Geoff Lang97073d12016-04-20 10:42:34 -07003991 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3992 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003993 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003994 return false;
3995 }
3996
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003997 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003998 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003999 context->handleError(
4000 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004001 return false;
4002 }
4003
Geoff Lang97073d12016-04-20 10:42:34 -07004004 if (dest->getImmutableFormat())
4005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004006 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07004007 return false;
4008 }
4009
4010 return true;
4011}
4012
4013bool ValidateCopySubTextureCHROMIUM(Context *context,
4014 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004015 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004016 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004017 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004018 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004019 GLint xoffset,
4020 GLint yoffset,
4021 GLint x,
4022 GLint y,
4023 GLsizei width,
4024 GLsizei height,
4025 GLboolean unpackFlipY,
4026 GLboolean unpackPremultiplyAlpha,
4027 GLboolean unpackUnmultiplyAlpha)
4028{
4029 if (!context->getExtensions().copyTexture)
4030 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004031 context->handleError(InvalidOperation()
4032 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004033 return false;
4034 }
4035
Geoff Lang4f0e0032017-05-01 16:04:35 -04004036 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004037 if (source == nullptr)
4038 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004039 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004040 return false;
4041 }
4042
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004043 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004044 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004045 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004046 return false;
4047 }
4048
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004049 TextureType sourceType = source->getType();
4050 ASSERT(sourceType != TextureType::CubeMap);
4051 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004052
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004053 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004054 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004055 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004056 return false;
4057 }
4058
4059 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4060 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004061 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004062 context->handleError(InvalidValue()
4063 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004064 return false;
4065 }
4066
4067 if (x < 0 || y < 0)
4068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004069 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004070 return false;
4071 }
4072
4073 if (width < 0 || height < 0)
4074 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004075 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004076 return false;
4077 }
4078
Geoff Lang4f0e0032017-05-01 16:04:35 -04004079 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4080 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004081 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004082 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004083 return false;
4084 }
4085
Geoff Lang4f0e0032017-05-01 16:04:35 -04004086 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4087 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004088 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004089 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004090 return false;
4091 }
4092
Geoff Lang63458a32017-10-30 15:16:53 -04004093 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4094 {
4095 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4096 return false;
4097 }
4098
Geoff Lang4f0e0032017-05-01 16:04:35 -04004099 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004100 if (dest == nullptr)
4101 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004102 context->handleError(InvalidValue()
4103 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004104 return false;
4105 }
4106
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004107 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004109 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004110 return false;
4111 }
4112
Brandon Jones28783792018-03-05 09:37:32 -08004113 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4114 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004115 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004116 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004117 return false;
4118 }
4119
Geoff Lang4f0e0032017-05-01 16:04:35 -04004120 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4121 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004122 context
4123 ->handleError(InvalidOperation()
4124 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004125 return false;
4126 }
4127
4128 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4129 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004131 context->handleError(InvalidOperation()
4132 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004133 return false;
4134 }
4135
4136 if (xoffset < 0 || yoffset < 0)
4137 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004138 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004139 return false;
4140 }
4141
Geoff Lang4f0e0032017-05-01 16:04:35 -04004142 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4143 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004144 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004145 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004146 return false;
4147 }
4148
4149 return true;
4150}
4151
Geoff Lang47110bf2016-04-20 11:13:22 -07004152bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4153{
4154 if (!context->getExtensions().copyCompressedTexture)
4155 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004156 context->handleError(InvalidOperation()
4157 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004158 return false;
4159 }
4160
4161 const gl::Texture *source = context->getTexture(sourceId);
4162 if (source == nullptr)
4163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004164 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004165 return false;
4166 }
4167
Corentin Wallez99d492c2018-02-27 15:17:10 -05004168 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004169 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004170 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004171 return false;
4172 }
4173
Corentin Wallez99d492c2018-02-27 15:17:10 -05004174 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4175 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004176 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004177 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004178 return false;
4179 }
4180
Corentin Wallez99d492c2018-02-27 15:17:10 -05004181 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004182 if (!sourceFormat.info->compressed)
4183 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004184 context->handleError(InvalidOperation()
4185 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004186 return false;
4187 }
4188
4189 const gl::Texture *dest = context->getTexture(destId);
4190 if (dest == nullptr)
4191 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004192 context->handleError(InvalidValue()
4193 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004194 return false;
4195 }
4196
Corentin Wallez99d492c2018-02-27 15:17:10 -05004197 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004199 context->handleError(InvalidValue()
4200 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004201 return false;
4202 }
4203
4204 if (dest->getImmutableFormat())
4205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004206 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004207 return false;
4208 }
4209
4210 return true;
4211}
4212
Jiawei Shao385b3e02018-03-21 09:43:28 +08004213bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004214{
4215 switch (type)
4216 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004217 case ShaderType::Vertex:
4218 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004219 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004220
Jiawei Shao385b3e02018-03-21 09:43:28 +08004221 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004222 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004223 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004224 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004225 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004226 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004227 break;
4228
Jiawei Shao385b3e02018-03-21 09:43:28 +08004229 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004230 if (!context->getExtensions().geometryShader)
4231 {
4232 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4233 return false;
4234 }
4235 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004236 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004237 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004238 return false;
4239 }
Jamie Madill29639852016-09-02 15:00:09 -04004240
4241 return true;
4242}
4243
Jamie Madill5b772312018-03-08 20:28:32 -05004244bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004245 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004246 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004247 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004248 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004249{
4250 if (size < 0)
4251 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004252 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004253 return false;
4254 }
4255
4256 switch (usage)
4257 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004258 case BufferUsage::StreamDraw:
4259 case BufferUsage::StaticDraw:
4260 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004261 break;
4262
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004263 case BufferUsage::StreamRead:
4264 case BufferUsage::StaticRead:
4265 case BufferUsage::DynamicRead:
4266 case BufferUsage::StreamCopy:
4267 case BufferUsage::StaticCopy:
4268 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004269 if (context->getClientMajorVersion() < 3)
4270 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004271 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004272 return false;
4273 }
4274 break;
4275
4276 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004277 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004278 return false;
4279 }
4280
Corentin Walleze4477002017-12-01 14:39:58 -05004281 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004282 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004283 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004284 return false;
4285 }
4286
4287 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4288
4289 if (!buffer)
4290 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004291 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004292 return false;
4293 }
4294
James Darpiniane8a93c62018-01-04 18:02:24 -08004295 if (context->getExtensions().webglCompatibility &&
4296 buffer->isBoundForTransformFeedbackAndOtherUse())
4297 {
4298 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4299 return false;
4300 }
4301
Jamie Madill29639852016-09-02 15:00:09 -04004302 return true;
4303}
4304
Jamie Madill5b772312018-03-08 20:28:32 -05004305bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004306 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004307 GLintptr offset,
4308 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004309 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004310{
Brandon Jones6cad5662017-06-14 13:25:13 -07004311 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004312 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004313 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4314 return false;
4315 }
4316
4317 if (offset < 0)
4318 {
4319 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004320 return false;
4321 }
4322
Corentin Walleze4477002017-12-01 14:39:58 -05004323 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004324 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004325 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004326 return false;
4327 }
4328
4329 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4330
4331 if (!buffer)
4332 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004333 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004334 return false;
4335 }
4336
4337 if (buffer->isMapped())
4338 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004339 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004340 return false;
4341 }
4342
James Darpiniane8a93c62018-01-04 18:02:24 -08004343 if (context->getExtensions().webglCompatibility &&
4344 buffer->isBoundForTransformFeedbackAndOtherUse())
4345 {
4346 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4347 return false;
4348 }
4349
Jamie Madill29639852016-09-02 15:00:09 -04004350 // Check for possible overflow of size + offset
4351 angle::CheckedNumeric<size_t> checkedSize(size);
4352 checkedSize += offset;
4353 if (!checkedSize.IsValid())
4354 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004355 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004356 return false;
4357 }
4358
4359 if (size + offset > buffer->getSize())
4360 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004361 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004362 return false;
4363 }
4364
Martin Radev4c4c8e72016-08-04 12:25:34 +03004365 return true;
4366}
4367
Geoff Lang111a99e2017-10-17 10:58:41 -04004368bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004369{
Geoff Langc339c4e2016-11-29 10:37:36 -05004370 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004371 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004372 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004373 return false;
4374 }
4375
Geoff Lang111a99e2017-10-17 10:58:41 -04004376 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004377 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004378 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004379 return false;
4380 }
4381
4382 return true;
4383}
4384
Jamie Madill5b772312018-03-08 20:28:32 -05004385bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004386{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004387 if (context->getClientMajorVersion() < 2)
4388 {
4389 return ValidateMultitextureUnit(context, texture);
4390 }
4391
Jamie Madillef300b12016-10-07 15:12:09 -04004392 if (texture < GL_TEXTURE0 ||
4393 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4394 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004395 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004396 return false;
4397 }
4398
4399 return true;
4400}
4401
Jamie Madill5b772312018-03-08 20:28:32 -05004402bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004403{
4404 Program *programObject = GetValidProgram(context, program);
4405 if (!programObject)
4406 {
4407 return false;
4408 }
4409
4410 Shader *shaderObject = GetValidShader(context, shader);
4411 if (!shaderObject)
4412 {
4413 return false;
4414 }
4415
Jiawei Shao385b3e02018-03-21 09:43:28 +08004416 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004417 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004418 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4419 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004420 }
4421
4422 return true;
4423}
4424
Jamie Madill5b772312018-03-08 20:28:32 -05004425bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004426{
4427 if (index >= MAX_VERTEX_ATTRIBS)
4428 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004429 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004430 return false;
4431 }
4432
4433 if (strncmp(name, "gl_", 3) == 0)
4434 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004435 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004436 return false;
4437 }
4438
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004439 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004440 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004441 const size_t length = strlen(name);
4442
4443 if (!IsValidESSLString(name, length))
4444 {
4445 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4446 // for shader-related entry points
4447 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4448 return false;
4449 }
4450
4451 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4452 {
4453 return false;
4454 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004455 }
4456
Jamie Madill01a80ee2016-11-07 12:06:18 -05004457 return GetValidProgram(context, program) != nullptr;
4458}
4459
Jamie Madill5b772312018-03-08 20:28:32 -05004460bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004461{
Corentin Walleze4477002017-12-01 14:39:58 -05004462 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004463 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004464 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004465 return false;
4466 }
4467
4468 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4469 !context->isBufferGenerated(buffer))
4470 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004471 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004472 return false;
4473 }
4474
4475 return true;
4476}
4477
Jamie Madill5b772312018-03-08 20:28:32 -05004478bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004479{
Geoff Lange8afa902017-09-27 15:00:43 -04004480 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004481 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004482 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004483 return false;
4484 }
4485
4486 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4487 !context->isFramebufferGenerated(framebuffer))
4488 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004489 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004490 return false;
4491 }
4492
4493 return true;
4494}
4495
Jamie Madill5b772312018-03-08 20:28:32 -05004496bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004497{
4498 if (target != GL_RENDERBUFFER)
4499 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004500 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004501 return false;
4502 }
4503
4504 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4505 !context->isRenderbufferGenerated(renderbuffer))
4506 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004508 return false;
4509 }
4510
4511 return true;
4512}
4513
Jamie Madill5b772312018-03-08 20:28:32 -05004514static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004515{
4516 switch (mode)
4517 {
4518 case GL_FUNC_ADD:
4519 case GL_FUNC_SUBTRACT:
4520 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004521 return true;
4522
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004523 case GL_MIN:
4524 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004525 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004526
4527 default:
4528 return false;
4529 }
4530}
4531
Jamie Madill5b772312018-03-08 20:28:32 -05004532bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004533{
4534 return true;
4535}
4536
Jamie Madill5b772312018-03-08 20:28:32 -05004537bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004538{
Geoff Lang50cac572017-09-26 17:37:43 -04004539 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004540 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004541 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004542 return false;
4543 }
4544
4545 return true;
4546}
4547
Jamie Madill5b772312018-03-08 20:28:32 -05004548bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004549{
Geoff Lang50cac572017-09-26 17:37:43 -04004550 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004552 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004553 return false;
4554 }
4555
Geoff Lang50cac572017-09-26 17:37:43 -04004556 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004557 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004558 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004559 return false;
4560 }
4561
4562 return true;
4563}
4564
Jamie Madill5b772312018-03-08 20:28:32 -05004565bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004566{
4567 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4568}
4569
4570static bool ValidSrcBlendFunc(GLenum srcBlend)
4571{
4572 switch (srcBlend)
4573 {
4574 case GL_ZERO:
4575 case GL_ONE:
4576 case GL_SRC_COLOR:
4577 case GL_ONE_MINUS_SRC_COLOR:
4578 case GL_DST_COLOR:
4579 case GL_ONE_MINUS_DST_COLOR:
4580 case GL_SRC_ALPHA:
4581 case GL_ONE_MINUS_SRC_ALPHA:
4582 case GL_DST_ALPHA:
4583 case GL_ONE_MINUS_DST_ALPHA:
4584 case GL_CONSTANT_COLOR:
4585 case GL_ONE_MINUS_CONSTANT_COLOR:
4586 case GL_CONSTANT_ALPHA:
4587 case GL_ONE_MINUS_CONSTANT_ALPHA:
4588 case GL_SRC_ALPHA_SATURATE:
4589 return true;
4590
4591 default:
4592 return false;
4593 }
4594}
4595
4596static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4597{
4598 switch (dstBlend)
4599 {
4600 case GL_ZERO:
4601 case GL_ONE:
4602 case GL_SRC_COLOR:
4603 case GL_ONE_MINUS_SRC_COLOR:
4604 case GL_DST_COLOR:
4605 case GL_ONE_MINUS_DST_COLOR:
4606 case GL_SRC_ALPHA:
4607 case GL_ONE_MINUS_SRC_ALPHA:
4608 case GL_DST_ALPHA:
4609 case GL_ONE_MINUS_DST_ALPHA:
4610 case GL_CONSTANT_COLOR:
4611 case GL_ONE_MINUS_CONSTANT_COLOR:
4612 case GL_CONSTANT_ALPHA:
4613 case GL_ONE_MINUS_CONSTANT_ALPHA:
4614 return true;
4615
4616 case GL_SRC_ALPHA_SATURATE:
4617 return (contextMajorVersion >= 3);
4618
4619 default:
4620 return false;
4621 }
4622}
4623
Jamie Madill5b772312018-03-08 20:28:32 -05004624bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004625 GLenum srcRGB,
4626 GLenum dstRGB,
4627 GLenum srcAlpha,
4628 GLenum dstAlpha)
4629{
4630 if (!ValidSrcBlendFunc(srcRGB))
4631 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004632 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004633 return false;
4634 }
4635
4636 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4637 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004638 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004639 return false;
4640 }
4641
4642 if (!ValidSrcBlendFunc(srcAlpha))
4643 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004644 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004645 return false;
4646 }
4647
4648 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4649 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004650 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004651 return false;
4652 }
4653
Frank Henigman146e8a12017-03-02 23:22:37 -05004654 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4655 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004656 {
4657 bool constantColorUsed =
4658 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4659 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4660
4661 bool constantAlphaUsed =
4662 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4663 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4664
4665 if (constantColorUsed && constantAlphaUsed)
4666 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004667 const char *msg;
4668 if (context->getExtensions().webglCompatibility)
4669 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004670 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004671 }
4672 else
4673 {
4674 msg =
4675 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4676 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4677 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004678 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004679 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004680 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004681 return false;
4682 }
4683 }
4684
4685 return true;
4686}
4687
Geoff Langc339c4e2016-11-29 10:37:36 -05004688bool ValidateGetString(Context *context, GLenum name)
4689{
4690 switch (name)
4691 {
4692 case GL_VENDOR:
4693 case GL_RENDERER:
4694 case GL_VERSION:
4695 case GL_SHADING_LANGUAGE_VERSION:
4696 case GL_EXTENSIONS:
4697 break;
4698
4699 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4700 if (!context->getExtensions().requestExtension)
4701 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004702 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004703 return false;
4704 }
4705 break;
4706
4707 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004708 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004709 return false;
4710 }
4711
4712 return true;
4713}
4714
Jamie Madill5b772312018-03-08 20:28:32 -05004715bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004716{
4717 if (width <= 0.0f || isNaN(width))
4718 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004719 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004720 return false;
4721 }
4722
4723 return true;
4724}
4725
Jamie Madill5b772312018-03-08 20:28:32 -05004726bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004727 GLuint index,
4728 GLint size,
4729 GLenum type,
4730 GLboolean normalized,
4731 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004732 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004733{
Shao80957d92017-02-20 21:25:59 +08004734 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004735 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004736 return false;
4737 }
4738
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004739 if (stride < 0)
4740 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004741 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004742 return false;
4743 }
4744
Shao80957d92017-02-20 21:25:59 +08004745 const Caps &caps = context->getCaps();
4746 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004747 {
Shao80957d92017-02-20 21:25:59 +08004748 if (stride > caps.maxVertexAttribStride)
4749 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004750 context->handleError(InvalidValue()
4751 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004752 return false;
4753 }
4754
4755 if (index >= caps.maxVertexAttribBindings)
4756 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004757 context->handleError(InvalidValue()
4758 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004759 return false;
4760 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004761 }
4762
4763 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4764 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4765 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4766 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004767 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4768 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004769 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4770 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004771 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004772 context
4773 ->handleError(InvalidOperation()
4774 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004775 return false;
4776 }
4777
4778 if (context->getExtensions().webglCompatibility)
4779 {
4780 // WebGL 1.0 [Section 6.14] Fixed point support
4781 // The WebGL API does not support the GL_FIXED data type.
4782 if (type == GL_FIXED)
4783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004784 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004785 return false;
4786 }
4787
Geoff Lang2d62ab72017-03-23 16:54:40 -04004788 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004789 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004790 return false;
4791 }
4792 }
4793
4794 return true;
4795}
4796
Jamie Madill5b772312018-03-08 20:28:32 -05004797bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004798{
4799 if (context->getExtensions().webglCompatibility && zNear > zFar)
4800 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004801 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004802 return false;
4803 }
4804
4805 return true;
4806}
4807
Jamie Madill5b772312018-03-08 20:28:32 -05004808bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004809 GLenum target,
4810 GLenum internalformat,
4811 GLsizei width,
4812 GLsizei height)
4813{
4814 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4815 height);
4816}
4817
Jamie Madill5b772312018-03-08 20:28:32 -05004818bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004819 GLenum target,
4820 GLsizei samples,
4821 GLenum internalformat,
4822 GLsizei width,
4823 GLsizei height)
4824{
4825 if (!context->getExtensions().framebufferMultisample)
4826 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004827 context->handleError(InvalidOperation()
4828 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004829 return false;
4830 }
4831
4832 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4833 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4834 // generated.
4835 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4836 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004837 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004838 return false;
4839 }
4840
4841 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4842 // the specified storage. This is different than ES 3.0 in which a sample number higher
4843 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4844 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4845 if (context->getClientMajorVersion() >= 3)
4846 {
4847 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4848 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4849 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004850 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004851 return false;
4852 }
4853 }
4854
4855 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4856 width, height);
4857}
4858
Jamie Madill5b772312018-03-08 20:28:32 -05004859bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004860{
Geoff Lange8afa902017-09-27 15:00:43 -04004861 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004862 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004863 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004864 return false;
4865 }
4866
4867 return true;
4868}
4869
Jamie Madill5b772312018-03-08 20:28:32 -05004870bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004871{
4872 return true;
4873}
4874
Jamie Madill5b772312018-03-08 20:28:32 -05004875bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004876{
4877 return true;
4878}
4879
Jamie Madill5b772312018-03-08 20:28:32 -05004880bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004881{
4882 return true;
4883}
4884
Jamie Madill5b772312018-03-08 20:28:32 -05004885bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004886 GLboolean red,
4887 GLboolean green,
4888 GLboolean blue,
4889 GLboolean alpha)
4890{
4891 return true;
4892}
4893
Jamie Madill5b772312018-03-08 20:28:32 -05004894bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004895{
4896 return true;
4897}
4898
Jamie Madill5b772312018-03-08 20:28:32 -05004899bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004900{
4901 return true;
4902}
4903
Jamie Madill5b772312018-03-08 20:28:32 -05004904bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004905{
4906 switch (mode)
4907 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004908 case CullFaceMode::Front:
4909 case CullFaceMode::Back:
4910 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004911 break;
4912
4913 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004914 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004915 return false;
4916 }
4917
4918 return true;
4919}
4920
Jamie Madill5b772312018-03-08 20:28:32 -05004921bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004922{
4923 if (program == 0)
4924 {
4925 return false;
4926 }
4927
4928 if (!context->getProgram(program))
4929 {
4930 if (context->getShader(program))
4931 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004932 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004933 return false;
4934 }
4935 else
4936 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004937 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004938 return false;
4939 }
4940 }
4941
4942 return true;
4943}
4944
Jamie Madill5b772312018-03-08 20:28:32 -05004945bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004946{
4947 if (shader == 0)
4948 {
4949 return false;
4950 }
4951
4952 if (!context->getShader(shader))
4953 {
4954 if (context->getProgram(shader))
4955 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004956 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004957 return false;
4958 }
4959 else
4960 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004961 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004962 return false;
4963 }
4964 }
4965
4966 return true;
4967}
4968
Jamie Madill5b772312018-03-08 20:28:32 -05004969bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004970{
4971 switch (func)
4972 {
4973 case GL_NEVER:
4974 case GL_ALWAYS:
4975 case GL_LESS:
4976 case GL_LEQUAL:
4977 case GL_EQUAL:
4978 case GL_GREATER:
4979 case GL_GEQUAL:
4980 case GL_NOTEQUAL:
4981 break;
4982
4983 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004984 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004985 return false;
4986 }
4987
4988 return true;
4989}
4990
Jamie Madill5b772312018-03-08 20:28:32 -05004991bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004992{
4993 return true;
4994}
4995
Jamie Madill5b772312018-03-08 20:28:32 -05004996bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004997{
4998 Program *programObject = GetValidProgram(context, program);
4999 if (!programObject)
5000 {
5001 return false;
5002 }
5003
5004 Shader *shaderObject = GetValidShader(context, shader);
5005 if (!shaderObject)
5006 {
5007 return false;
5008 }
5009
Jiawei Shao385b3e02018-03-21 09:43:28 +08005010 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005011 if (attachedShader != shaderObject)
5012 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005013 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005014 return false;
5015 }
5016
5017 return true;
5018}
5019
Jamie Madill5b772312018-03-08 20:28:32 -05005020bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005021{
5022 if (index >= MAX_VERTEX_ATTRIBS)
5023 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005024 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005025 return false;
5026 }
5027
5028 return true;
5029}
5030
Jamie Madill5b772312018-03-08 20:28:32 -05005031bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005032{
5033 if (index >= MAX_VERTEX_ATTRIBS)
5034 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005035 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005036 return false;
5037 }
5038
5039 return true;
5040}
5041
Jamie Madill5b772312018-03-08 20:28:32 -05005042bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005043{
5044 return true;
5045}
5046
Jamie Madill5b772312018-03-08 20:28:32 -05005047bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005048{
5049 return true;
5050}
5051
Jamie Madill5b772312018-03-08 20:28:32 -05005052bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005053{
5054 switch (mode)
5055 {
5056 case GL_CW:
5057 case GL_CCW:
5058 break;
5059 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005060 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005061 return false;
5062 }
5063
5064 return true;
5065}
5066
Jamie Madill5b772312018-03-08 20:28:32 -05005067bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005068 GLuint program,
5069 GLuint index,
5070 GLsizei bufsize,
5071 GLsizei *length,
5072 GLint *size,
5073 GLenum *type,
5074 GLchar *name)
5075{
5076 if (bufsize < 0)
5077 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005078 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005079 return false;
5080 }
5081
5082 Program *programObject = GetValidProgram(context, program);
5083
5084 if (!programObject)
5085 {
5086 return false;
5087 }
5088
5089 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5090 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005091 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005092 return false;
5093 }
5094
5095 return true;
5096}
5097
Jamie Madill5b772312018-03-08 20:28:32 -05005098bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005099 GLuint program,
5100 GLuint index,
5101 GLsizei bufsize,
5102 GLsizei *length,
5103 GLint *size,
5104 GLenum *type,
5105 GLchar *name)
5106{
5107 if (bufsize < 0)
5108 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005109 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110 return false;
5111 }
5112
5113 Program *programObject = GetValidProgram(context, program);
5114
5115 if (!programObject)
5116 {
5117 return false;
5118 }
5119
5120 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5121 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005122 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005123 return false;
5124 }
5125
5126 return true;
5127}
5128
Jamie Madill5b772312018-03-08 20:28:32 -05005129bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005130 GLuint program,
5131 GLsizei maxcount,
5132 GLsizei *count,
5133 GLuint *shaders)
5134{
5135 if (maxcount < 0)
5136 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005137 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005138 return false;
5139 }
5140
5141 Program *programObject = GetValidProgram(context, program);
5142
5143 if (!programObject)
5144 {
5145 return false;
5146 }
5147
5148 return true;
5149}
5150
Jamie Madill5b772312018-03-08 20:28:32 -05005151bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005152{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005153 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5154 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005155 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005157 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005158 return false;
5159 }
5160
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161 Program *programObject = GetValidProgram(context, program);
5162
5163 if (!programObject)
5164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005166 return false;
5167 }
5168
5169 if (!programObject->isLinked())
5170 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005171 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005172 return false;
5173 }
5174
5175 return true;
5176}
5177
Jamie Madill5b772312018-03-08 20:28:32 -05005178bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005179{
5180 GLenum nativeType;
5181 unsigned int numParams = 0;
5182 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5183}
5184
Jamie Madill5b772312018-03-08 20:28:32 -05005185bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005186{
5187 return true;
5188}
5189
Jamie Madill5b772312018-03-08 20:28:32 -05005190bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005191{
5192 GLenum nativeType;
5193 unsigned int numParams = 0;
5194 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5195}
5196
Jamie Madill5b772312018-03-08 20:28:32 -05005197bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *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 ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005205 GLuint program,
5206 GLsizei bufsize,
5207 GLsizei *length,
5208 GLchar *infolog)
5209{
5210 if (bufsize < 0)
5211 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005212 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 return false;
5214 }
5215
5216 Program *programObject = GetValidProgram(context, program);
5217 if (!programObject)
5218 {
5219 return false;
5220 }
5221
5222 return true;
5223}
5224
Jamie Madill5b772312018-03-08 20:28:32 -05005225bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005226 GLuint shader,
5227 GLsizei bufsize,
5228 GLsizei *length,
5229 GLchar *infolog)
5230{
5231 if (bufsize < 0)
5232 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005233 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005234 return false;
5235 }
5236
5237 Shader *shaderObject = GetValidShader(context, shader);
5238 if (!shaderObject)
5239 {
5240 return false;
5241 }
5242
5243 return true;
5244}
5245
Jamie Madill5b772312018-03-08 20:28:32 -05005246bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005247 GLenum shadertype,
5248 GLenum precisiontype,
5249 GLint *range,
5250 GLint *precision)
5251{
5252 switch (shadertype)
5253 {
5254 case GL_VERTEX_SHADER:
5255 case GL_FRAGMENT_SHADER:
5256 break;
5257 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005258 context->handleError(InvalidOperation()
5259 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005260 return false;
5261 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005262 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005263 return false;
5264 }
5265
5266 switch (precisiontype)
5267 {
5268 case GL_LOW_FLOAT:
5269 case GL_MEDIUM_FLOAT:
5270 case GL_HIGH_FLOAT:
5271 case GL_LOW_INT:
5272 case GL_MEDIUM_INT:
5273 case GL_HIGH_INT:
5274 break;
5275
5276 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005277 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005278 return false;
5279 }
5280
5281 return true;
5282}
5283
Jamie Madill5b772312018-03-08 20:28:32 -05005284bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005285 GLuint shader,
5286 GLsizei bufsize,
5287 GLsizei *length,
5288 GLchar *source)
5289{
5290 if (bufsize < 0)
5291 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005292 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293 return false;
5294 }
5295
5296 Shader *shaderObject = GetValidShader(context, shader);
5297 if (!shaderObject)
5298 {
5299 return false;
5300 }
5301
5302 return true;
5303}
5304
Jamie Madill5b772312018-03-08 20:28:32 -05005305bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005306{
5307 if (strstr(name, "gl_") == name)
5308 {
5309 return false;
5310 }
5311
Geoff Langfc32e8b2017-05-31 14:16:59 -04005312 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5313 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005314 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005316 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005317 return false;
5318 }
5319
Jamie Madillc1d770e2017-04-13 17:31:24 -04005320 Program *programObject = GetValidProgram(context, program);
5321
5322 if (!programObject)
5323 {
5324 return false;
5325 }
5326
5327 if (!programObject->isLinked())
5328 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005329 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005330 return false;
5331 }
5332
5333 return true;
5334}
5335
Jamie Madill5b772312018-03-08 20:28:32 -05005336bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005337{
5338 switch (mode)
5339 {
5340 case GL_FASTEST:
5341 case GL_NICEST:
5342 case GL_DONT_CARE:
5343 break;
5344
5345 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005346 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347 return false;
5348 }
5349
5350 switch (target)
5351 {
5352 case GL_GENERATE_MIPMAP_HINT:
5353 break;
5354
Geoff Lange7bd2182017-06-16 16:13:13 -04005355 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5356 if (context->getClientVersion() < ES_3_0 &&
5357 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005358 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005359 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005360 return false;
5361 }
5362 break;
5363
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005364 case GL_PERSPECTIVE_CORRECTION_HINT:
5365 case GL_POINT_SMOOTH_HINT:
5366 case GL_LINE_SMOOTH_HINT:
5367 case GL_FOG_HINT:
5368 if (context->getClientMajorVersion() >= 2)
5369 {
5370 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5371 return false;
5372 }
5373 break;
5374
Jamie Madillc1d770e2017-04-13 17:31:24 -04005375 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005376 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005377 return false;
5378 }
5379
5380 return true;
5381}
5382
Jamie Madill5b772312018-03-08 20:28:32 -05005383bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005384{
5385 return true;
5386}
5387
Jamie Madill5b772312018-03-08 20:28:32 -05005388bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005389{
5390 return true;
5391}
5392
Jamie Madill5b772312018-03-08 20:28:32 -05005393bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005394{
5395 return true;
5396}
5397
Jamie Madill5b772312018-03-08 20:28:32 -05005398bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005399{
5400 return true;
5401}
5402
Jamie Madill5b772312018-03-08 20:28:32 -05005403bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005404{
5405 return true;
5406}
5407
Jamie Madill5b772312018-03-08 20:28:32 -05005408bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005409{
5410 return true;
5411}
5412
Jamie Madill5b772312018-03-08 20:28:32 -05005413bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005414{
5415 if (context->getClientMajorVersion() < 3)
5416 {
5417 switch (pname)
5418 {
5419 case GL_UNPACK_IMAGE_HEIGHT:
5420 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005421 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005422 return false;
5423
5424 case GL_UNPACK_ROW_LENGTH:
5425 case GL_UNPACK_SKIP_ROWS:
5426 case GL_UNPACK_SKIP_PIXELS:
5427 if (!context->getExtensions().unpackSubimage)
5428 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005429 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005430 return false;
5431 }
5432 break;
5433
5434 case GL_PACK_ROW_LENGTH:
5435 case GL_PACK_SKIP_ROWS:
5436 case GL_PACK_SKIP_PIXELS:
5437 if (!context->getExtensions().packSubimage)
5438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005439 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005440 return false;
5441 }
5442 break;
5443 }
5444 }
5445
5446 if (param < 0)
5447 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005448 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005449 return false;
5450 }
5451
5452 switch (pname)
5453 {
5454 case GL_UNPACK_ALIGNMENT:
5455 if (param != 1 && param != 2 && param != 4 && param != 8)
5456 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005457 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005458 return false;
5459 }
5460 break;
5461
5462 case GL_PACK_ALIGNMENT:
5463 if (param != 1 && param != 2 && param != 4 && param != 8)
5464 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005465 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005466 return false;
5467 }
5468 break;
5469
5470 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005471 if (!context->getExtensions().packReverseRowOrder)
5472 {
5473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5474 }
5475 break;
5476
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477 case GL_UNPACK_ROW_LENGTH:
5478 case GL_UNPACK_IMAGE_HEIGHT:
5479 case GL_UNPACK_SKIP_IMAGES:
5480 case GL_UNPACK_SKIP_ROWS:
5481 case GL_UNPACK_SKIP_PIXELS:
5482 case GL_PACK_ROW_LENGTH:
5483 case GL_PACK_SKIP_ROWS:
5484 case GL_PACK_SKIP_PIXELS:
5485 break;
5486
5487 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005488 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005489 return false;
5490 }
5491
5492 return true;
5493}
5494
Jamie Madill5b772312018-03-08 20:28:32 -05005495bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005496{
5497 return true;
5498}
5499
Jamie Madill5b772312018-03-08 20:28:32 -05005500bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005501{
5502 return true;
5503}
5504
Jamie Madill5b772312018-03-08 20:28:32 -05005505bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005506{
5507 return true;
5508}
5509
Jamie Madill5b772312018-03-08 20:28:32 -05005510bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005511{
5512 if (width < 0 || height < 0)
5513 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005514 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005515 return false;
5516 }
5517
5518 return true;
5519}
5520
Jamie Madill5b772312018-03-08 20:28:32 -05005521bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005522 GLsizei n,
5523 const GLuint *shaders,
5524 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005525 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005526 GLsizei length)
5527{
5528 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5529 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5530 shaderBinaryFormats.end())
5531 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005532 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005533 return false;
5534 }
5535
5536 return true;
5537}
5538
Jamie Madill5b772312018-03-08 20:28:32 -05005539bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005540 GLuint shader,
5541 GLsizei count,
5542 const GLchar *const *string,
5543 const GLint *length)
5544{
5545 if (count < 0)
5546 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005547 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005548 return false;
5549 }
5550
Geoff Langfc32e8b2017-05-31 14:16:59 -04005551 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5552 // shader-related entry points
5553 if (context->getExtensions().webglCompatibility)
5554 {
5555 for (GLsizei i = 0; i < count; i++)
5556 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005557 size_t len =
5558 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005559
5560 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005561 if (!IsValidESSLShaderSourceString(string[i], len,
5562 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005563 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005564 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005565 return false;
5566 }
5567 }
5568 }
5569
Jamie Madillc1d770e2017-04-13 17:31:24 -04005570 Shader *shaderObject = GetValidShader(context, shader);
5571 if (!shaderObject)
5572 {
5573 return false;
5574 }
5575
5576 return true;
5577}
5578
Jamie Madill5b772312018-03-08 20:28:32 -05005579bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580{
5581 if (!IsValidStencilFunc(func))
5582 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005583 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005584 return false;
5585 }
5586
5587 return true;
5588}
5589
Jamie Madill5b772312018-03-08 20:28:32 -05005590bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005591{
5592 if (!IsValidStencilFace(face))
5593 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005594 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005595 return false;
5596 }
5597
5598 if (!IsValidStencilFunc(func))
5599 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005600 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005601 return false;
5602 }
5603
5604 return true;
5605}
5606
Jamie Madill5b772312018-03-08 20:28:32 -05005607bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005608{
5609 return true;
5610}
5611
Jamie Madill5b772312018-03-08 20:28:32 -05005612bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005613{
5614 if (!IsValidStencilFace(face))
5615 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005616 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005617 return false;
5618 }
5619
5620 return true;
5621}
5622
Jamie Madill5b772312018-03-08 20:28:32 -05005623bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005624{
5625 if (!IsValidStencilOp(fail))
5626 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005627 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005628 return false;
5629 }
5630
5631 if (!IsValidStencilOp(zfail))
5632 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005633 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005634 return false;
5635 }
5636
5637 if (!IsValidStencilOp(zpass))
5638 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005639 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005640 return false;
5641 }
5642
5643 return true;
5644}
5645
Jamie Madill5b772312018-03-08 20:28:32 -05005646bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005647 GLenum face,
5648 GLenum fail,
5649 GLenum zfail,
5650 GLenum zpass)
5651{
5652 if (!IsValidStencilFace(face))
5653 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005654 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655 return false;
5656 }
5657
5658 return ValidateStencilOp(context, fail, zfail, zpass);
5659}
5660
Jamie Madill5b772312018-03-08 20:28:32 -05005661bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005662{
5663 return ValidateUniform(context, GL_FLOAT, location, 1);
5664}
5665
Jamie Madill5b772312018-03-08 20:28:32 -05005666bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005667{
5668 return ValidateUniform(context, GL_FLOAT, location, count);
5669}
5670
Jamie Madill5b772312018-03-08 20:28:32 -05005671bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005672{
5673 return ValidateUniform1iv(context, location, 1, &x);
5674}
5675
Jamie Madill5b772312018-03-08 20:28:32 -05005676bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005677{
5678 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5679}
5680
Jamie Madill5b772312018-03-08 20:28:32 -05005681bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005682{
5683 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5684}
5685
Jamie Madill5b772312018-03-08 20:28:32 -05005686bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005687{
5688 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5689}
5690
Jamie Madill5b772312018-03-08 20:28:32 -05005691bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005692{
5693 return ValidateUniform(context, GL_INT_VEC2, location, count);
5694}
5695
Jamie Madill5b772312018-03-08 20:28:32 -05005696bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005697{
5698 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5699}
5700
Jamie Madill5b772312018-03-08 20:28:32 -05005701bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005702{
5703 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5704}
5705
Jamie Madill5b772312018-03-08 20:28:32 -05005706bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005707{
5708 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5709}
5710
Jamie Madill5b772312018-03-08 20:28:32 -05005711bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005712{
5713 return ValidateUniform(context, GL_INT_VEC3, location, count);
5714}
5715
Jamie Madill5b772312018-03-08 20:28:32 -05005716bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005717{
5718 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5719}
5720
Jamie Madill5b772312018-03-08 20:28:32 -05005721bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005722{
5723 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5724}
5725
Jamie Madill5b772312018-03-08 20:28:32 -05005726bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005727{
5728 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5729}
5730
Jamie Madill5b772312018-03-08 20:28:32 -05005731bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005732{
5733 return ValidateUniform(context, GL_INT_VEC4, location, count);
5734}
5735
Jamie Madill5b772312018-03-08 20:28:32 -05005736bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005737 GLint location,
5738 GLsizei count,
5739 GLboolean transpose,
5740 const GLfloat *value)
5741{
5742 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5743}
5744
Jamie Madill5b772312018-03-08 20:28:32 -05005745bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005746 GLint location,
5747 GLsizei count,
5748 GLboolean transpose,
5749 const GLfloat *value)
5750{
5751 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5752}
5753
Jamie Madill5b772312018-03-08 20:28:32 -05005754bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005755 GLint location,
5756 GLsizei count,
5757 GLboolean transpose,
5758 const GLfloat *value)
5759{
5760 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5761}
5762
Jamie Madill5b772312018-03-08 20:28:32 -05005763bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005764{
5765 Program *programObject = GetValidProgram(context, program);
5766
5767 if (!programObject)
5768 {
5769 return false;
5770 }
5771
5772 return true;
5773}
5774
Jamie Madill5b772312018-03-08 20:28:32 -05005775bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005776{
5777 return ValidateVertexAttribIndex(context, index);
5778}
5779
Jamie Madill5b772312018-03-08 20:28:32 -05005780bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005781{
5782 return ValidateVertexAttribIndex(context, index);
5783}
5784
Jamie Madill5b772312018-03-08 20:28:32 -05005785bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005786{
5787 return ValidateVertexAttribIndex(context, index);
5788}
5789
Jamie Madill5b772312018-03-08 20:28:32 -05005790bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005791{
5792 return ValidateVertexAttribIndex(context, index);
5793}
5794
Jamie Madill5b772312018-03-08 20:28:32 -05005795bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005796{
5797 return ValidateVertexAttribIndex(context, index);
5798}
5799
Jamie Madill5b772312018-03-08 20:28:32 -05005800bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005801{
5802 return ValidateVertexAttribIndex(context, index);
5803}
5804
Jamie Madill5b772312018-03-08 20:28:32 -05005805bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005806 GLuint index,
5807 GLfloat x,
5808 GLfloat y,
5809 GLfloat z,
5810 GLfloat w)
5811{
5812 return ValidateVertexAttribIndex(context, index);
5813}
5814
Jamie Madill5b772312018-03-08 20:28:32 -05005815bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005816{
5817 return ValidateVertexAttribIndex(context, index);
5818}
5819
Jamie Madill5b772312018-03-08 20:28:32 -05005820bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005821{
5822 if (width < 0 || height < 0)
5823 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005824 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005825 return false;
5826 }
5827
5828 return true;
5829}
5830
Jamie Madill5b772312018-03-08 20:28:32 -05005831bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005832 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005833 GLsizei count,
5834 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005835 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005836{
5837 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5838}
5839
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005840bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005841 GLenum target,
5842 GLenum attachment,
5843 GLenum pname,
5844 GLint *params)
5845{
5846 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5847 nullptr);
5848}
5849
Jamie Madill5b772312018-03-08 20:28:32 -05005850bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005851{
5852 return ValidateGetProgramivBase(context, program, pname, nullptr);
5853}
5854
Jamie Madill5b772312018-03-08 20:28:32 -05005855bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005856 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005857 GLint level,
5858 GLenum internalformat,
5859 GLint x,
5860 GLint y,
5861 GLsizei width,
5862 GLsizei height,
5863 GLint border)
5864{
5865 if (context->getClientMajorVersion() < 3)
5866 {
5867 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5868 0, x, y, width, height, border);
5869 }
5870
5871 ASSERT(context->getClientMajorVersion() == 3);
5872 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5873 0, x, y, width, height, border);
5874}
5875
5876bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005877 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005878 GLint level,
5879 GLint xoffset,
5880 GLint yoffset,
5881 GLint x,
5882 GLint y,
5883 GLsizei width,
5884 GLsizei height)
5885{
5886 if (context->getClientMajorVersion() < 3)
5887 {
5888 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5889 yoffset, x, y, width, height, 0);
5890 }
5891
5892 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5893 yoffset, 0, x, y, width, height, 0);
5894}
5895
5896bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5897{
5898 return ValidateGenOrDelete(context, n);
5899}
5900
5901bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5902{
5903 return ValidateGenOrDelete(context, n);
5904}
5905
5906bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5907{
5908 return ValidateGenOrDelete(context, n);
5909}
5910
5911bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5912{
5913 return ValidateGenOrDelete(context, n);
5914}
5915
5916bool ValidateDisable(Context *context, GLenum cap)
5917{
5918 if (!ValidCap(context, cap, false))
5919 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005920 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005921 return false;
5922 }
5923
5924 return true;
5925}
5926
5927bool ValidateEnable(Context *context, GLenum cap)
5928{
5929 if (!ValidCap(context, cap, false))
5930 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005931 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005932 return false;
5933 }
5934
5935 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5936 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5937 {
5938 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005939 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005940
5941 // We also output an error message to the debugger window if tracing is active, so that
5942 // developers can see the error message.
5943 ERR() << errorMessage;
5944 return false;
5945 }
5946
5947 return true;
5948}
5949
5950bool ValidateFramebufferRenderbuffer(Context *context,
5951 GLenum target,
5952 GLenum attachment,
5953 GLenum renderbuffertarget,
5954 GLuint renderbuffer)
5955{
Geoff Lange8afa902017-09-27 15:00:43 -04005956 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005957 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005958 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5959 return false;
5960 }
5961
5962 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5963 {
5964 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005965 return false;
5966 }
5967
5968 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5969 renderbuffertarget, renderbuffer);
5970}
5971
5972bool ValidateFramebufferTexture2D(Context *context,
5973 GLenum target,
5974 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005975 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005976 GLuint texture,
5977 GLint level)
5978{
5979 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5980 // extension
5981 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5982 level != 0)
5983 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005984 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005985 return false;
5986 }
5987
5988 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5989 {
5990 return false;
5991 }
5992
5993 if (texture != 0)
5994 {
5995 gl::Texture *tex = context->getTexture(texture);
5996 ASSERT(tex);
5997
5998 const gl::Caps &caps = context->getCaps();
5999
6000 switch (textarget)
6001 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006002 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006003 {
6004 if (level > gl::log2(caps.max2DTextureSize))
6005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006006 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006007 return false;
6008 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006009 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006010 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006011 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 return false;
6013 }
6014 }
6015 break;
6016
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006017 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006018 {
6019 if (level != 0)
6020 {
6021 context->handleError(InvalidValue());
6022 return false;
6023 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006024 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006025 {
6026 context->handleError(InvalidOperation()
6027 << "Textarget must match the texture target type.");
6028 return false;
6029 }
6030 }
6031 break;
6032
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006033 case TextureTarget::CubeMapNegativeX:
6034 case TextureTarget::CubeMapNegativeY:
6035 case TextureTarget::CubeMapNegativeZ:
6036 case TextureTarget::CubeMapPositiveX:
6037 case TextureTarget::CubeMapPositiveY:
6038 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006039 {
6040 if (level > gl::log2(caps.maxCubeMapTextureSize))
6041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006042 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006043 return false;
6044 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006045 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006046 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006047 context->handleError(InvalidOperation()
6048 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 return false;
6050 }
6051 }
6052 break;
6053
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006054 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006055 {
6056 if (context->getClientVersion() < ES_3_1)
6057 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006058 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006059 return false;
6060 }
6061
6062 if (level != 0)
6063 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006064 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006065 return false;
6066 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006067 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006069 context->handleError(InvalidOperation()
6070 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006071 return false;
6072 }
6073 }
6074 break;
6075
6076 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006077 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006078 return false;
6079 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006080 }
6081
6082 return true;
6083}
6084
6085bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6086{
6087 return ValidateGenOrDelete(context, n);
6088}
6089
6090bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6091{
6092 return ValidateGenOrDelete(context, n);
6093}
6094
6095bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6096{
6097 return ValidateGenOrDelete(context, n);
6098}
6099
6100bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6101{
6102 return ValidateGenOrDelete(context, n);
6103}
6104
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006105bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006106{
6107 if (!ValidTextureTarget(context, target))
6108 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006109 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006110 return false;
6111 }
6112
6113 Texture *texture = context->getTargetTexture(target);
6114
6115 if (texture == nullptr)
6116 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006117 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006118 return false;
6119 }
6120
6121 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6122
6123 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6124 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6125 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6126 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006127 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006128 return false;
6129 }
6130
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006131 TextureTarget baseTarget = (target == TextureType::CubeMap)
6132 ? TextureTarget::CubeMapPositiveX
6133 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006134 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6135 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6136 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006137 {
6138 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6139 return false;
6140 }
6141
Geoff Lang536eca12017-09-13 11:23:35 -04006142 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6143 bool formatUnsized = !format.sized;
6144 bool formatColorRenderableAndFilterable =
6145 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006146 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006147 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006148 {
Geoff Lang536eca12017-09-13 11:23:35 -04006149 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006150 return false;
6151 }
6152
Geoff Lang536eca12017-09-13 11:23:35 -04006153 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6154 // generation
6155 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6156 {
6157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6158 return false;
6159 }
6160
Jiange2c00842018-07-13 16:50:49 +08006161 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6162 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6163 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006164 {
Geoff Lang536eca12017-09-13 11:23:35 -04006165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006166 return false;
6167 }
6168
6169 // Non-power of 2 ES2 check
6170 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6171 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6172 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6173 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006174 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6175 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006176 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006177 return false;
6178 }
6179
6180 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006181 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006182 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006183 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006184 return false;
6185 }
6186
6187 return true;
6188}
6189
Jamie Madill5b772312018-03-08 20:28:32 -05006190bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006191 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006192 GLenum pname,
6193 GLint *params)
6194{
6195 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6196}
6197
6198bool ValidateGetRenderbufferParameteriv(Context *context,
6199 GLenum target,
6200 GLenum pname,
6201 GLint *params)
6202{
6203 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6204}
6205
6206bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6207{
6208 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6209}
6210
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006211bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006212{
6213 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6214}
6215
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006216bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006217{
6218 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6219}
6220
6221bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6222{
6223 return ValidateGetUniformBase(context, program, location);
6224}
6225
6226bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6227{
6228 return ValidateGetUniformBase(context, program, location);
6229}
6230
6231bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6232{
6233 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6234}
6235
6236bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6237{
6238 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6239}
6240
6241bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6242{
6243 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6244}
6245
6246bool ValidateIsEnabled(Context *context, GLenum cap)
6247{
6248 if (!ValidCap(context, cap, true))
6249 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006250 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006251 return false;
6252 }
6253
6254 return true;
6255}
6256
6257bool ValidateLinkProgram(Context *context, GLuint program)
6258{
6259 if (context->hasActiveTransformFeedback(program))
6260 {
6261 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006262 context->handleError(InvalidOperation() << "Cannot link program while program is "
6263 "associated with an active transform "
6264 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006265 return false;
6266 }
6267
6268 Program *programObject = GetValidProgram(context, program);
6269 if (!programObject)
6270 {
6271 return false;
6272 }
6273
6274 return true;
6275}
6276
Jamie Madill4928b7c2017-06-20 12:57:39 -04006277bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006278 GLint x,
6279 GLint y,
6280 GLsizei width,
6281 GLsizei height,
6282 GLenum format,
6283 GLenum type,
6284 void *pixels)
6285{
6286 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6287 nullptr, pixels);
6288}
6289
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006290bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006291{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006292 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006293}
6294
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006295bool ValidateTexParameterfv(Context *context,
6296 TextureType target,
6297 GLenum pname,
6298 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006299{
6300 return ValidateTexParameterBase(context, target, pname, -1, params);
6301}
6302
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006303bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006304{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006305 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006306}
6307
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006308bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006309{
6310 return ValidateTexParameterBase(context, target, pname, -1, params);
6311}
6312
6313bool ValidateUseProgram(Context *context, GLuint program)
6314{
6315 if (program != 0)
6316 {
6317 Program *programObject = context->getProgram(program);
6318 if (!programObject)
6319 {
6320 // ES 3.1.0 section 7.3 page 72
6321 if (context->getShader(program))
6322 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006323 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006324 return false;
6325 }
6326 else
6327 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006328 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006329 return false;
6330 }
6331 }
6332 if (!programObject->isLinked())
6333 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006334 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006335 return false;
6336 }
6337 }
6338 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6339 {
6340 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006341 context
6342 ->handleError(InvalidOperation()
6343 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006344 return false;
6345 }
6346
6347 return true;
6348}
6349
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006350bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6351{
6352 if (!context->getExtensions().fence)
6353 {
6354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6355 return false;
6356 }
6357
6358 if (n < 0)
6359 {
6360 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6361 return false;
6362 }
6363
6364 return true;
6365}
6366
6367bool ValidateFinishFenceNV(Context *context, GLuint fence)
6368{
6369 if (!context->getExtensions().fence)
6370 {
6371 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6372 return false;
6373 }
6374
6375 FenceNV *fenceObject = context->getFenceNV(fence);
6376
6377 if (fenceObject == nullptr)
6378 {
6379 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6380 return false;
6381 }
6382
6383 if (!fenceObject->isSet())
6384 {
6385 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6386 return false;
6387 }
6388
6389 return true;
6390}
6391
6392bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6393{
6394 if (!context->getExtensions().fence)
6395 {
6396 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6397 return false;
6398 }
6399
6400 if (n < 0)
6401 {
6402 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6403 return false;
6404 }
6405
6406 return true;
6407}
6408
6409bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6410{
6411 if (!context->getExtensions().fence)
6412 {
6413 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6414 return false;
6415 }
6416
6417 FenceNV *fenceObject = context->getFenceNV(fence);
6418
6419 if (fenceObject == nullptr)
6420 {
6421 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6422 return false;
6423 }
6424
6425 if (!fenceObject->isSet())
6426 {
6427 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6428 return false;
6429 }
6430
6431 switch (pname)
6432 {
6433 case GL_FENCE_STATUS_NV:
6434 case GL_FENCE_CONDITION_NV:
6435 break;
6436
6437 default:
6438 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6439 return false;
6440 }
6441
6442 return true;
6443}
6444
6445bool ValidateGetGraphicsResetStatusEXT(Context *context)
6446{
6447 if (!context->getExtensions().robustness)
6448 {
6449 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6450 return false;
6451 }
6452
6453 return true;
6454}
6455
6456bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6457 GLuint shader,
6458 GLsizei bufsize,
6459 GLsizei *length,
6460 GLchar *source)
6461{
6462 if (!context->getExtensions().translatedShaderSource)
6463 {
6464 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6465 return false;
6466 }
6467
6468 if (bufsize < 0)
6469 {
6470 context->handleError(InvalidValue());
6471 return false;
6472 }
6473
6474 Shader *shaderObject = context->getShader(shader);
6475
6476 if (!shaderObject)
6477 {
6478 context->handleError(InvalidOperation());
6479 return false;
6480 }
6481
6482 return true;
6483}
6484
6485bool ValidateIsFenceNV(Context *context, GLuint fence)
6486{
6487 if (!context->getExtensions().fence)
6488 {
6489 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6490 return false;
6491 }
6492
6493 return true;
6494}
6495
Jamie Madill007530e2017-12-28 14:27:04 -05006496bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6497{
6498 if (!context->getExtensions().fence)
6499 {
6500 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6501 return false;
6502 }
6503
6504 if (condition != GL_ALL_COMPLETED_NV)
6505 {
6506 context->handleError(InvalidEnum());
6507 return false;
6508 }
6509
6510 FenceNV *fenceObject = context->getFenceNV(fence);
6511
6512 if (fenceObject == nullptr)
6513 {
6514 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6515 return false;
6516 }
6517
6518 return true;
6519}
6520
6521bool ValidateTestFenceNV(Context *context, GLuint fence)
6522{
6523 if (!context->getExtensions().fence)
6524 {
6525 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6526 return false;
6527 }
6528
6529 FenceNV *fenceObject = context->getFenceNV(fence);
6530
6531 if (fenceObject == nullptr)
6532 {
6533 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6534 return false;
6535 }
6536
6537 if (fenceObject->isSet() != GL_TRUE)
6538 {
6539 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6540 return false;
6541 }
6542
6543 return true;
6544}
6545
6546bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006547 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006548 GLsizei levels,
6549 GLenum internalformat,
6550 GLsizei width,
6551 GLsizei height)
6552{
6553 if (!context->getExtensions().textureStorage)
6554 {
6555 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6556 return false;
6557 }
6558
6559 if (context->getClientMajorVersion() < 3)
6560 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006561 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006562 height);
6563 }
6564
6565 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006566 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006567 1);
6568}
6569
6570bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6571{
6572 if (!context->getExtensions().instancedArrays)
6573 {
6574 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6575 return false;
6576 }
6577
6578 if (index >= MAX_VERTEX_ATTRIBS)
6579 {
6580 context->handleError(InvalidValue());
6581 return false;
6582 }
6583
6584 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6585 {
6586 if (index == 0 && divisor != 0)
6587 {
6588 const char *errorMessage =
6589 "The current context doesn't support setting a non-zero divisor on the "
6590 "attribute with index zero. "
6591 "Please reorder the attributes in your vertex shader so that attribute zero "
6592 "can have a zero divisor.";
6593 context->handleError(InvalidOperation() << errorMessage);
6594
6595 // We also output an error message to the debugger window if tracing is active, so
6596 // that developers can see the error message.
6597 ERR() << errorMessage;
6598 return false;
6599 }
6600 }
6601
6602 return true;
6603}
6604
6605bool ValidateTexImage3DOES(Context *context,
6606 GLenum target,
6607 GLint level,
6608 GLenum internalformat,
6609 GLsizei width,
6610 GLsizei height,
6611 GLsizei depth,
6612 GLint border,
6613 GLenum format,
6614 GLenum type,
6615 const void *pixels)
6616{
6617 UNIMPLEMENTED(); // FIXME
6618 return false;
6619}
6620
6621bool ValidatePopGroupMarkerEXT(Context *context)
6622{
6623 if (!context->getExtensions().debugMarker)
6624 {
6625 // The debug marker calls should not set error state
6626 // However, it seems reasonable to set an error state if the extension is not enabled
6627 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6628 return false;
6629 }
6630
6631 return true;
6632}
6633
Jamie Madillfa920eb2018-01-04 11:45:50 -05006634bool ValidateTexStorage1DEXT(Context *context,
6635 GLenum target,
6636 GLsizei levels,
6637 GLenum internalformat,
6638 GLsizei width)
6639{
6640 UNIMPLEMENTED();
6641 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6642 return false;
6643}
6644
6645bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006646 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006647 GLsizei levels,
6648 GLenum internalformat,
6649 GLsizei width,
6650 GLsizei height,
6651 GLsizei depth)
6652{
6653 if (!context->getExtensions().textureStorage)
6654 {
6655 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6656 return false;
6657 }
6658
6659 if (context->getClientMajorVersion() < 3)
6660 {
6661 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6662 return false;
6663 }
6664
6665 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6666 depth);
6667}
6668
jchen1082af6202018-06-22 10:59:52 +08006669bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6670{
6671 if (!context->getExtensions().parallelShaderCompile)
6672 {
6673 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6674 return false;
6675 }
6676 return true;
6677}
6678
Jamie Madillc29968b2016-01-20 11:17:23 -05006679} // namespace gl