blob: 895a9101571b0c8ff40bc8878c6af9bac860fc03 [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{
2984 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002985 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002986 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002987 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002988 return false;
2989 }
2990
Geoff Langf41a7152016-09-19 15:11:17 -04002991 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2992 !context->isTextureGenerated(texture))
2993 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002994 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002995 return false;
2996 }
2997
Ian Ewell54f87462016-03-10 13:47:21 -05002998 switch (target)
2999 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003000 case TextureType::_2D:
3001 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05003002 break;
3003
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003004 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003005 if (!context->getExtensions().textureRectangle)
3006 {
3007 context->handleError(InvalidEnum()
3008 << "Context does not support GL_ANGLE_texture_rectangle");
3009 return false;
3010 }
3011 break;
3012
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003013 case TextureType::_3D:
3014 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03003015 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003016 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003017 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003018 return false;
3019 }
3020 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003021
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003022 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003023 if (context->getClientVersion() < Version(3, 1))
3024 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003025 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003026 return false;
3027 }
Geoff Lang3b573612016-10-31 14:08:10 -04003028 break;
Olli Etuahod310a432018-08-24 15:40:23 +03003029 case TextureType::_2DMultisampleArray:
3030 if (!context->getExtensions().textureMultisampleArray)
3031 {
3032 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
3033 return false;
3034 }
3035 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003036 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003037 if (!context->getExtensions().eglImageExternal &&
3038 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003039 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003040 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003041 return false;
3042 }
3043 break;
3044 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003045 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003046 return false;
3047 }
3048
3049 return true;
3050}
3051
Geoff Langd8605522016-04-13 10:19:12 -04003052bool ValidateBindUniformLocationCHROMIUM(Context *context,
3053 GLuint program,
3054 GLint location,
3055 const GLchar *name)
3056{
3057 if (!context->getExtensions().bindUniformLocation)
3058 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003059 context->handleError(InvalidOperation()
3060 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003061 return false;
3062 }
3063
3064 Program *programObject = GetValidProgram(context, program);
3065 if (!programObject)
3066 {
3067 return false;
3068 }
3069
3070 if (location < 0)
3071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003072 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003073 return false;
3074 }
3075
3076 const Caps &caps = context->getCaps();
3077 if (static_cast<size_t>(location) >=
3078 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3079 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003080 context->handleError(InvalidValue() << "Location must be less than "
3081 "(MAX_VERTEX_UNIFORM_VECTORS + "
3082 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003083 return false;
3084 }
3085
Geoff Langfc32e8b2017-05-31 14:16:59 -04003086 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3087 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003088 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003090 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003091 return false;
3092 }
3093
Geoff Langd8605522016-04-13 10:19:12 -04003094 if (strncmp(name, "gl_", 3) == 0)
3095 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003096 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003097 return false;
3098 }
3099
3100 return true;
3101}
3102
Jamie Madille2e406c2016-06-02 13:04:10 -04003103bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003104{
3105 if (!context->getExtensions().framebufferMixedSamples)
3106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003107 context->handleError(InvalidOperation()
3108 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003109 return false;
3110 }
3111 switch (components)
3112 {
3113 case GL_RGB:
3114 case GL_RGBA:
3115 case GL_ALPHA:
3116 case GL_NONE:
3117 break;
3118 default:
3119 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003120 InvalidEnum()
3121 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003122 return false;
3123 }
3124
3125 return true;
3126}
3127
Sami Väisänene45e53b2016-05-25 10:36:04 +03003128// CHROMIUM_path_rendering
3129
Jamie Madill007530e2017-12-28 14:27:04 -05003130bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003131{
Jamie Madill007530e2017-12-28 14:27:04 -05003132 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003133 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003134 return false;
3135 }
Jamie Madill007530e2017-12-28 14:27:04 -05003136
Sami Väisänene45e53b2016-05-25 10:36:04 +03003137 if (matrix == nullptr)
3138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003139 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003140 return false;
3141 }
Jamie Madill007530e2017-12-28 14:27:04 -05003142
Sami Väisänene45e53b2016-05-25 10:36:04 +03003143 return true;
3144}
3145
Jamie Madill007530e2017-12-28 14:27:04 -05003146bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003147{
Jamie Madill007530e2017-12-28 14:27:04 -05003148 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003149}
3150
Jamie Madill007530e2017-12-28 14:27:04 -05003151bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003152{
3153 if (!context->getExtensions().pathRendering)
3154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003155 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003156 return false;
3157 }
3158
3159 // range = 0 is undefined in NV_path_rendering.
3160 // we add stricter semantic check here and require a non zero positive range.
3161 if (range <= 0)
3162 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003163 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003164 return false;
3165 }
3166
3167 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3168 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003169 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003170 return false;
3171 }
3172
3173 return true;
3174}
3175
Jamie Madill007530e2017-12-28 14:27:04 -05003176bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003177{
3178 if (!context->getExtensions().pathRendering)
3179 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003180 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181 return false;
3182 }
3183
3184 // range = 0 is undefined in NV_path_rendering.
3185 // we add stricter semantic check here and require a non zero positive range.
3186 if (range <= 0)
3187 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003188 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003189 return false;
3190 }
3191
3192 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3193 checkedRange += range;
3194
3195 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3196 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003197 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003198 return false;
3199 }
3200 return true;
3201}
3202
Jamie Madill007530e2017-12-28 14:27:04 -05003203bool ValidatePathCommandsCHROMIUM(Context *context,
3204 GLuint path,
3205 GLsizei numCommands,
3206 const GLubyte *commands,
3207 GLsizei numCoords,
3208 GLenum coordType,
3209 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003210{
3211 if (!context->getExtensions().pathRendering)
3212 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003213 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003214 return false;
3215 }
Brandon Jones59770802018-04-02 13:18:42 -07003216 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003217 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003218 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003219 return false;
3220 }
3221
3222 if (numCommands < 0)
3223 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003224 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003225 return false;
3226 }
3227 else if (numCommands > 0)
3228 {
3229 if (!commands)
3230 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003231 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003232 return false;
3233 }
3234 }
3235
3236 if (numCoords < 0)
3237 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003238 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003239 return false;
3240 }
3241 else if (numCoords > 0)
3242 {
3243 if (!coords)
3244 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003245 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003246 return false;
3247 }
3248 }
3249
3250 std::uint32_t coordTypeSize = 0;
3251 switch (coordType)
3252 {
3253 case GL_BYTE:
3254 coordTypeSize = sizeof(GLbyte);
3255 break;
3256
3257 case GL_UNSIGNED_BYTE:
3258 coordTypeSize = sizeof(GLubyte);
3259 break;
3260
3261 case GL_SHORT:
3262 coordTypeSize = sizeof(GLshort);
3263 break;
3264
3265 case GL_UNSIGNED_SHORT:
3266 coordTypeSize = sizeof(GLushort);
3267 break;
3268
3269 case GL_FLOAT:
3270 coordTypeSize = sizeof(GLfloat);
3271 break;
3272
3273 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003274 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003275 return false;
3276 }
3277
3278 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3279 checkedSize += (coordTypeSize * numCoords);
3280 if (!checkedSize.IsValid())
3281 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003282 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003283 return false;
3284 }
3285
3286 // early return skips command data validation when it doesn't exist.
3287 if (!commands)
3288 return true;
3289
3290 GLsizei expectedNumCoords = 0;
3291 for (GLsizei i = 0; i < numCommands; ++i)
3292 {
3293 switch (commands[i])
3294 {
3295 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3296 break;
3297 case GL_MOVE_TO_CHROMIUM:
3298 case GL_LINE_TO_CHROMIUM:
3299 expectedNumCoords += 2;
3300 break;
3301 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3302 expectedNumCoords += 4;
3303 break;
3304 case GL_CUBIC_CURVE_TO_CHROMIUM:
3305 expectedNumCoords += 6;
3306 break;
3307 case GL_CONIC_CURVE_TO_CHROMIUM:
3308 expectedNumCoords += 5;
3309 break;
3310 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003311 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003312 return false;
3313 }
3314 }
3315 if (expectedNumCoords != numCoords)
3316 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003317 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003318 return false;
3319 }
3320
3321 return true;
3322}
3323
Jamie Madill007530e2017-12-28 14:27:04 -05003324bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003325{
3326 if (!context->getExtensions().pathRendering)
3327 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003328 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003329 return false;
3330 }
Brandon Jones59770802018-04-02 13:18:42 -07003331 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003332 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003333 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003334 return false;
3335 }
3336
3337 switch (pname)
3338 {
3339 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3340 if (value < 0.0f)
3341 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003342 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003343 return false;
3344 }
3345 break;
3346 case GL_PATH_END_CAPS_CHROMIUM:
3347 switch (static_cast<GLenum>(value))
3348 {
3349 case GL_FLAT_CHROMIUM:
3350 case GL_SQUARE_CHROMIUM:
3351 case GL_ROUND_CHROMIUM:
3352 break;
3353 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003354 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003355 return false;
3356 }
3357 break;
3358 case GL_PATH_JOIN_STYLE_CHROMIUM:
3359 switch (static_cast<GLenum>(value))
3360 {
3361 case GL_MITER_REVERT_CHROMIUM:
3362 case GL_BEVEL_CHROMIUM:
3363 case GL_ROUND_CHROMIUM:
3364 break;
3365 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003366 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003367 return false;
3368 }
Nico Weber41b072b2018-02-09 10:01:32 -05003369 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003370 case GL_PATH_MITER_LIMIT_CHROMIUM:
3371 if (value < 0.0f)
3372 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003373 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003374 return false;
3375 }
3376 break;
3377
3378 case GL_PATH_STROKE_BOUND_CHROMIUM:
3379 // no errors, only clamping.
3380 break;
3381
3382 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003383 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003384 return false;
3385 }
3386 return true;
3387}
3388
Jamie Madill007530e2017-12-28 14:27:04 -05003389bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3390{
3391 // TODO(jmadill): Use proper clamping cast.
3392 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3393}
3394
3395bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003396{
3397 if (!context->getExtensions().pathRendering)
3398 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003399 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003400 return false;
3401 }
3402
Brandon Jones59770802018-04-02 13:18:42 -07003403 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003404 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003405 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003406 return false;
3407 }
3408 if (!value)
3409 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003410 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003411 return false;
3412 }
3413
3414 switch (pname)
3415 {
3416 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3417 case GL_PATH_END_CAPS_CHROMIUM:
3418 case GL_PATH_JOIN_STYLE_CHROMIUM:
3419 case GL_PATH_MITER_LIMIT_CHROMIUM:
3420 case GL_PATH_STROKE_BOUND_CHROMIUM:
3421 break;
3422
3423 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003424 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003425 return false;
3426 }
3427
3428 return true;
3429}
3430
Jamie Madill007530e2017-12-28 14:27:04 -05003431bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3432{
3433 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3434 reinterpret_cast<GLfloat *>(value));
3435}
3436
3437bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003438{
3439 if (!context->getExtensions().pathRendering)
3440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003441 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003442 return false;
3443 }
3444
3445 switch (func)
3446 {
3447 case GL_NEVER:
3448 case GL_ALWAYS:
3449 case GL_LESS:
3450 case GL_LEQUAL:
3451 case GL_EQUAL:
3452 case GL_GEQUAL:
3453 case GL_GREATER:
3454 case GL_NOTEQUAL:
3455 break;
3456 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003457 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458 return false;
3459 }
3460
3461 return true;
3462}
3463
3464// Note that the spec specifies that for the path drawing commands
3465// if the path object is not an existing path object the command
3466// does nothing and no error is generated.
3467// However if the path object exists but has not been specified any
3468// commands then an error is generated.
3469
Jamie Madill007530e2017-12-28 14:27:04 -05003470bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471{
3472 if (!context->getExtensions().pathRendering)
3473 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003474 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003475 return false;
3476 }
Brandon Jones59770802018-04-02 13:18:42 -07003477 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003478 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003479 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003480 return false;
3481 }
3482
3483 switch (fillMode)
3484 {
3485 case GL_COUNT_UP_CHROMIUM:
3486 case GL_COUNT_DOWN_CHROMIUM:
3487 break;
3488 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003489 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003490 return false;
3491 }
3492
3493 if (!isPow2(mask + 1))
3494 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003495 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003496 return false;
3497 }
3498
3499 return true;
3500}
3501
Jamie Madill007530e2017-12-28 14:27:04 -05003502bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003503{
3504 if (!context->getExtensions().pathRendering)
3505 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003506 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003507 return false;
3508 }
Brandon Jones59770802018-04-02 13:18:42 -07003509 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003511 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003512 return false;
3513 }
3514
3515 return true;
3516}
3517
Brandon Jonesd1049182018-03-28 10:02:20 -07003518bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3519{
3520 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3521}
3522
3523bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3524{
3525 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3526}
3527
Jamie Madill007530e2017-12-28 14:27:04 -05003528bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003529{
3530 if (!context->getExtensions().pathRendering)
3531 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003532 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003533 return false;
3534 }
Brandon Jones59770802018-04-02 13:18:42 -07003535 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003536 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003537 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003538 return false;
3539 }
3540
3541 switch (coverMode)
3542 {
3543 case GL_CONVEX_HULL_CHROMIUM:
3544 case GL_BOUNDING_BOX_CHROMIUM:
3545 break;
3546 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003547 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003548 return false;
3549 }
3550 return true;
3551}
3552
Jamie Madill007530e2017-12-28 14:27:04 -05003553bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3554 GLuint path,
3555 GLenum fillMode,
3556 GLuint mask,
3557 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003558{
Jamie Madill007530e2017-12-28 14:27:04 -05003559 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3560 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003561}
3562
Jamie Madill007530e2017-12-28 14:27:04 -05003563bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3564 GLuint path,
3565 GLint reference,
3566 GLuint mask,
3567 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003568{
Jamie Madill007530e2017-12-28 14:27:04 -05003569 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3570 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003571}
3572
Brandon Jonesd1049182018-03-28 10:02:20 -07003573bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003574{
3575 if (!context->getExtensions().pathRendering)
3576 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003577 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003578 return false;
3579 }
3580 return true;
3581}
3582
Jamie Madill007530e2017-12-28 14:27:04 -05003583bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3584 GLsizei numPaths,
3585 GLenum pathNameType,
3586 const void *paths,
3587 GLuint pathBase,
3588 GLenum coverMode,
3589 GLenum transformType,
3590 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003591{
3592 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3593 transformType, transformValues))
3594 return false;
3595
3596 switch (coverMode)
3597 {
3598 case GL_CONVEX_HULL_CHROMIUM:
3599 case GL_BOUNDING_BOX_CHROMIUM:
3600 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3601 break;
3602 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003603 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003604 return false;
3605 }
3606
3607 return true;
3608}
3609
Jamie Madill007530e2017-12-28 14:27:04 -05003610bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3611 GLsizei numPaths,
3612 GLenum pathNameType,
3613 const void *paths,
3614 GLuint pathBase,
3615 GLenum coverMode,
3616 GLenum transformType,
3617 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003618{
3619 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3620 transformType, transformValues))
3621 return false;
3622
3623 switch (coverMode)
3624 {
3625 case GL_CONVEX_HULL_CHROMIUM:
3626 case GL_BOUNDING_BOX_CHROMIUM:
3627 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3628 break;
3629 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003630 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003631 return false;
3632 }
3633
3634 return true;
3635}
3636
Jamie Madill007530e2017-12-28 14:27:04 -05003637bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3638 GLsizei numPaths,
3639 GLenum pathNameType,
3640 const void *paths,
3641 GLuint pathBase,
3642 GLenum fillMode,
3643 GLuint mask,
3644 GLenum transformType,
3645 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003646{
3647
3648 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3649 transformType, transformValues))
3650 return false;
3651
3652 switch (fillMode)
3653 {
3654 case GL_COUNT_UP_CHROMIUM:
3655 case GL_COUNT_DOWN_CHROMIUM:
3656 break;
3657 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003658 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003659 return false;
3660 }
3661 if (!isPow2(mask + 1))
3662 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003663 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003664 return false;
3665 }
3666 return true;
3667}
3668
Jamie Madill007530e2017-12-28 14:27:04 -05003669bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3670 GLsizei numPaths,
3671 GLenum pathNameType,
3672 const void *paths,
3673 GLuint pathBase,
3674 GLint reference,
3675 GLuint mask,
3676 GLenum transformType,
3677 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003678{
3679 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3680 transformType, transformValues))
3681 return false;
3682
3683 // no more validation here.
3684
3685 return true;
3686}
3687
Jamie Madill007530e2017-12-28 14:27:04 -05003688bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3689 GLsizei numPaths,
3690 GLenum pathNameType,
3691 const void *paths,
3692 GLuint pathBase,
3693 GLenum fillMode,
3694 GLuint mask,
3695 GLenum coverMode,
3696 GLenum transformType,
3697 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003698{
3699 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3700 transformType, transformValues))
3701 return false;
3702
3703 switch (coverMode)
3704 {
3705 case GL_CONVEX_HULL_CHROMIUM:
3706 case GL_BOUNDING_BOX_CHROMIUM:
3707 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3708 break;
3709 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003710 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003711 return false;
3712 }
3713
3714 switch (fillMode)
3715 {
3716 case GL_COUNT_UP_CHROMIUM:
3717 case GL_COUNT_DOWN_CHROMIUM:
3718 break;
3719 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003720 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003721 return false;
3722 }
3723 if (!isPow2(mask + 1))
3724 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003725 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003726 return false;
3727 }
3728
3729 return true;
3730}
3731
Jamie Madill007530e2017-12-28 14:27:04 -05003732bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3733 GLsizei numPaths,
3734 GLenum pathNameType,
3735 const void *paths,
3736 GLuint pathBase,
3737 GLint reference,
3738 GLuint mask,
3739 GLenum coverMode,
3740 GLenum transformType,
3741 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003742{
3743 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3744 transformType, transformValues))
3745 return false;
3746
3747 switch (coverMode)
3748 {
3749 case GL_CONVEX_HULL_CHROMIUM:
3750 case GL_BOUNDING_BOX_CHROMIUM:
3751 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3752 break;
3753 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003754 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003755 return false;
3756 }
3757
3758 return true;
3759}
3760
Jamie Madill007530e2017-12-28 14:27:04 -05003761bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3762 GLuint program,
3763 GLint location,
3764 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003765{
3766 if (!context->getExtensions().pathRendering)
3767 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003768 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003769 return false;
3770 }
3771
3772 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3773 if (location >= MaxLocation)
3774 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003775 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003776 return false;
3777 }
3778
3779 const auto *programObject = context->getProgram(program);
3780 if (!programObject)
3781 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003782 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003783 return false;
3784 }
3785
3786 if (!name)
3787 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003788 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003789 return false;
3790 }
3791
3792 if (angle::BeginsWith(name, "gl_"))
3793 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003794 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003795 return false;
3796 }
3797
3798 return true;
3799}
3800
Jamie Madill007530e2017-12-28 14:27:04 -05003801bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3802 GLuint program,
3803 GLint location,
3804 GLenum genMode,
3805 GLint components,
3806 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003807{
3808 if (!context->getExtensions().pathRendering)
3809 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003810 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003811 return false;
3812 }
3813
3814 const auto *programObject = context->getProgram(program);
3815 if (!programObject || programObject->isFlaggedForDeletion())
3816 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003817 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003818 return false;
3819 }
3820
3821 if (!programObject->isLinked())
3822 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003823 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003824 return false;
3825 }
3826
3827 switch (genMode)
3828 {
3829 case GL_NONE:
3830 if (components != 0)
3831 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003832 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003833 return false;
3834 }
3835 break;
3836
3837 case GL_OBJECT_LINEAR_CHROMIUM:
3838 case GL_EYE_LINEAR_CHROMIUM:
3839 case GL_CONSTANT_CHROMIUM:
3840 if (components < 1 || components > 4)
3841 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003842 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003843 return false;
3844 }
3845 if (!coeffs)
3846 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003847 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003848 return false;
3849 }
3850 break;
3851
3852 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003853 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003854 return false;
3855 }
3856
3857 // If the location is -1 then the command is silently ignored
3858 // and no further validation is needed.
3859 if (location == -1)
3860 return true;
3861
jchen103fd614d2018-08-13 12:21:58 +08003862 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003863
3864 if (!binding.valid)
3865 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003866 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003867 return false;
3868 }
3869
3870 if (binding.type != GL_NONE)
3871 {
3872 GLint expectedComponents = 0;
3873 switch (binding.type)
3874 {
3875 case GL_FLOAT:
3876 expectedComponents = 1;
3877 break;
3878 case GL_FLOAT_VEC2:
3879 expectedComponents = 2;
3880 break;
3881 case GL_FLOAT_VEC3:
3882 expectedComponents = 3;
3883 break;
3884 case GL_FLOAT_VEC4:
3885 expectedComponents = 4;
3886 break;
3887 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003888 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003889 InvalidOperation()
3890 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003891 return false;
3892 }
3893 if (expectedComponents != components && genMode != GL_NONE)
3894 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003895 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003896 return false;
3897 }
3898 }
3899 return true;
3900}
3901
Geoff Lang97073d12016-04-20 10:42:34 -07003902bool ValidateCopyTextureCHROMIUM(Context *context,
3903 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003904 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003905 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003906 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003907 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003908 GLint internalFormat,
3909 GLenum destType,
3910 GLboolean unpackFlipY,
3911 GLboolean unpackPremultiplyAlpha,
3912 GLboolean unpackUnmultiplyAlpha)
3913{
3914 if (!context->getExtensions().copyTexture)
3915 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003916 context->handleError(InvalidOperation()
3917 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003918 return false;
3919 }
3920
Geoff Lang4f0e0032017-05-01 16:04:35 -04003921 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003922 if (source == nullptr)
3923 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003924 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003925 return false;
3926 }
3927
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003928 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003929 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003930 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003931 return false;
3932 }
3933
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003934 TextureType sourceType = source->getType();
3935 ASSERT(sourceType != TextureType::CubeMap);
3936 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003937
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003938 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003939 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003940 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003941 return false;
3942 }
3943
Geoff Lang4f0e0032017-05-01 16:04:35 -04003944 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3945 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3946 if (sourceWidth == 0 || sourceHeight == 0)
3947 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003948 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003949 return false;
3950 }
3951
3952 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3953 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003954 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003955 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003956 return false;
3957 }
3958
Geoff Lang63458a32017-10-30 15:16:53 -04003959 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3960 {
3961 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3962 return false;
3963 }
3964
Geoff Lang4f0e0032017-05-01 16:04:35 -04003965 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003966 if (dest == nullptr)
3967 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003968 context->handleError(InvalidValue()
3969 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003970 return false;
3971 }
3972
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003973 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003974 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003975 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003976 return false;
3977 }
3978
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003979 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003980 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003981 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003982 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003983 return false;
3984 }
3985
Geoff Lang97073d12016-04-20 10:42:34 -07003986 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3987 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003988 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003989 return false;
3990 }
3991
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003992 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003993 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003994 context->handleError(
3995 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003996 return false;
3997 }
3998
Geoff Lang97073d12016-04-20 10:42:34 -07003999 if (dest->getImmutableFormat())
4000 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004001 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07004002 return false;
4003 }
4004
4005 return true;
4006}
4007
4008bool ValidateCopySubTextureCHROMIUM(Context *context,
4009 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004010 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004011 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004012 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004013 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004014 GLint xoffset,
4015 GLint yoffset,
4016 GLint x,
4017 GLint y,
4018 GLsizei width,
4019 GLsizei height,
4020 GLboolean unpackFlipY,
4021 GLboolean unpackPremultiplyAlpha,
4022 GLboolean unpackUnmultiplyAlpha)
4023{
4024 if (!context->getExtensions().copyTexture)
4025 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004026 context->handleError(InvalidOperation()
4027 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004028 return false;
4029 }
4030
Geoff Lang4f0e0032017-05-01 16:04:35 -04004031 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004032 if (source == nullptr)
4033 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004034 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004035 return false;
4036 }
4037
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004038 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004039 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004040 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004041 return false;
4042 }
4043
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004044 TextureType sourceType = source->getType();
4045 ASSERT(sourceType != TextureType::CubeMap);
4046 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004047
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004048 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004049 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004050 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004051 return false;
4052 }
4053
4054 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4055 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004056 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004057 context->handleError(InvalidValue()
4058 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004059 return false;
4060 }
4061
4062 if (x < 0 || y < 0)
4063 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004064 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004065 return false;
4066 }
4067
4068 if (width < 0 || height < 0)
4069 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004070 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004071 return false;
4072 }
4073
Geoff Lang4f0e0032017-05-01 16:04:35 -04004074 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4075 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004076 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004077 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004078 return false;
4079 }
4080
Geoff Lang4f0e0032017-05-01 16:04:35 -04004081 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4082 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004083 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004084 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004085 return false;
4086 }
4087
Geoff Lang63458a32017-10-30 15:16:53 -04004088 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4089 {
4090 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4091 return false;
4092 }
4093
Geoff Lang4f0e0032017-05-01 16:04:35 -04004094 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004095 if (dest == nullptr)
4096 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004097 context->handleError(InvalidValue()
4098 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004099 return false;
4100 }
4101
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004102 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004103 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004104 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004105 return false;
4106 }
4107
Brandon Jones28783792018-03-05 09:37:32 -08004108 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4109 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004110 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004111 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004112 return false;
4113 }
4114
Geoff Lang4f0e0032017-05-01 16:04:35 -04004115 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4116 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004117 context
4118 ->handleError(InvalidOperation()
4119 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004120 return false;
4121 }
4122
4123 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4124 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004125 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004126 context->handleError(InvalidOperation()
4127 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004128 return false;
4129 }
4130
4131 if (xoffset < 0 || yoffset < 0)
4132 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004133 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004134 return false;
4135 }
4136
Geoff Lang4f0e0032017-05-01 16:04:35 -04004137 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4138 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004140 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004141 return false;
4142 }
4143
4144 return true;
4145}
4146
Geoff Lang47110bf2016-04-20 11:13:22 -07004147bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4148{
4149 if (!context->getExtensions().copyCompressedTexture)
4150 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004151 context->handleError(InvalidOperation()
4152 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004153 return false;
4154 }
4155
4156 const gl::Texture *source = context->getTexture(sourceId);
4157 if (source == nullptr)
4158 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004159 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004160 return false;
4161 }
4162
Corentin Wallez99d492c2018-02-27 15:17:10 -05004163 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004164 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004165 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004166 return false;
4167 }
4168
Corentin Wallez99d492c2018-02-27 15:17:10 -05004169 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4170 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004171 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004172 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004173 return false;
4174 }
4175
Corentin Wallez99d492c2018-02-27 15:17:10 -05004176 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004177 if (!sourceFormat.info->compressed)
4178 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004179 context->handleError(InvalidOperation()
4180 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004181 return false;
4182 }
4183
4184 const gl::Texture *dest = context->getTexture(destId);
4185 if (dest == nullptr)
4186 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004187 context->handleError(InvalidValue()
4188 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004189 return false;
4190 }
4191
Corentin Wallez99d492c2018-02-27 15:17:10 -05004192 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004194 context->handleError(InvalidValue()
4195 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004196 return false;
4197 }
4198
4199 if (dest->getImmutableFormat())
4200 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004201 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004202 return false;
4203 }
4204
4205 return true;
4206}
4207
Jiawei Shao385b3e02018-03-21 09:43:28 +08004208bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004209{
4210 switch (type)
4211 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004212 case ShaderType::Vertex:
4213 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004214 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004215
Jiawei Shao385b3e02018-03-21 09:43:28 +08004216 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004217 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004218 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004219 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004220 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004221 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004222 break;
4223
Jiawei Shao385b3e02018-03-21 09:43:28 +08004224 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004225 if (!context->getExtensions().geometryShader)
4226 {
4227 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4228 return false;
4229 }
4230 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004231 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004232 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004233 return false;
4234 }
Jamie Madill29639852016-09-02 15:00:09 -04004235
4236 return true;
4237}
4238
Jamie Madill5b772312018-03-08 20:28:32 -05004239bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004240 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004241 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004242 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004243 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004244{
4245 if (size < 0)
4246 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004247 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004248 return false;
4249 }
4250
4251 switch (usage)
4252 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004253 case BufferUsage::StreamDraw:
4254 case BufferUsage::StaticDraw:
4255 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004256 break;
4257
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004258 case BufferUsage::StreamRead:
4259 case BufferUsage::StaticRead:
4260 case BufferUsage::DynamicRead:
4261 case BufferUsage::StreamCopy:
4262 case BufferUsage::StaticCopy:
4263 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004264 if (context->getClientMajorVersion() < 3)
4265 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004266 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004267 return false;
4268 }
4269 break;
4270
4271 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004272 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004273 return false;
4274 }
4275
Corentin Walleze4477002017-12-01 14:39:58 -05004276 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004277 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004278 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004279 return false;
4280 }
4281
4282 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4283
4284 if (!buffer)
4285 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004286 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004287 return false;
4288 }
4289
James Darpiniane8a93c62018-01-04 18:02:24 -08004290 if (context->getExtensions().webglCompatibility &&
4291 buffer->isBoundForTransformFeedbackAndOtherUse())
4292 {
4293 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4294 return false;
4295 }
4296
Jamie Madill29639852016-09-02 15:00:09 -04004297 return true;
4298}
4299
Jamie Madill5b772312018-03-08 20:28:32 -05004300bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004301 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004302 GLintptr offset,
4303 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004304 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004305{
Brandon Jones6cad5662017-06-14 13:25:13 -07004306 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004307 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004308 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4309 return false;
4310 }
4311
4312 if (offset < 0)
4313 {
4314 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004315 return false;
4316 }
4317
Corentin Walleze4477002017-12-01 14:39:58 -05004318 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004319 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004320 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004321 return false;
4322 }
4323
4324 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4325
4326 if (!buffer)
4327 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004328 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004329 return false;
4330 }
4331
4332 if (buffer->isMapped())
4333 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004334 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004335 return false;
4336 }
4337
James Darpiniane8a93c62018-01-04 18:02:24 -08004338 if (context->getExtensions().webglCompatibility &&
4339 buffer->isBoundForTransformFeedbackAndOtherUse())
4340 {
4341 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4342 return false;
4343 }
4344
Jamie Madill29639852016-09-02 15:00:09 -04004345 // Check for possible overflow of size + offset
4346 angle::CheckedNumeric<size_t> checkedSize(size);
4347 checkedSize += offset;
4348 if (!checkedSize.IsValid())
4349 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004350 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004351 return false;
4352 }
4353
4354 if (size + offset > buffer->getSize())
4355 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004356 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004357 return false;
4358 }
4359
Martin Radev4c4c8e72016-08-04 12:25:34 +03004360 return true;
4361}
4362
Geoff Lang111a99e2017-10-17 10:58:41 -04004363bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004364{
Geoff Langc339c4e2016-11-29 10:37:36 -05004365 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004366 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004367 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004368 return false;
4369 }
4370
Geoff Lang111a99e2017-10-17 10:58:41 -04004371 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004372 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004373 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004374 return false;
4375 }
4376
4377 return true;
4378}
4379
Jamie Madill5b772312018-03-08 20:28:32 -05004380bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004381{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004382 if (context->getClientMajorVersion() < 2)
4383 {
4384 return ValidateMultitextureUnit(context, texture);
4385 }
4386
Jamie Madillef300b12016-10-07 15:12:09 -04004387 if (texture < GL_TEXTURE0 ||
4388 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4389 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004390 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004391 return false;
4392 }
4393
4394 return true;
4395}
4396
Jamie Madill5b772312018-03-08 20:28:32 -05004397bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004398{
4399 Program *programObject = GetValidProgram(context, program);
4400 if (!programObject)
4401 {
4402 return false;
4403 }
4404
4405 Shader *shaderObject = GetValidShader(context, shader);
4406 if (!shaderObject)
4407 {
4408 return false;
4409 }
4410
Jiawei Shao385b3e02018-03-21 09:43:28 +08004411 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004412 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004413 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4414 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004415 }
4416
4417 return true;
4418}
4419
Jamie Madill5b772312018-03-08 20:28:32 -05004420bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004421{
4422 if (index >= MAX_VERTEX_ATTRIBS)
4423 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004424 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004425 return false;
4426 }
4427
4428 if (strncmp(name, "gl_", 3) == 0)
4429 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004430 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004431 return false;
4432 }
4433
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004434 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004435 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004436 const size_t length = strlen(name);
4437
4438 if (!IsValidESSLString(name, length))
4439 {
4440 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4441 // for shader-related entry points
4442 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4443 return false;
4444 }
4445
4446 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4447 {
4448 return false;
4449 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004450 }
4451
Jamie Madill01a80ee2016-11-07 12:06:18 -05004452 return GetValidProgram(context, program) != nullptr;
4453}
4454
Jamie Madill5b772312018-03-08 20:28:32 -05004455bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004456{
Corentin Walleze4477002017-12-01 14:39:58 -05004457 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004458 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004459 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004460 return false;
4461 }
4462
4463 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4464 !context->isBufferGenerated(buffer))
4465 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004466 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004467 return false;
4468 }
4469
4470 return true;
4471}
4472
Jamie Madill5b772312018-03-08 20:28:32 -05004473bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004474{
Geoff Lange8afa902017-09-27 15:00:43 -04004475 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004476 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004477 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004478 return false;
4479 }
4480
4481 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4482 !context->isFramebufferGenerated(framebuffer))
4483 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004484 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004485 return false;
4486 }
4487
4488 return true;
4489}
4490
Jamie Madill5b772312018-03-08 20:28:32 -05004491bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004492{
4493 if (target != GL_RENDERBUFFER)
4494 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004495 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004496 return false;
4497 }
4498
4499 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4500 !context->isRenderbufferGenerated(renderbuffer))
4501 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004502 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004503 return false;
4504 }
4505
4506 return true;
4507}
4508
Jamie Madill5b772312018-03-08 20:28:32 -05004509static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004510{
4511 switch (mode)
4512 {
4513 case GL_FUNC_ADD:
4514 case GL_FUNC_SUBTRACT:
4515 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004516 return true;
4517
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004518 case GL_MIN:
4519 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004520 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004521
4522 default:
4523 return false;
4524 }
4525}
4526
Jamie Madill5b772312018-03-08 20:28:32 -05004527bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004528{
4529 return true;
4530}
4531
Jamie Madill5b772312018-03-08 20:28:32 -05004532bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004533{
Geoff Lang50cac572017-09-26 17:37:43 -04004534 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004536 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004537 return false;
4538 }
4539
4540 return true;
4541}
4542
Jamie Madill5b772312018-03-08 20:28:32 -05004543bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004544{
Geoff Lang50cac572017-09-26 17:37:43 -04004545 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004546 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004547 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004548 return false;
4549 }
4550
Geoff Lang50cac572017-09-26 17:37:43 -04004551 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004553 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004554 return false;
4555 }
4556
4557 return true;
4558}
4559
Jamie Madill5b772312018-03-08 20:28:32 -05004560bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004561{
4562 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4563}
4564
4565static bool ValidSrcBlendFunc(GLenum srcBlend)
4566{
4567 switch (srcBlend)
4568 {
4569 case GL_ZERO:
4570 case GL_ONE:
4571 case GL_SRC_COLOR:
4572 case GL_ONE_MINUS_SRC_COLOR:
4573 case GL_DST_COLOR:
4574 case GL_ONE_MINUS_DST_COLOR:
4575 case GL_SRC_ALPHA:
4576 case GL_ONE_MINUS_SRC_ALPHA:
4577 case GL_DST_ALPHA:
4578 case GL_ONE_MINUS_DST_ALPHA:
4579 case GL_CONSTANT_COLOR:
4580 case GL_ONE_MINUS_CONSTANT_COLOR:
4581 case GL_CONSTANT_ALPHA:
4582 case GL_ONE_MINUS_CONSTANT_ALPHA:
4583 case GL_SRC_ALPHA_SATURATE:
4584 return true;
4585
4586 default:
4587 return false;
4588 }
4589}
4590
4591static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4592{
4593 switch (dstBlend)
4594 {
4595 case GL_ZERO:
4596 case GL_ONE:
4597 case GL_SRC_COLOR:
4598 case GL_ONE_MINUS_SRC_COLOR:
4599 case GL_DST_COLOR:
4600 case GL_ONE_MINUS_DST_COLOR:
4601 case GL_SRC_ALPHA:
4602 case GL_ONE_MINUS_SRC_ALPHA:
4603 case GL_DST_ALPHA:
4604 case GL_ONE_MINUS_DST_ALPHA:
4605 case GL_CONSTANT_COLOR:
4606 case GL_ONE_MINUS_CONSTANT_COLOR:
4607 case GL_CONSTANT_ALPHA:
4608 case GL_ONE_MINUS_CONSTANT_ALPHA:
4609 return true;
4610
4611 case GL_SRC_ALPHA_SATURATE:
4612 return (contextMajorVersion >= 3);
4613
4614 default:
4615 return false;
4616 }
4617}
4618
Jamie Madill5b772312018-03-08 20:28:32 -05004619bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004620 GLenum srcRGB,
4621 GLenum dstRGB,
4622 GLenum srcAlpha,
4623 GLenum dstAlpha)
4624{
4625 if (!ValidSrcBlendFunc(srcRGB))
4626 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004627 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004628 return false;
4629 }
4630
4631 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4632 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004633 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004634 return false;
4635 }
4636
4637 if (!ValidSrcBlendFunc(srcAlpha))
4638 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004639 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004640 return false;
4641 }
4642
4643 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4644 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004645 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004646 return false;
4647 }
4648
Frank Henigman146e8a12017-03-02 23:22:37 -05004649 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4650 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004651 {
4652 bool constantColorUsed =
4653 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4654 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4655
4656 bool constantAlphaUsed =
4657 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4658 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4659
4660 if (constantColorUsed && constantAlphaUsed)
4661 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004662 const char *msg;
4663 if (context->getExtensions().webglCompatibility)
4664 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004665 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004666 }
4667 else
4668 {
4669 msg =
4670 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4671 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4672 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004673 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004674 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004675 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004676 return false;
4677 }
4678 }
4679
4680 return true;
4681}
4682
Geoff Langc339c4e2016-11-29 10:37:36 -05004683bool ValidateGetString(Context *context, GLenum name)
4684{
4685 switch (name)
4686 {
4687 case GL_VENDOR:
4688 case GL_RENDERER:
4689 case GL_VERSION:
4690 case GL_SHADING_LANGUAGE_VERSION:
4691 case GL_EXTENSIONS:
4692 break;
4693
4694 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4695 if (!context->getExtensions().requestExtension)
4696 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004697 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004698 return false;
4699 }
4700 break;
4701
4702 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004703 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004704 return false;
4705 }
4706
4707 return true;
4708}
4709
Jamie Madill5b772312018-03-08 20:28:32 -05004710bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004711{
4712 if (width <= 0.0f || isNaN(width))
4713 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004714 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004715 return false;
4716 }
4717
4718 return true;
4719}
4720
Jamie Madill5b772312018-03-08 20:28:32 -05004721bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004722 GLuint index,
4723 GLint size,
4724 GLenum type,
4725 GLboolean normalized,
4726 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004727 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004728{
Shao80957d92017-02-20 21:25:59 +08004729 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004730 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004731 return false;
4732 }
4733
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004734 if (stride < 0)
4735 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004736 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004737 return false;
4738 }
4739
Shao80957d92017-02-20 21:25:59 +08004740 const Caps &caps = context->getCaps();
4741 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004742 {
Shao80957d92017-02-20 21:25:59 +08004743 if (stride > caps.maxVertexAttribStride)
4744 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004745 context->handleError(InvalidValue()
4746 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004747 return false;
4748 }
4749
4750 if (index >= caps.maxVertexAttribBindings)
4751 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004752 context->handleError(InvalidValue()
4753 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004754 return false;
4755 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004756 }
4757
4758 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4759 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4760 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4761 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004762 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4763 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004764 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4765 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004767 context
4768 ->handleError(InvalidOperation()
4769 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004770 return false;
4771 }
4772
4773 if (context->getExtensions().webglCompatibility)
4774 {
4775 // WebGL 1.0 [Section 6.14] Fixed point support
4776 // The WebGL API does not support the GL_FIXED data type.
4777 if (type == GL_FIXED)
4778 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004779 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004780 return false;
4781 }
4782
Geoff Lang2d62ab72017-03-23 16:54:40 -04004783 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004784 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004785 return false;
4786 }
4787 }
4788
4789 return true;
4790}
4791
Jamie Madill5b772312018-03-08 20:28:32 -05004792bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004793{
4794 if (context->getExtensions().webglCompatibility && zNear > zFar)
4795 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004796 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004797 return false;
4798 }
4799
4800 return true;
4801}
4802
Jamie Madill5b772312018-03-08 20:28:32 -05004803bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004804 GLenum target,
4805 GLenum internalformat,
4806 GLsizei width,
4807 GLsizei height)
4808{
4809 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4810 height);
4811}
4812
Jamie Madill5b772312018-03-08 20:28:32 -05004813bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004814 GLenum target,
4815 GLsizei samples,
4816 GLenum internalformat,
4817 GLsizei width,
4818 GLsizei height)
4819{
4820 if (!context->getExtensions().framebufferMultisample)
4821 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004822 context->handleError(InvalidOperation()
4823 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004824 return false;
4825 }
4826
4827 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4828 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4829 // generated.
4830 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4831 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004832 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004833 return false;
4834 }
4835
4836 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4837 // the specified storage. This is different than ES 3.0 in which a sample number higher
4838 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4839 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4840 if (context->getClientMajorVersion() >= 3)
4841 {
4842 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4843 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4844 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004845 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004846 return false;
4847 }
4848 }
4849
4850 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4851 width, height);
4852}
4853
Jamie Madill5b772312018-03-08 20:28:32 -05004854bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004855{
Geoff Lange8afa902017-09-27 15:00:43 -04004856 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004857 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004858 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004859 return false;
4860 }
4861
4862 return true;
4863}
4864
Jamie Madill5b772312018-03-08 20:28:32 -05004865bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004866{
4867 return true;
4868}
4869
Jamie Madill5b772312018-03-08 20:28:32 -05004870bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004871{
4872 return true;
4873}
4874
Jamie Madill5b772312018-03-08 20:28:32 -05004875bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004876{
4877 return true;
4878}
4879
Jamie Madill5b772312018-03-08 20:28:32 -05004880bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004881 GLboolean red,
4882 GLboolean green,
4883 GLboolean blue,
4884 GLboolean alpha)
4885{
4886 return true;
4887}
4888
Jamie Madill5b772312018-03-08 20:28:32 -05004889bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004890{
4891 return true;
4892}
4893
Jamie Madill5b772312018-03-08 20:28:32 -05004894bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004895{
4896 return true;
4897}
4898
Jamie Madill5b772312018-03-08 20:28:32 -05004899bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004900{
4901 switch (mode)
4902 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004903 case CullFaceMode::Front:
4904 case CullFaceMode::Back:
4905 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004906 break;
4907
4908 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004909 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004910 return false;
4911 }
4912
4913 return true;
4914}
4915
Jamie Madill5b772312018-03-08 20:28:32 -05004916bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004917{
4918 if (program == 0)
4919 {
4920 return false;
4921 }
4922
4923 if (!context->getProgram(program))
4924 {
4925 if (context->getShader(program))
4926 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004927 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004928 return false;
4929 }
4930 else
4931 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004932 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004933 return false;
4934 }
4935 }
4936
4937 return true;
4938}
4939
Jamie Madill5b772312018-03-08 20:28:32 -05004940bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004941{
4942 if (shader == 0)
4943 {
4944 return false;
4945 }
4946
4947 if (!context->getShader(shader))
4948 {
4949 if (context->getProgram(shader))
4950 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004951 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004952 return false;
4953 }
4954 else
4955 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004956 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004957 return false;
4958 }
4959 }
4960
4961 return true;
4962}
4963
Jamie Madill5b772312018-03-08 20:28:32 -05004964bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004965{
4966 switch (func)
4967 {
4968 case GL_NEVER:
4969 case GL_ALWAYS:
4970 case GL_LESS:
4971 case GL_LEQUAL:
4972 case GL_EQUAL:
4973 case GL_GREATER:
4974 case GL_GEQUAL:
4975 case GL_NOTEQUAL:
4976 break;
4977
4978 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004979 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004980 return false;
4981 }
4982
4983 return true;
4984}
4985
Jamie Madill5b772312018-03-08 20:28:32 -05004986bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004987{
4988 return true;
4989}
4990
Jamie Madill5b772312018-03-08 20:28:32 -05004991bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004992{
4993 Program *programObject = GetValidProgram(context, program);
4994 if (!programObject)
4995 {
4996 return false;
4997 }
4998
4999 Shader *shaderObject = GetValidShader(context, shader);
5000 if (!shaderObject)
5001 {
5002 return false;
5003 }
5004
Jiawei Shao385b3e02018-03-21 09:43:28 +08005005 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005006 if (attachedShader != shaderObject)
5007 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005008 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005009 return false;
5010 }
5011
5012 return true;
5013}
5014
Jamie Madill5b772312018-03-08 20:28:32 -05005015bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005016{
5017 if (index >= MAX_VERTEX_ATTRIBS)
5018 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005019 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005020 return false;
5021 }
5022
5023 return true;
5024}
5025
Jamie Madill5b772312018-03-08 20:28:32 -05005026bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005027{
5028 if (index >= MAX_VERTEX_ATTRIBS)
5029 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005030 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005031 return false;
5032 }
5033
5034 return true;
5035}
5036
Jamie Madill5b772312018-03-08 20:28:32 -05005037bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005038{
5039 return true;
5040}
5041
Jamie Madill5b772312018-03-08 20:28:32 -05005042bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005043{
5044 return true;
5045}
5046
Jamie Madill5b772312018-03-08 20:28:32 -05005047bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005048{
5049 switch (mode)
5050 {
5051 case GL_CW:
5052 case GL_CCW:
5053 break;
5054 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005055 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005056 return false;
5057 }
5058
5059 return true;
5060}
5061
Jamie Madill5b772312018-03-08 20:28:32 -05005062bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005063 GLuint program,
5064 GLuint index,
5065 GLsizei bufsize,
5066 GLsizei *length,
5067 GLint *size,
5068 GLenum *type,
5069 GLchar *name)
5070{
5071 if (bufsize < 0)
5072 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005073 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005074 return false;
5075 }
5076
5077 Program *programObject = GetValidProgram(context, program);
5078
5079 if (!programObject)
5080 {
5081 return false;
5082 }
5083
5084 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5085 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005086 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005087 return false;
5088 }
5089
5090 return true;
5091}
5092
Jamie Madill5b772312018-03-08 20:28:32 -05005093bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005094 GLuint program,
5095 GLuint index,
5096 GLsizei bufsize,
5097 GLsizei *length,
5098 GLint *size,
5099 GLenum *type,
5100 GLchar *name)
5101{
5102 if (bufsize < 0)
5103 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005104 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005105 return false;
5106 }
5107
5108 Program *programObject = GetValidProgram(context, program);
5109
5110 if (!programObject)
5111 {
5112 return false;
5113 }
5114
5115 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5116 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005117 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005118 return false;
5119 }
5120
5121 return true;
5122}
5123
Jamie Madill5b772312018-03-08 20:28:32 -05005124bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005125 GLuint program,
5126 GLsizei maxcount,
5127 GLsizei *count,
5128 GLuint *shaders)
5129{
5130 if (maxcount < 0)
5131 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005132 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005133 return false;
5134 }
5135
5136 Program *programObject = GetValidProgram(context, program);
5137
5138 if (!programObject)
5139 {
5140 return false;
5141 }
5142
5143 return true;
5144}
5145
Jamie Madill5b772312018-03-08 20:28:32 -05005146bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005147{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005148 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5149 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005150 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005151 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005152 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005153 return false;
5154 }
5155
Jamie Madillc1d770e2017-04-13 17:31:24 -04005156 Program *programObject = GetValidProgram(context, program);
5157
5158 if (!programObject)
5159 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005160 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161 return false;
5162 }
5163
5164 if (!programObject->isLinked())
5165 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005166 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005167 return false;
5168 }
5169
5170 return true;
5171}
5172
Jamie Madill5b772312018-03-08 20:28:32 -05005173bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005174{
5175 GLenum nativeType;
5176 unsigned int numParams = 0;
5177 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5178}
5179
Jamie Madill5b772312018-03-08 20:28:32 -05005180bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005181{
5182 return true;
5183}
5184
Jamie Madill5b772312018-03-08 20:28:32 -05005185bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005186{
5187 GLenum nativeType;
5188 unsigned int numParams = 0;
5189 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5190}
5191
Jamie Madill5b772312018-03-08 20:28:32 -05005192bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005193{
5194 GLenum nativeType;
5195 unsigned int numParams = 0;
5196 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5197}
5198
Jamie Madill5b772312018-03-08 20:28:32 -05005199bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005200 GLuint program,
5201 GLsizei bufsize,
5202 GLsizei *length,
5203 GLchar *infolog)
5204{
5205 if (bufsize < 0)
5206 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005207 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005208 return false;
5209 }
5210
5211 Program *programObject = GetValidProgram(context, program);
5212 if (!programObject)
5213 {
5214 return false;
5215 }
5216
5217 return true;
5218}
5219
Jamie Madill5b772312018-03-08 20:28:32 -05005220bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005221 GLuint shader,
5222 GLsizei bufsize,
5223 GLsizei *length,
5224 GLchar *infolog)
5225{
5226 if (bufsize < 0)
5227 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005228 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005229 return false;
5230 }
5231
5232 Shader *shaderObject = GetValidShader(context, shader);
5233 if (!shaderObject)
5234 {
5235 return false;
5236 }
5237
5238 return true;
5239}
5240
Jamie Madill5b772312018-03-08 20:28:32 -05005241bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005242 GLenum shadertype,
5243 GLenum precisiontype,
5244 GLint *range,
5245 GLint *precision)
5246{
5247 switch (shadertype)
5248 {
5249 case GL_VERTEX_SHADER:
5250 case GL_FRAGMENT_SHADER:
5251 break;
5252 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005253 context->handleError(InvalidOperation()
5254 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005255 return false;
5256 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005257 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005258 return false;
5259 }
5260
5261 switch (precisiontype)
5262 {
5263 case GL_LOW_FLOAT:
5264 case GL_MEDIUM_FLOAT:
5265 case GL_HIGH_FLOAT:
5266 case GL_LOW_INT:
5267 case GL_MEDIUM_INT:
5268 case GL_HIGH_INT:
5269 break;
5270
5271 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005272 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005273 return false;
5274 }
5275
5276 return true;
5277}
5278
Jamie Madill5b772312018-03-08 20:28:32 -05005279bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005280 GLuint shader,
5281 GLsizei bufsize,
5282 GLsizei *length,
5283 GLchar *source)
5284{
5285 if (bufsize < 0)
5286 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005287 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005288 return false;
5289 }
5290
5291 Shader *shaderObject = GetValidShader(context, shader);
5292 if (!shaderObject)
5293 {
5294 return false;
5295 }
5296
5297 return true;
5298}
5299
Jamie Madill5b772312018-03-08 20:28:32 -05005300bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005301{
5302 if (strstr(name, "gl_") == name)
5303 {
5304 return false;
5305 }
5306
Geoff Langfc32e8b2017-05-31 14:16:59 -04005307 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5308 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005309 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005310 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005311 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005312 return false;
5313 }
5314
Jamie Madillc1d770e2017-04-13 17:31:24 -04005315 Program *programObject = GetValidProgram(context, program);
5316
5317 if (!programObject)
5318 {
5319 return false;
5320 }
5321
5322 if (!programObject->isLinked())
5323 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005324 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005325 return false;
5326 }
5327
5328 return true;
5329}
5330
Jamie Madill5b772312018-03-08 20:28:32 -05005331bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005332{
5333 switch (mode)
5334 {
5335 case GL_FASTEST:
5336 case GL_NICEST:
5337 case GL_DONT_CARE:
5338 break;
5339
5340 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005341 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005342 return false;
5343 }
5344
5345 switch (target)
5346 {
5347 case GL_GENERATE_MIPMAP_HINT:
5348 break;
5349
Geoff Lange7bd2182017-06-16 16:13:13 -04005350 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5351 if (context->getClientVersion() < ES_3_0 &&
5352 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005353 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005354 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005355 return false;
5356 }
5357 break;
5358
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005359 case GL_PERSPECTIVE_CORRECTION_HINT:
5360 case GL_POINT_SMOOTH_HINT:
5361 case GL_LINE_SMOOTH_HINT:
5362 case GL_FOG_HINT:
5363 if (context->getClientMajorVersion() >= 2)
5364 {
5365 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5366 return false;
5367 }
5368 break;
5369
Jamie Madillc1d770e2017-04-13 17:31:24 -04005370 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005371 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005372 return false;
5373 }
5374
5375 return true;
5376}
5377
Jamie Madill5b772312018-03-08 20:28:32 -05005378bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005379{
5380 return true;
5381}
5382
Jamie Madill5b772312018-03-08 20:28:32 -05005383bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005384{
5385 return true;
5386}
5387
Jamie Madill5b772312018-03-08 20:28:32 -05005388bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005389{
5390 return true;
5391}
5392
Jamie Madill5b772312018-03-08 20:28:32 -05005393bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005394{
5395 return true;
5396}
5397
Jamie Madill5b772312018-03-08 20:28:32 -05005398bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005399{
5400 return true;
5401}
5402
Jamie Madill5b772312018-03-08 20:28:32 -05005403bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005404{
5405 return true;
5406}
5407
Jamie Madill5b772312018-03-08 20:28:32 -05005408bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005409{
5410 if (context->getClientMajorVersion() < 3)
5411 {
5412 switch (pname)
5413 {
5414 case GL_UNPACK_IMAGE_HEIGHT:
5415 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005416 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005417 return false;
5418
5419 case GL_UNPACK_ROW_LENGTH:
5420 case GL_UNPACK_SKIP_ROWS:
5421 case GL_UNPACK_SKIP_PIXELS:
5422 if (!context->getExtensions().unpackSubimage)
5423 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005424 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005425 return false;
5426 }
5427 break;
5428
5429 case GL_PACK_ROW_LENGTH:
5430 case GL_PACK_SKIP_ROWS:
5431 case GL_PACK_SKIP_PIXELS:
5432 if (!context->getExtensions().packSubimage)
5433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005434 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005435 return false;
5436 }
5437 break;
5438 }
5439 }
5440
5441 if (param < 0)
5442 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005443 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444 return false;
5445 }
5446
5447 switch (pname)
5448 {
5449 case GL_UNPACK_ALIGNMENT:
5450 if (param != 1 && param != 2 && param != 4 && param != 8)
5451 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005452 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005453 return false;
5454 }
5455 break;
5456
5457 case GL_PACK_ALIGNMENT:
5458 if (param != 1 && param != 2 && param != 4 && param != 8)
5459 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005460 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005461 return false;
5462 }
5463 break;
5464
5465 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005466 if (!context->getExtensions().packReverseRowOrder)
5467 {
5468 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5469 }
5470 break;
5471
Jamie Madillc1d770e2017-04-13 17:31:24 -04005472 case GL_UNPACK_ROW_LENGTH:
5473 case GL_UNPACK_IMAGE_HEIGHT:
5474 case GL_UNPACK_SKIP_IMAGES:
5475 case GL_UNPACK_SKIP_ROWS:
5476 case GL_UNPACK_SKIP_PIXELS:
5477 case GL_PACK_ROW_LENGTH:
5478 case GL_PACK_SKIP_ROWS:
5479 case GL_PACK_SKIP_PIXELS:
5480 break;
5481
5482 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005483 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005484 return false;
5485 }
5486
5487 return true;
5488}
5489
Jamie Madill5b772312018-03-08 20:28:32 -05005490bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005491{
5492 return true;
5493}
5494
Jamie Madill5b772312018-03-08 20:28:32 -05005495bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005496{
5497 return true;
5498}
5499
Jamie Madill5b772312018-03-08 20:28:32 -05005500bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005501{
5502 return true;
5503}
5504
Jamie Madill5b772312018-03-08 20:28:32 -05005505bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005506{
5507 if (width < 0 || height < 0)
5508 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005509 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005510 return false;
5511 }
5512
5513 return true;
5514}
5515
Jamie Madill5b772312018-03-08 20:28:32 -05005516bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005517 GLsizei n,
5518 const GLuint *shaders,
5519 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005520 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005521 GLsizei length)
5522{
5523 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5524 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5525 shaderBinaryFormats.end())
5526 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005527 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005528 return false;
5529 }
5530
5531 return true;
5532}
5533
Jamie Madill5b772312018-03-08 20:28:32 -05005534bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005535 GLuint shader,
5536 GLsizei count,
5537 const GLchar *const *string,
5538 const GLint *length)
5539{
5540 if (count < 0)
5541 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005542 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005543 return false;
5544 }
5545
Geoff Langfc32e8b2017-05-31 14:16:59 -04005546 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5547 // shader-related entry points
5548 if (context->getExtensions().webglCompatibility)
5549 {
5550 for (GLsizei i = 0; i < count; i++)
5551 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005552 size_t len =
5553 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005554
5555 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005556 if (!IsValidESSLShaderSourceString(string[i], len,
5557 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005558 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005559 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005560 return false;
5561 }
5562 }
5563 }
5564
Jamie Madillc1d770e2017-04-13 17:31:24 -04005565 Shader *shaderObject = GetValidShader(context, shader);
5566 if (!shaderObject)
5567 {
5568 return false;
5569 }
5570
5571 return true;
5572}
5573
Jamie Madill5b772312018-03-08 20:28:32 -05005574bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005575{
5576 if (!IsValidStencilFunc(func))
5577 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005578 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005579 return false;
5580 }
5581
5582 return true;
5583}
5584
Jamie Madill5b772312018-03-08 20:28:32 -05005585bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005586{
5587 if (!IsValidStencilFace(face))
5588 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005589 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005590 return false;
5591 }
5592
5593 if (!IsValidStencilFunc(func))
5594 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005595 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596 return false;
5597 }
5598
5599 return true;
5600}
5601
Jamie Madill5b772312018-03-08 20:28:32 -05005602bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005603{
5604 return true;
5605}
5606
Jamie Madill5b772312018-03-08 20:28:32 -05005607bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005608{
5609 if (!IsValidStencilFace(face))
5610 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005611 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005612 return false;
5613 }
5614
5615 return true;
5616}
5617
Jamie Madill5b772312018-03-08 20:28:32 -05005618bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005619{
5620 if (!IsValidStencilOp(fail))
5621 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005622 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005623 return false;
5624 }
5625
5626 if (!IsValidStencilOp(zfail))
5627 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005628 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629 return false;
5630 }
5631
5632 if (!IsValidStencilOp(zpass))
5633 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005634 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005635 return false;
5636 }
5637
5638 return true;
5639}
5640
Jamie Madill5b772312018-03-08 20:28:32 -05005641bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005642 GLenum face,
5643 GLenum fail,
5644 GLenum zfail,
5645 GLenum zpass)
5646{
5647 if (!IsValidStencilFace(face))
5648 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005649 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650 return false;
5651 }
5652
5653 return ValidateStencilOp(context, fail, zfail, zpass);
5654}
5655
Jamie Madill5b772312018-03-08 20:28:32 -05005656bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005657{
5658 return ValidateUniform(context, GL_FLOAT, location, 1);
5659}
5660
Jamie Madill5b772312018-03-08 20:28:32 -05005661bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005662{
5663 return ValidateUniform(context, GL_FLOAT, location, count);
5664}
5665
Jamie Madill5b772312018-03-08 20:28:32 -05005666bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005667{
5668 return ValidateUniform1iv(context, location, 1, &x);
5669}
5670
Jamie Madill5b772312018-03-08 20:28:32 -05005671bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005672{
5673 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5674}
5675
Jamie Madill5b772312018-03-08 20:28:32 -05005676bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005677{
5678 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5679}
5680
Jamie Madill5b772312018-03-08 20:28:32 -05005681bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005682{
5683 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5684}
5685
Jamie Madill5b772312018-03-08 20:28:32 -05005686bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005687{
5688 return ValidateUniform(context, GL_INT_VEC2, location, count);
5689}
5690
Jamie Madill5b772312018-03-08 20:28:32 -05005691bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005692{
5693 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5694}
5695
Jamie Madill5b772312018-03-08 20:28:32 -05005696bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005697{
5698 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5699}
5700
Jamie Madill5b772312018-03-08 20:28:32 -05005701bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005702{
5703 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5704}
5705
Jamie Madill5b772312018-03-08 20:28:32 -05005706bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005707{
5708 return ValidateUniform(context, GL_INT_VEC3, location, count);
5709}
5710
Jamie Madill5b772312018-03-08 20:28:32 -05005711bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005712{
5713 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5714}
5715
Jamie Madill5b772312018-03-08 20:28:32 -05005716bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005717{
5718 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5719}
5720
Jamie Madill5b772312018-03-08 20:28:32 -05005721bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005722{
5723 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5724}
5725
Jamie Madill5b772312018-03-08 20:28:32 -05005726bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005727{
5728 return ValidateUniform(context, GL_INT_VEC4, location, count);
5729}
5730
Jamie Madill5b772312018-03-08 20:28:32 -05005731bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005732 GLint location,
5733 GLsizei count,
5734 GLboolean transpose,
5735 const GLfloat *value)
5736{
5737 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5738}
5739
Jamie Madill5b772312018-03-08 20:28:32 -05005740bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005741 GLint location,
5742 GLsizei count,
5743 GLboolean transpose,
5744 const GLfloat *value)
5745{
5746 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5747}
5748
Jamie Madill5b772312018-03-08 20:28:32 -05005749bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005750 GLint location,
5751 GLsizei count,
5752 GLboolean transpose,
5753 const GLfloat *value)
5754{
5755 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5756}
5757
Jamie Madill5b772312018-03-08 20:28:32 -05005758bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005759{
5760 Program *programObject = GetValidProgram(context, program);
5761
5762 if (!programObject)
5763 {
5764 return false;
5765 }
5766
5767 return true;
5768}
5769
Jamie Madill5b772312018-03-08 20:28:32 -05005770bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005771{
5772 return ValidateVertexAttribIndex(context, index);
5773}
5774
Jamie Madill5b772312018-03-08 20:28:32 -05005775bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005776{
5777 return ValidateVertexAttribIndex(context, index);
5778}
5779
Jamie Madill5b772312018-03-08 20:28:32 -05005780bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005781{
5782 return ValidateVertexAttribIndex(context, index);
5783}
5784
Jamie Madill5b772312018-03-08 20:28:32 -05005785bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005786{
5787 return ValidateVertexAttribIndex(context, index);
5788}
5789
Jamie Madill5b772312018-03-08 20:28:32 -05005790bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005791{
5792 return ValidateVertexAttribIndex(context, index);
5793}
5794
Jamie Madill5b772312018-03-08 20:28:32 -05005795bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005796{
5797 return ValidateVertexAttribIndex(context, index);
5798}
5799
Jamie Madill5b772312018-03-08 20:28:32 -05005800bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005801 GLuint index,
5802 GLfloat x,
5803 GLfloat y,
5804 GLfloat z,
5805 GLfloat w)
5806{
5807 return ValidateVertexAttribIndex(context, index);
5808}
5809
Jamie Madill5b772312018-03-08 20:28:32 -05005810bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005811{
5812 return ValidateVertexAttribIndex(context, index);
5813}
5814
Jamie Madill5b772312018-03-08 20:28:32 -05005815bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005816{
5817 if (width < 0 || height < 0)
5818 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005819 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005820 return false;
5821 }
5822
5823 return true;
5824}
5825
Jamie Madill493f9572018-05-24 19:52:15 -04005826bool ValidateDrawArrays(Context *context, PrimitiveMode mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005827{
5828 return ValidateDrawArraysCommon(context, mode, first, count, 1);
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