blob: 27d0d3be16bc942fb9b4faf418944919b005d6f0 [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 Yang13b708f2018-03-21 12:14:10 -0700801 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700802 case GL_POINT_SIZE_ARRAY_OES:
803 return context->getClientVersion() < Version(2, 0) &&
804 context->getExtensions().pointSizeArray;
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700805
Jamie Madillbe849e42017-05-02 15:49:00 -0400806 default:
807 return false;
808 }
809}
810
Geoff Langfc32e8b2017-05-31 14:16:59 -0400811// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
812// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400813bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400814{
815 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400816 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
817 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400818 {
819 return true;
820 }
821
822 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
823 if (c >= 9 && c <= 13)
824 {
825 return true;
826 }
827
828 return false;
829}
830
Geoff Langcab92ee2017-07-19 17:32:07 -0400831bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400832{
Geoff Langa71a98e2017-06-19 15:15:00 -0400833 for (size_t i = 0; i < len; i++)
834 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400835 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400836 {
837 return false;
838 }
839 }
840
841 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400842}
843
Geoff Langcab92ee2017-07-19 17:32:07 -0400844bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
845{
846 enum class ParseState
847 {
848 // Have not seen an ASCII non-whitespace character yet on
849 // this line. Possible that we might see a preprocessor
850 // directive.
851 BEGINING_OF_LINE,
852
853 // Have seen at least one ASCII non-whitespace character
854 // on this line.
855 MIDDLE_OF_LINE,
856
857 // Handling a preprocessor directive. Passes through all
858 // characters up to the end of the line. Disables comment
859 // processing.
860 IN_PREPROCESSOR_DIRECTIVE,
861
862 // Handling a single-line comment. The comment text is
863 // replaced with a single space.
864 IN_SINGLE_LINE_COMMENT,
865
866 // Handling a multi-line comment. Newlines are passed
867 // through to preserve line numbers.
868 IN_MULTI_LINE_COMMENT
869 };
870
871 ParseState state = ParseState::BEGINING_OF_LINE;
872 size_t pos = 0;
873
874 while (pos < len)
875 {
876 char c = str[pos];
877 char next = pos + 1 < len ? str[pos + 1] : 0;
878
879 // Check for newlines
880 if (c == '\n' || c == '\r')
881 {
882 if (state != ParseState::IN_MULTI_LINE_COMMENT)
883 {
884 state = ParseState::BEGINING_OF_LINE;
885 }
886
887 pos++;
888 continue;
889 }
890
891 switch (state)
892 {
893 case ParseState::BEGINING_OF_LINE:
894 if (c == ' ')
895 {
896 // Maintain the BEGINING_OF_LINE state until a non-space is seen
897 pos++;
898 }
899 else if (c == '#')
900 {
901 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
902 pos++;
903 }
904 else
905 {
906 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
907 state = ParseState::MIDDLE_OF_LINE;
908 }
909 break;
910
911 case ParseState::MIDDLE_OF_LINE:
912 if (c == '/' && next == '/')
913 {
914 state = ParseState::IN_SINGLE_LINE_COMMENT;
915 pos++;
916 }
917 else if (c == '/' && next == '*')
918 {
919 state = ParseState::IN_MULTI_LINE_COMMENT;
920 pos++;
921 }
922 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
923 {
924 // Skip line continuation characters
925 }
926 else if (!IsValidESSLCharacter(c))
927 {
928 return false;
929 }
930 pos++;
931 break;
932
933 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700934 // Line-continuation characters may not be permitted.
935 // Otherwise, just pass it through. Do not parse comments in this state.
936 if (!lineContinuationAllowed && c == '\\')
937 {
938 return false;
939 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400940 pos++;
941 break;
942
943 case ParseState::IN_SINGLE_LINE_COMMENT:
944 // Line-continuation characters are processed before comment processing.
945 // Advance string if a new line character is immediately behind
946 // line-continuation character.
947 if (c == '\\' && (next == '\n' || next == '\r'))
948 {
949 pos++;
950 }
951 pos++;
952 break;
953
954 case ParseState::IN_MULTI_LINE_COMMENT:
955 if (c == '*' && next == '/')
956 {
957 state = ParseState::MIDDLE_OF_LINE;
958 pos++;
959 }
960 pos++;
961 break;
962 }
963 }
964
965 return true;
966}
967
Jamie Madill5b772312018-03-08 20:28:32 -0500968bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700969{
970 ASSERT(context->isWebGL());
971
972 // WebGL 1.0 [Section 6.16] GLSL Constructs
973 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
974 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
975 {
976 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
977 return false;
978 }
979
980 return true;
981}
982
Jamie Madill5b772312018-03-08 20:28:32 -0500983bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700984{
985 ASSERT(context->isWebGL());
986
987 if (context->isWebGL1() && length > 256)
988 {
989 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
990 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
991 // locations.
992 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
993
994 return false;
995 }
996 else if (length > 1024)
997 {
998 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
999 // uniform and attribute locations.
1000 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1001 return false;
1002 }
1003
1004 return true;
1005}
1006
Jamie Madill007530e2017-12-28 14:27:04 -05001007bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1008{
1009 if (!context->getExtensions().pathRendering)
1010 {
1011 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1012 return false;
1013 }
1014
1015 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1016 {
1017 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1018 return false;
1019 }
1020 return true;
1021}
Jamie Madillc29968b2016-01-20 11:17:23 -05001022} // anonymous namespace
1023
Geoff Langff5b2d52016-09-07 11:32:23 -04001024bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001025 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001026 GLint level,
1027 GLenum internalformat,
1028 bool isCompressed,
1029 bool isSubImage,
1030 GLint xoffset,
1031 GLint yoffset,
1032 GLsizei width,
1033 GLsizei height,
1034 GLint border,
1035 GLenum format,
1036 GLenum type,
1037 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001038 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001039{
Jamie Madill6f38f822014-06-06 17:12:20 -04001040 if (!ValidTexture2DDestinationTarget(context, target))
1041 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001042 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001043 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001044 }
1045
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001046 TextureType texType = TextureTargetToType(target);
1047 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001049 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001050 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001051 }
1052
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001053 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001054 {
1055 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1056 return false;
1057 }
1058
1059 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001060 std::numeric_limits<GLsizei>::max() - yoffset < height)
1061 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001062 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001063 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001064 }
1065
Geoff Lang6e898aa2017-06-02 11:17:26 -04001066 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1067 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1068 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1069 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1070 // case.
1071 bool nonEqualFormatsAllowed =
1072 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1073 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1074
1075 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001076 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001077 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001078 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001079 }
1080
Geoff Langaae65a42014-05-26 12:43:44 -04001081 const gl::Caps &caps = context->getCaps();
1082
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001083 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001084 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001085 case TextureType::_2D:
1086 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1087 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1088 {
1089 context->handleError(InvalidValue());
1090 return false;
1091 }
1092 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001093
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001094 case TextureType::Rectangle:
1095 ASSERT(level == 0);
1096 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1097 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1098 {
1099 context->handleError(InvalidValue());
1100 return false;
1101 }
1102 if (isCompressed)
1103 {
1104 context->handleError(InvalidEnum()
1105 << "Rectangle texture cannot have a compressed format.");
1106 return false;
1107 }
1108 break;
1109
1110 case TextureType::CubeMap:
1111 if (!isSubImage && width != height)
1112 {
1113 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1114 return false;
1115 }
1116
1117 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1118 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1119 {
1120 context->handleError(InvalidValue());
1121 return false;
1122 }
1123 break;
1124
1125 default:
1126 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001127 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001128 }
1129
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001130 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001131 if (!texture)
1132 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001133 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001134 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001135 }
1136
Geoff Langa9be0dc2014-12-17 12:34:40 -05001137 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001138 {
Geoff Langca271392017-04-05 12:30:00 -04001139 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1140 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001141 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001142 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001143 return false;
1144 }
1145
Geoff Langa9be0dc2014-12-17 12:34:40 -05001146 if (format != GL_NONE)
1147 {
Geoff Langca271392017-04-05 12:30:00 -04001148 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1149 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001150 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001152 return false;
1153 }
1154 }
1155
1156 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1157 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1158 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001159 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001160 return false;
1161 }
Geoff Langfb052642017-10-24 13:42:09 -04001162
1163 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001164 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001165 {
1166 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1167 return false;
1168 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001169 }
1170 else
1171 {
Geoff Lang69cce582015-09-17 13:20:36 -04001172 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001174 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001175 return false;
1176 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001177 }
1178
1179 // Verify zero border
1180 if (border != 0)
1181 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001182 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001183 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184 }
1185
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001186 if (isCompressed)
1187 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001188 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001189 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1190 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001191 switch (actualInternalFormat)
1192 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001193 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1194 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1195 if (!context->getExtensions().textureCompressionDXT1)
1196 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001197 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001198 return false;
1199 }
1200 break;
1201 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001202 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001203 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001204 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001205 return false;
1206 }
1207 break;
1208 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1209 if (!context->getExtensions().textureCompressionDXT5)
1210 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001211 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001212 return false;
1213 }
1214 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001215 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1216 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1217 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1218 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1219 if (!context->getExtensions().textureCompressionS3TCsRGB)
1220 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001221 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001222 return false;
1223 }
1224 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001225 case GL_ETC1_RGB8_OES:
1226 if (!context->getExtensions().compressedETC1RGB8Texture)
1227 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001228 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001229 return false;
1230 }
Geoff Lang86f81162017-10-30 15:10:45 -04001231 if (isSubImage)
1232 {
1233 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1234 return false;
1235 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001236 break;
1237 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001238 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1239 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1240 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1241 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001242 if (!context->getExtensions().lossyETCDecode)
1243 {
Geoff Lang86f81162017-10-30 15:10:45 -04001244 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001245 return false;
1246 }
1247 break;
1248 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001249 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001250 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001251 }
Geoff Lang966c9402017-04-18 12:38:27 -04001252
1253 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001254 {
Geoff Lang966c9402017-04-18 12:38:27 -04001255 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1256 height, texture->getWidth(target, level),
1257 texture->getHeight(target, level)))
1258 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001259 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001260 return false;
1261 }
1262
1263 if (format != actualInternalFormat)
1264 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001265 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001266 return false;
1267 }
1268 }
1269 else
1270 {
1271 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1272 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001273 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001274 return false;
1275 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001276 }
1277 }
1278 else
1279 {
1280 // validate <type> by itself (used as secondary key below)
1281 switch (type)
1282 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001283 case GL_UNSIGNED_BYTE:
1284 case GL_UNSIGNED_SHORT_5_6_5:
1285 case GL_UNSIGNED_SHORT_4_4_4_4:
1286 case GL_UNSIGNED_SHORT_5_5_5_1:
1287 case GL_UNSIGNED_SHORT:
1288 case GL_UNSIGNED_INT:
1289 case GL_UNSIGNED_INT_24_8_OES:
1290 case GL_HALF_FLOAT_OES:
1291 case GL_FLOAT:
1292 break;
1293 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001294 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001295 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001296 }
1297
1298 // validate <format> + <type> combinations
1299 // - invalid <format> -> sets INVALID_ENUM
1300 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1301 switch (format)
1302 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 case GL_ALPHA:
1304 case GL_LUMINANCE:
1305 case GL_LUMINANCE_ALPHA:
1306 switch (type)
1307 {
1308 case GL_UNSIGNED_BYTE:
1309 case GL_FLOAT:
1310 case GL_HALF_FLOAT_OES:
1311 break;
1312 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001313 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001314 return false;
1315 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001316 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001317 case GL_RED:
1318 case GL_RG:
1319 if (!context->getExtensions().textureRG)
1320 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001321 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001322 return false;
1323 }
1324 switch (type)
1325 {
1326 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001327 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001328 case GL_FLOAT:
1329 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001330 if (!context->getExtensions().textureFloat)
1331 {
1332 context->handleError(InvalidEnum());
1333 return false;
1334 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001335 break;
1336 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001337 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001338 return false;
1339 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001340 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001341 case GL_RGB:
1342 switch (type)
1343 {
1344 case GL_UNSIGNED_BYTE:
1345 case GL_UNSIGNED_SHORT_5_6_5:
1346 case GL_FLOAT:
1347 case GL_HALF_FLOAT_OES:
1348 break;
1349 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001351 return false;
1352 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001353 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001354 case GL_RGBA:
1355 switch (type)
1356 {
1357 case GL_UNSIGNED_BYTE:
1358 case GL_UNSIGNED_SHORT_4_4_4_4:
1359 case GL_UNSIGNED_SHORT_5_5_5_1:
1360 case GL_FLOAT:
1361 case GL_HALF_FLOAT_OES:
1362 break;
1363 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001365 return false;
1366 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001367 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001368 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001369 if (!context->getExtensions().textureFormatBGRA8888)
1370 {
1371 context->handleError(InvalidEnum());
1372 return false;
1373 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001374 switch (type)
1375 {
1376 case GL_UNSIGNED_BYTE:
1377 break;
1378 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001379 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001380 return false;
1381 }
1382 break;
1383 case GL_SRGB_EXT:
1384 case GL_SRGB_ALPHA_EXT:
1385 if (!context->getExtensions().sRGB)
1386 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001387 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001388 return false;
1389 }
1390 switch (type)
1391 {
1392 case GL_UNSIGNED_BYTE:
1393 break;
1394 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001396 return false;
1397 }
1398 break;
1399 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1400 // handled below
1401 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1402 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1403 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1404 break;
1405 case GL_DEPTH_COMPONENT:
1406 switch (type)
1407 {
1408 case GL_UNSIGNED_SHORT:
1409 case GL_UNSIGNED_INT:
1410 break;
1411 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001412 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001413 return false;
1414 }
1415 break;
1416 case GL_DEPTH_STENCIL_OES:
1417 switch (type)
1418 {
1419 case GL_UNSIGNED_INT_24_8_OES:
1420 break;
1421 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001422 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001423 return false;
1424 }
1425 break;
1426 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001427 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001428 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001429 }
1430
1431 switch (format)
1432 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1434 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1435 if (context->getExtensions().textureCompressionDXT1)
1436 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001437 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001438 return false;
1439 }
1440 else
1441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001442 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 break;
1446 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1447 if (context->getExtensions().textureCompressionDXT3)
1448 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001449 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001450 return false;
1451 }
1452 else
1453 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001454 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001455 return false;
1456 }
1457 break;
1458 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1459 if (context->getExtensions().textureCompressionDXT5)
1460 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001461 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001462 return false;
1463 }
1464 else
1465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001466 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 return false;
1468 }
1469 break;
1470 case GL_ETC1_RGB8_OES:
1471 if (context->getExtensions().compressedETC1RGB8Texture)
1472 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001473 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001474 return false;
1475 }
1476 else
1477 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001478 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001479 return false;
1480 }
1481 break;
1482 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001483 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1484 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1485 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1486 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 if (context->getExtensions().lossyETCDecode)
1488 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001489 context->handleError(InvalidOperation()
1490 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001491 return false;
1492 }
1493 else
1494 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001495 context->handleError(InvalidEnum()
1496 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 return false;
1498 }
1499 break;
1500 case GL_DEPTH_COMPONENT:
1501 case GL_DEPTH_STENCIL_OES:
1502 if (!context->getExtensions().depthTextures)
1503 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001504 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001505 return false;
1506 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001507 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001508 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001509 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001510 return false;
1511 }
1512 // OES_depth_texture supports loading depth data and multiple levels,
1513 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001514 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001515 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001516 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1517 return false;
1518 }
1519 if (level != 0)
1520 {
1521 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001522 return false;
1523 }
1524 break;
1525 default:
1526 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001527 }
1528
Geoff Lang6e898aa2017-06-02 11:17:26 -04001529 if (!isSubImage)
1530 {
1531 switch (internalformat)
1532 {
1533 case GL_RGBA32F:
1534 if (!context->getExtensions().colorBufferFloatRGBA)
1535 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001536 context->handleError(InvalidValue()
1537 << "Sized GL_RGBA32F internal format requires "
1538 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001539 return false;
1540 }
1541 if (type != GL_FLOAT)
1542 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001544 return false;
1545 }
1546 if (format != GL_RGBA)
1547 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001548 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001549 return false;
1550 }
1551 break;
1552
1553 case GL_RGB32F:
1554 if (!context->getExtensions().colorBufferFloatRGB)
1555 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001556 context->handleError(InvalidValue()
1557 << "Sized GL_RGB32F internal format requires "
1558 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001559 return false;
1560 }
1561 if (type != GL_FLOAT)
1562 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001563 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001564 return false;
1565 }
1566 if (format != GL_RGB)
1567 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001568 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001569 return false;
1570 }
1571 break;
1572
1573 default:
1574 break;
1575 }
1576 }
1577
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001578 if (type == GL_FLOAT)
1579 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001580 if (!context->getExtensions().textureFloat)
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 else if (type == GL_HALF_FLOAT_OES)
1587 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001588 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001589 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001590 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001591 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001592 }
1593 }
1594 }
1595
Geoff Langdbcced82017-06-06 15:55:54 -04001596 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001597 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001598 imageSize))
1599 {
1600 return false;
1601 }
1602
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001603 return true;
1604}
1605
He Yunchaoced53ae2016-11-29 15:00:51 +08001606bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001607 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001608 GLsizei levels,
1609 GLenum internalformat,
1610 GLsizei width,
1611 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001612{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001613 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1614 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001615 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001616 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001617 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001618 }
1619
1620 if (width < 1 || height < 1 || levels < 1)
1621 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001622 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001623 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001624 }
1625
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001626 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001627 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001628 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001629 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001630 }
1631
1632 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1633 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001634 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001635 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 }
1637
Geoff Langca271392017-04-05 12:30:00 -04001638 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001639 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001640 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001641 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001642 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001643 }
1644
Geoff Langaae65a42014-05-26 12:43:44 -04001645 const gl::Caps &caps = context->getCaps();
1646
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001647 switch (target)
1648 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001649 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001650 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1651 static_cast<GLuint>(height) > caps.max2DTextureSize)
1652 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001653 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001654 return false;
1655 }
1656 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001657 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001658 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1659 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1660 {
1661 context->handleError(InvalidValue());
1662 return false;
1663 }
1664 if (formatInfo.compressed)
1665 {
1666 context->handleError(InvalidEnum()
1667 << "Rectangle texture cannot have a compressed format.");
1668 return false;
1669 }
1670 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001671 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001672 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1673 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1674 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001675 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001676 return false;
1677 }
1678 break;
1679 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001680 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001681 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001682 }
1683
Geoff Langc0b9ef42014-07-02 10:02:37 -04001684 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001685 {
1686 if (!gl::isPow2(width) || !gl::isPow2(height))
1687 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001688 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001689 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001690 }
1691 }
1692
1693 switch (internalformat)
1694 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001695 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1696 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1697 if (!context->getExtensions().textureCompressionDXT1)
1698 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001699 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001700 return false;
1701 }
1702 break;
1703 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1704 if (!context->getExtensions().textureCompressionDXT3)
1705 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001706 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001707 return false;
1708 }
1709 break;
1710 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1711 if (!context->getExtensions().textureCompressionDXT5)
1712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001713 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001714 return false;
1715 }
1716 break;
1717 case GL_ETC1_RGB8_OES:
1718 if (!context->getExtensions().compressedETC1RGB8Texture)
1719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001720 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001721 return false;
1722 }
1723 break;
1724 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001725 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1726 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1727 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1728 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001729 if (!context->getExtensions().lossyETCDecode)
1730 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001731 context->handleError(InvalidEnum()
1732 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001733 return false;
1734 }
1735 break;
1736 case GL_RGBA32F_EXT:
1737 case GL_RGB32F_EXT:
1738 case GL_ALPHA32F_EXT:
1739 case GL_LUMINANCE32F_EXT:
1740 case GL_LUMINANCE_ALPHA32F_EXT:
1741 if (!context->getExtensions().textureFloat)
1742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001743 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001744 return false;
1745 }
1746 break;
1747 case GL_RGBA16F_EXT:
1748 case GL_RGB16F_EXT:
1749 case GL_ALPHA16F_EXT:
1750 case GL_LUMINANCE16F_EXT:
1751 case GL_LUMINANCE_ALPHA16F_EXT:
1752 if (!context->getExtensions().textureHalfFloat)
1753 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001754 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001755 return false;
1756 }
1757 break;
1758 case GL_R8_EXT:
1759 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001760 if (!context->getExtensions().textureRG)
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_R16F_EXT:
1767 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001768 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1769 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001770 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001771 return false;
1772 }
1773 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001774 case GL_R32F_EXT:
1775 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001776 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001777 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001778 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001779 return false;
1780 }
1781 break;
1782 case GL_DEPTH_COMPONENT16:
1783 case GL_DEPTH_COMPONENT32_OES:
1784 case GL_DEPTH24_STENCIL8_OES:
1785 if (!context->getExtensions().depthTextures)
1786 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001787 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001788 return false;
1789 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001790 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001791 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001792 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001793 return false;
1794 }
1795 // ANGLE_depth_texture only supports 1-level textures
1796 if (levels != 1)
1797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001798 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001799 return false;
1800 }
1801 break;
1802 default:
1803 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001804 }
1805
Geoff Lang691e58c2014-12-19 17:03:25 -05001806 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001807 if (!texture || texture->id() == 0)
1808 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001809 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001810 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001811 }
1812
Geoff Lang69cce582015-09-17 13:20:36 -04001813 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001814 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001815 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001816 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001817 }
1818
1819 return true;
1820}
1821
He Yunchaoced53ae2016-11-29 15:00:51 +08001822bool ValidateDiscardFramebufferEXT(Context *context,
1823 GLenum target,
1824 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001825 const GLenum *attachments)
1826{
Jamie Madillc29968b2016-01-20 11:17:23 -05001827 if (!context->getExtensions().discardFramebuffer)
1828 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001829 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001830 return false;
1831 }
1832
Austin Kinross08332632015-05-05 13:35:47 -07001833 bool defaultFramebuffer = false;
1834
1835 switch (target)
1836 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001837 case GL_FRAMEBUFFER:
1838 defaultFramebuffer =
1839 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1840 break;
1841 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001842 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001843 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001844 }
1845
He Yunchaoced53ae2016-11-29 15:00:51 +08001846 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1847 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001848}
1849
Austin Kinrossbc781f32015-10-26 09:27:38 -07001850bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1851{
1852 if (!context->getExtensions().vertexArrayObject)
1853 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001854 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001855 return false;
1856 }
1857
1858 return ValidateBindVertexArrayBase(context, array);
1859}
1860
Jamie Madilld7576732017-08-26 18:49:50 -04001861bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001862{
1863 if (!context->getExtensions().vertexArrayObject)
1864 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001865 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001866 return false;
1867 }
1868
Olli Etuaho41997e72016-03-10 13:38:39 +02001869 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870}
1871
Jamie Madilld7576732017-08-26 18:49:50 -04001872bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001873{
1874 if (!context->getExtensions().vertexArrayObject)
1875 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001876 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001877 return false;
1878 }
1879
Olli Etuaho41997e72016-03-10 13:38:39 +02001880 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001881}
1882
Jamie Madilld7576732017-08-26 18:49:50 -04001883bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001884{
1885 if (!context->getExtensions().vertexArrayObject)
1886 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001887 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001888 return false;
1889 }
1890
1891 return true;
1892}
Geoff Langc5629752015-12-07 16:29:04 -05001893
1894bool ValidateProgramBinaryOES(Context *context,
1895 GLuint program,
1896 GLenum binaryFormat,
1897 const void *binary,
1898 GLint length)
1899{
1900 if (!context->getExtensions().getProgramBinary)
1901 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001902 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001903 return false;
1904 }
1905
1906 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1907}
1908
1909bool ValidateGetProgramBinaryOES(Context *context,
1910 GLuint program,
1911 GLsizei bufSize,
1912 GLsizei *length,
1913 GLenum *binaryFormat,
1914 void *binary)
1915{
1916 if (!context->getExtensions().getProgramBinary)
1917 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001918 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001919 return false;
1920 }
1921
1922 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1923}
Geoff Lange102fee2015-12-10 11:23:30 -05001924
Geoff Lang70d0f492015-12-10 17:45:46 -05001925static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1926{
1927 switch (source)
1928 {
1929 case GL_DEBUG_SOURCE_API:
1930 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1931 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1932 case GL_DEBUG_SOURCE_OTHER:
1933 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1934 return !mustBeThirdPartyOrApplication;
1935
1936 case GL_DEBUG_SOURCE_THIRD_PARTY:
1937 case GL_DEBUG_SOURCE_APPLICATION:
1938 return true;
1939
1940 default:
1941 return false;
1942 }
1943}
1944
1945static bool ValidDebugType(GLenum type)
1946{
1947 switch (type)
1948 {
1949 case GL_DEBUG_TYPE_ERROR:
1950 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1951 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1952 case GL_DEBUG_TYPE_PERFORMANCE:
1953 case GL_DEBUG_TYPE_PORTABILITY:
1954 case GL_DEBUG_TYPE_OTHER:
1955 case GL_DEBUG_TYPE_MARKER:
1956 case GL_DEBUG_TYPE_PUSH_GROUP:
1957 case GL_DEBUG_TYPE_POP_GROUP:
1958 return true;
1959
1960 default:
1961 return false;
1962 }
1963}
1964
1965static bool ValidDebugSeverity(GLenum severity)
1966{
1967 switch (severity)
1968 {
1969 case GL_DEBUG_SEVERITY_HIGH:
1970 case GL_DEBUG_SEVERITY_MEDIUM:
1971 case GL_DEBUG_SEVERITY_LOW:
1972 case GL_DEBUG_SEVERITY_NOTIFICATION:
1973 return true;
1974
1975 default:
1976 return false;
1977 }
1978}
1979
Geoff Lange102fee2015-12-10 11:23:30 -05001980bool ValidateDebugMessageControlKHR(Context *context,
1981 GLenum source,
1982 GLenum type,
1983 GLenum severity,
1984 GLsizei count,
1985 const GLuint *ids,
1986 GLboolean enabled)
1987{
1988 if (!context->getExtensions().debug)
1989 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001990 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001991 return false;
1992 }
1993
Geoff Lang70d0f492015-12-10 17:45:46 -05001994 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1995 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001996 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001997 return false;
1998 }
1999
2000 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2001 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002002 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002003 return false;
2004 }
2005
2006 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2007 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002008 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002009 return false;
2010 }
2011
2012 if (count > 0)
2013 {
2014 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2015 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002016 context->handleError(
2017 InvalidOperation()
2018 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002019 return false;
2020 }
2021
2022 if (severity != GL_DONT_CARE)
2023 {
Jamie Madill437fa652016-05-03 15:13:24 -04002024 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002025 InvalidOperation()
2026 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002027 return false;
2028 }
2029 }
2030
Geoff Lange102fee2015-12-10 11:23:30 -05002031 return true;
2032}
2033
2034bool ValidateDebugMessageInsertKHR(Context *context,
2035 GLenum source,
2036 GLenum type,
2037 GLuint id,
2038 GLenum severity,
2039 GLsizei length,
2040 const GLchar *buf)
2041{
2042 if (!context->getExtensions().debug)
2043 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002044 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002045 return false;
2046 }
2047
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002048 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002049 {
2050 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2051 // not generate an error.
2052 return false;
2053 }
2054
2055 if (!ValidDebugSeverity(severity))
2056 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002057 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002058 return false;
2059 }
2060
2061 if (!ValidDebugType(type))
2062 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002063 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002064 return false;
2065 }
2066
2067 if (!ValidDebugSource(source, true))
2068 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002069 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002070 return false;
2071 }
2072
2073 size_t messageLength = (length < 0) ? strlen(buf) : length;
2074 if (messageLength > context->getExtensions().maxDebugMessageLength)
2075 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002076 context->handleError(InvalidValue()
2077 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002078 return false;
2079 }
2080
Geoff Lange102fee2015-12-10 11:23:30 -05002081 return true;
2082}
2083
2084bool ValidateDebugMessageCallbackKHR(Context *context,
2085 GLDEBUGPROCKHR callback,
2086 const void *userParam)
2087{
2088 if (!context->getExtensions().debug)
2089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002090 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002091 return false;
2092 }
2093
Geoff Lange102fee2015-12-10 11:23:30 -05002094 return true;
2095}
2096
2097bool ValidateGetDebugMessageLogKHR(Context *context,
2098 GLuint count,
2099 GLsizei bufSize,
2100 GLenum *sources,
2101 GLenum *types,
2102 GLuint *ids,
2103 GLenum *severities,
2104 GLsizei *lengths,
2105 GLchar *messageLog)
2106{
2107 if (!context->getExtensions().debug)
2108 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002109 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002110 return false;
2111 }
2112
Geoff Lang70d0f492015-12-10 17:45:46 -05002113 if (bufSize < 0 && messageLog != nullptr)
2114 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002115 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002116 return false;
2117 }
2118
Geoff Lange102fee2015-12-10 11:23:30 -05002119 return true;
2120}
2121
2122bool ValidatePushDebugGroupKHR(Context *context,
2123 GLenum source,
2124 GLuint id,
2125 GLsizei length,
2126 const GLchar *message)
2127{
2128 if (!context->getExtensions().debug)
2129 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002130 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002131 return false;
2132 }
2133
Geoff Lang70d0f492015-12-10 17:45:46 -05002134 if (!ValidDebugSource(source, true))
2135 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002136 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002137 return false;
2138 }
2139
2140 size_t messageLength = (length < 0) ? strlen(message) : length;
2141 if (messageLength > context->getExtensions().maxDebugMessageLength)
2142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002143 context->handleError(InvalidValue()
2144 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002145 return false;
2146 }
2147
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002148 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002149 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2150 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002151 context
2152 ->handleError(StackOverflow()
2153 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002154 return false;
2155 }
2156
Geoff Lange102fee2015-12-10 11:23:30 -05002157 return true;
2158}
2159
2160bool ValidatePopDebugGroupKHR(Context *context)
2161{
2162 if (!context->getExtensions().debug)
2163 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002164 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002165 return false;
2166 }
2167
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002168 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002169 if (currentStackSize <= 1)
2170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002171 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002172 return false;
2173 }
2174
2175 return true;
2176}
2177
2178static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2179{
2180 switch (identifier)
2181 {
2182 case GL_BUFFER:
2183 if (context->getBuffer(name) == nullptr)
2184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002185 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002186 return false;
2187 }
2188 return true;
2189
2190 case GL_SHADER:
2191 if (context->getShader(name) == nullptr)
2192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002193 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002194 return false;
2195 }
2196 return true;
2197
2198 case GL_PROGRAM:
2199 if (context->getProgram(name) == nullptr)
2200 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002201 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002202 return false;
2203 }
2204 return true;
2205
2206 case GL_VERTEX_ARRAY:
2207 if (context->getVertexArray(name) == nullptr)
2208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002209 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002210 return false;
2211 }
2212 return true;
2213
2214 case GL_QUERY:
2215 if (context->getQuery(name) == nullptr)
2216 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002217 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002218 return false;
2219 }
2220 return true;
2221
2222 case GL_TRANSFORM_FEEDBACK:
2223 if (context->getTransformFeedback(name) == nullptr)
2224 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002225 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002226 return false;
2227 }
2228 return true;
2229
2230 case GL_SAMPLER:
2231 if (context->getSampler(name) == nullptr)
2232 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002233 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002234 return false;
2235 }
2236 return true;
2237
2238 case GL_TEXTURE:
2239 if (context->getTexture(name) == nullptr)
2240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002241 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002242 return false;
2243 }
2244 return true;
2245
2246 case GL_RENDERBUFFER:
2247 if (context->getRenderbuffer(name) == nullptr)
2248 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002249 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002250 return false;
2251 }
2252 return true;
2253
2254 case GL_FRAMEBUFFER:
2255 if (context->getFramebuffer(name) == nullptr)
2256 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002257 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002258 return false;
2259 }
2260 return true;
2261
2262 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002263 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002264 return false;
2265 }
Geoff Lange102fee2015-12-10 11:23:30 -05002266}
2267
Martin Radev9d901792016-07-15 15:58:58 +03002268static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2269{
2270 size_t labelLength = 0;
2271
2272 if (length < 0)
2273 {
2274 if (label != nullptr)
2275 {
2276 labelLength = strlen(label);
2277 }
2278 }
2279 else
2280 {
2281 labelLength = static_cast<size_t>(length);
2282 }
2283
2284 if (labelLength > context->getExtensions().maxLabelLength)
2285 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002286 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002287 return false;
2288 }
2289
2290 return true;
2291}
2292
Geoff Lange102fee2015-12-10 11:23:30 -05002293bool ValidateObjectLabelKHR(Context *context,
2294 GLenum identifier,
2295 GLuint name,
2296 GLsizei length,
2297 const GLchar *label)
2298{
2299 if (!context->getExtensions().debug)
2300 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002301 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002302 return false;
2303 }
2304
Geoff Lang70d0f492015-12-10 17:45:46 -05002305 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2306 {
2307 return false;
2308 }
2309
Martin Radev9d901792016-07-15 15:58:58 +03002310 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002311 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002312 return false;
2313 }
2314
Geoff Lange102fee2015-12-10 11:23:30 -05002315 return true;
2316}
2317
2318bool ValidateGetObjectLabelKHR(Context *context,
2319 GLenum identifier,
2320 GLuint name,
2321 GLsizei bufSize,
2322 GLsizei *length,
2323 GLchar *label)
2324{
2325 if (!context->getExtensions().debug)
2326 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002327 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002328 return false;
2329 }
2330
Geoff Lang70d0f492015-12-10 17:45:46 -05002331 if (bufSize < 0)
2332 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002333 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002334 return false;
2335 }
2336
2337 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2338 {
2339 return false;
2340 }
2341
Martin Radev9d901792016-07-15 15:58:58 +03002342 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002343}
2344
2345static bool ValidateObjectPtrName(Context *context, const void *ptr)
2346{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002347 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002348 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002349 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002350 return false;
2351 }
2352
Geoff Lange102fee2015-12-10 11:23:30 -05002353 return true;
2354}
2355
2356bool ValidateObjectPtrLabelKHR(Context *context,
2357 const void *ptr,
2358 GLsizei length,
2359 const GLchar *label)
2360{
2361 if (!context->getExtensions().debug)
2362 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002363 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002364 return false;
2365 }
2366
Geoff Lang70d0f492015-12-10 17:45:46 -05002367 if (!ValidateObjectPtrName(context, ptr))
2368 {
2369 return false;
2370 }
2371
Martin Radev9d901792016-07-15 15:58:58 +03002372 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002373 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002374 return false;
2375 }
2376
Geoff Lange102fee2015-12-10 11:23:30 -05002377 return true;
2378}
2379
2380bool ValidateGetObjectPtrLabelKHR(Context *context,
2381 const void *ptr,
2382 GLsizei bufSize,
2383 GLsizei *length,
2384 GLchar *label)
2385{
2386 if (!context->getExtensions().debug)
2387 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002389 return false;
2390 }
2391
Geoff Lang70d0f492015-12-10 17:45:46 -05002392 if (bufSize < 0)
2393 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002394 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002395 return false;
2396 }
2397
2398 if (!ValidateObjectPtrName(context, ptr))
2399 {
2400 return false;
2401 }
2402
Martin Radev9d901792016-07-15 15:58:58 +03002403 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002404}
2405
2406bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2407{
2408 if (!context->getExtensions().debug)
2409 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002410 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002411 return false;
2412 }
2413
Geoff Lang70d0f492015-12-10 17:45:46 -05002414 // TODO: represent this in Context::getQueryParameterInfo.
2415 switch (pname)
2416 {
2417 case GL_DEBUG_CALLBACK_FUNCTION:
2418 case GL_DEBUG_CALLBACK_USER_PARAM:
2419 break;
2420
2421 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002422 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002423 return false;
2424 }
2425
Geoff Lange102fee2015-12-10 11:23:30 -05002426 return true;
2427}
Jamie Madillc29968b2016-01-20 11:17:23 -05002428
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002429bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2430 GLenum pname,
2431 GLsizei bufSize,
2432 GLsizei *length,
2433 void **params)
2434{
2435 UNIMPLEMENTED();
2436 return false;
2437}
2438
Jamie Madillc29968b2016-01-20 11:17:23 -05002439bool ValidateBlitFramebufferANGLE(Context *context,
2440 GLint srcX0,
2441 GLint srcY0,
2442 GLint srcX1,
2443 GLint srcY1,
2444 GLint dstX0,
2445 GLint dstY0,
2446 GLint dstX1,
2447 GLint dstY1,
2448 GLbitfield mask,
2449 GLenum filter)
2450{
2451 if (!context->getExtensions().framebufferBlit)
2452 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002453 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002454 return false;
2455 }
2456
2457 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2458 {
2459 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002460 context->handleError(InvalidOperation() << "Scaling and flipping in "
2461 "BlitFramebufferANGLE not supported by this "
2462 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002463 return false;
2464 }
2465
2466 if (filter == GL_LINEAR)
2467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002468 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002469 return false;
2470 }
2471
Jamie Madill51f40ec2016-06-15 14:06:00 -04002472 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2473 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002474
2475 if (mask & GL_COLOR_BUFFER_BIT)
2476 {
2477 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2478 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2479
2480 if (readColorAttachment && drawColorAttachment)
2481 {
2482 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002483 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002484 readColorAttachment->type() != GL_RENDERBUFFER &&
2485 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2486 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002487 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002488 return false;
2489 }
2490
Geoff Langa15472a2015-08-11 11:48:03 -04002491 for (size_t drawbufferIdx = 0;
2492 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002493 {
Geoff Langa15472a2015-08-11 11:48:03 -04002494 const FramebufferAttachment *attachment =
2495 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2496 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002497 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002498 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002499 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002500 attachment->type() != GL_RENDERBUFFER &&
2501 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2502 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002503 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002504 return false;
2505 }
2506
2507 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002508 if (!Format::EquivalentForBlit(attachment->getFormat(),
2509 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002510 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002511 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002512 return false;
2513 }
2514 }
2515 }
2516
Jamie Madille98b1b52018-03-08 09:47:23 -05002517 GLint samples = 0;
2518 ANGLE_VALIDATION_TRY(readFramebuffer->getSamples(context, &samples));
2519 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002520 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2521 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2522 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002523 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002524 return false;
2525 }
2526 }
2527 }
2528
2529 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2530 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2531 for (size_t i = 0; i < 2; i++)
2532 {
2533 if (mask & masks[i])
2534 {
2535 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002536 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002537 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002538 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002539
2540 if (readBuffer && drawBuffer)
2541 {
2542 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2543 dstX0, dstY0, dstX1, dstY1))
2544 {
2545 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002546 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2547 "stencil blits are supported by "
2548 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002549 return false;
2550 }
2551
2552 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2553 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002554 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002555 return false;
2556 }
2557 }
2558 }
2559 }
2560
2561 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2562 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002563}
Jamie Madillc29968b2016-01-20 11:17:23 -05002564
Jamie Madill5b772312018-03-08 20:28:32 -05002565bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002566{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002567 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002568
2569 if (!ValidateFramebufferComplete(context, fbo, true))
Jamie Madillc29968b2016-01-20 11:17:23 -05002570 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002571 return false;
2572 }
2573
2574 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2575 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002576 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002577 return false;
2578 }
2579
Geoff Lang76e65652017-03-27 14:58:02 -04002580 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2581 {
2582 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2583 GL_SIGNED_NORMALIZED};
2584
Corentin Wallez59c41592017-07-11 13:19:54 -04002585 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002586 drawBufferIdx++)
2587 {
2588 if (!ValidateWebGLFramebufferAttachmentClearType(
2589 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2590 {
2591 return false;
2592 }
2593 }
2594 }
2595
Jamie Madillc29968b2016-01-20 11:17:23 -05002596 return true;
2597}
2598
Jamie Madill5b772312018-03-08 20:28:32 -05002599bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002600{
2601 if (!context->getExtensions().drawBuffers)
2602 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002603 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002604 return false;
2605 }
2606
2607 return ValidateDrawBuffersBase(context, n, bufs);
2608}
2609
Jamie Madill73a84962016-02-12 09:27:23 -05002610bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002611 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002612 GLint level,
2613 GLint internalformat,
2614 GLsizei width,
2615 GLsizei height,
2616 GLint border,
2617 GLenum format,
2618 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002619 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002620{
Martin Radev1be913c2016-07-11 17:59:16 +03002621 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002622 {
2623 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002624 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002625 }
2626
Martin Radev1be913c2016-07-11 17:59:16 +03002627 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002628 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002629 0, 0, width, height, 1, border, format, type, -1,
2630 pixels);
2631}
2632
Brandon Jones416aaf92018-04-10 08:10:16 -07002633bool ValidateTexImage2DRobustANGLE(Context *context,
2634 TextureTarget target,
2635 GLint level,
2636 GLint internalformat,
2637 GLsizei width,
2638 GLsizei height,
2639 GLint border,
2640 GLenum format,
2641 GLenum type,
2642 GLsizei bufSize,
2643 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002644{
2645 if (!ValidateRobustEntryPoint(context, bufSize))
2646 {
2647 return false;
2648 }
2649
2650 if (context->getClientMajorVersion() < 3)
2651 {
2652 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2653 0, 0, width, height, border, format, type, bufSize,
2654 pixels);
2655 }
2656
2657 ASSERT(context->getClientMajorVersion() >= 3);
2658 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2659 0, 0, width, height, 1, border, format, type, bufSize,
2660 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002661}
2662
2663bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002664 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002665 GLint level,
2666 GLint xoffset,
2667 GLint yoffset,
2668 GLsizei width,
2669 GLsizei height,
2670 GLenum format,
2671 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002672 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002673{
2674
Martin Radev1be913c2016-07-11 17:59:16 +03002675 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002676 {
2677 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002678 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002679 }
2680
Martin Radev1be913c2016-07-11 17:59:16 +03002681 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002682 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002683 yoffset, 0, width, height, 1, 0, format, type, -1,
2684 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002685}
2686
Geoff Langc52f6f12016-10-14 10:18:00 -04002687bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002688 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002689 GLint level,
2690 GLint xoffset,
2691 GLint yoffset,
2692 GLsizei width,
2693 GLsizei height,
2694 GLenum format,
2695 GLenum type,
2696 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002697 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002698{
2699 if (!ValidateRobustEntryPoint(context, bufSize))
2700 {
2701 return false;
2702 }
2703
2704 if (context->getClientMajorVersion() < 3)
2705 {
2706 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2707 yoffset, width, height, 0, format, type, bufSize,
2708 pixels);
2709 }
2710
2711 ASSERT(context->getClientMajorVersion() >= 3);
2712 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2713 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2714 pixels);
2715}
2716
Jamie Madill73a84962016-02-12 09:27:23 -05002717bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002718 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002719 GLint level,
2720 GLenum internalformat,
2721 GLsizei width,
2722 GLsizei height,
2723 GLint border,
2724 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002725 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002726{
Martin Radev1be913c2016-07-11 17:59:16 +03002727 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002728 {
2729 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002730 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002731 {
2732 return false;
2733 }
2734 }
2735 else
2736 {
Martin Radev1be913c2016-07-11 17:59:16 +03002737 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002738 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002739 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002740 data))
2741 {
2742 return false;
2743 }
2744 }
2745
Geoff Langca271392017-04-05 12:30:00 -04002746 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002747 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002748 if (blockSizeOrErr.isError())
2749 {
2750 context->handleError(blockSizeOrErr.getError());
2751 return false;
2752 }
2753
2754 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002755 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002756 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002757 return false;
2758 }
2759
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002760 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002761 {
2762 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2763 return false;
2764 }
2765
Jamie Madill73a84962016-02-12 09:27:23 -05002766 return true;
2767}
2768
Corentin Wallezb2931602017-04-11 15:58:57 -04002769bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002770 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002771 GLint level,
2772 GLenum internalformat,
2773 GLsizei width,
2774 GLsizei height,
2775 GLint border,
2776 GLsizei imageSize,
2777 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002778 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002779{
2780 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2781 {
2782 return false;
2783 }
2784
2785 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2786 border, imageSize, data);
2787}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002788
Corentin Wallezb2931602017-04-11 15:58:57 -04002789bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002790 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002791 GLint level,
2792 GLint xoffset,
2793 GLint yoffset,
2794 GLsizei width,
2795 GLsizei height,
2796 GLenum format,
2797 GLsizei imageSize,
2798 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002799 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002800{
2801 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2802 {
2803 return false;
2804 }
2805
2806 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2807 format, imageSize, data);
2808}
2809
Jamie Madill73a84962016-02-12 09:27:23 -05002810bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002811 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002812 GLint level,
2813 GLint xoffset,
2814 GLint yoffset,
2815 GLsizei width,
2816 GLsizei height,
2817 GLenum format,
2818 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002819 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002820{
Martin Radev1be913c2016-07-11 17:59:16 +03002821 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002822 {
2823 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002824 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002825 {
2826 return false;
2827 }
2828 }
2829 else
2830 {
Martin Radev1be913c2016-07-11 17:59:16 +03002831 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002832 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002833 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002834 data))
2835 {
2836 return false;
2837 }
2838 }
2839
Geoff Langca271392017-04-05 12:30:00 -04002840 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002841 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002842 if (blockSizeOrErr.isError())
2843 {
2844 context->handleError(blockSizeOrErr.getError());
2845 return false;
2846 }
2847
2848 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002849 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002850 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002851 return false;
2852 }
2853
2854 return true;
2855}
2856
Corentin Wallez336129f2017-10-17 15:55:40 -04002857bool ValidateGetBufferPointervOES(Context *context,
2858 BufferBinding target,
2859 GLenum pname,
2860 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002861{
Geoff Lang496c02d2016-10-20 11:38:11 -07002862 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002863}
2864
Corentin Wallez336129f2017-10-17 15:55:40 -04002865bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002866{
2867 if (!context->getExtensions().mapBuffer)
2868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002869 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002870 return false;
2871 }
2872
Corentin Walleze4477002017-12-01 14:39:58 -05002873 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002874 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002875 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002876 return false;
2877 }
2878
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002879 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002880
2881 if (buffer == nullptr)
2882 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002883 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002884 return false;
2885 }
2886
2887 if (access != GL_WRITE_ONLY_OES)
2888 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002889 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002890 return false;
2891 }
2892
2893 if (buffer->isMapped())
2894 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002895 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002896 return false;
2897 }
2898
Geoff Lang79f71042017-08-14 16:43:43 -04002899 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002900}
2901
Corentin Wallez336129f2017-10-17 15:55:40 -04002902bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002903{
2904 if (!context->getExtensions().mapBuffer)
2905 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002906 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002907 return false;
2908 }
2909
2910 return ValidateUnmapBufferBase(context, target);
2911}
2912
2913bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002914 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002915 GLintptr offset,
2916 GLsizeiptr length,
2917 GLbitfield access)
2918{
2919 if (!context->getExtensions().mapBufferRange)
2920 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002921 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002922 return false;
2923 }
2924
2925 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2926}
2927
Corentin Wallez336129f2017-10-17 15:55:40 -04002928bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002929{
2930 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2931 ASSERT(buffer != nullptr);
2932
2933 // Check if this buffer is currently being used as a transform feedback output buffer
2934 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2935 if (transformFeedback != nullptr && transformFeedback->isActive())
2936 {
2937 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2938 {
2939 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2940 if (transformFeedbackBuffer.get() == buffer)
2941 {
2942 context->handleError(InvalidOperation()
2943 << "Buffer is currently bound for transform feedback.");
2944 return false;
2945 }
2946 }
2947 }
2948
James Darpiniane8a93c62018-01-04 18:02:24 -08002949 if (context->getExtensions().webglCompatibility &&
2950 buffer->isBoundForTransformFeedbackAndOtherUse())
2951 {
2952 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2953 return false;
2954 }
2955
Geoff Lang79f71042017-08-14 16:43:43 -04002956 return true;
2957}
2958
Olli Etuaho4f667482016-03-30 15:56:35 +03002959bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002960 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002961 GLintptr offset,
2962 GLsizeiptr length)
2963{
2964 if (!context->getExtensions().mapBufferRange)
2965 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002966 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002967 return false;
2968 }
2969
2970 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2971}
2972
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002973bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002974{
2975 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002976 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002977 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002978 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002979 return false;
2980 }
2981
Geoff Langf41a7152016-09-19 15:11:17 -04002982 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2983 !context->isTextureGenerated(texture))
2984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002985 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002986 return false;
2987 }
2988
Ian Ewell54f87462016-03-10 13:47:21 -05002989 switch (target)
2990 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002991 case TextureType::_2D:
2992 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002993 break;
2994
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002995 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002996 if (!context->getExtensions().textureRectangle)
2997 {
2998 context->handleError(InvalidEnum()
2999 << "Context does not support GL_ANGLE_texture_rectangle");
3000 return false;
3001 }
3002 break;
3003
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003004 case TextureType::_3D:
3005 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03003006 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003007 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003008 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003009 return false;
3010 }
3011 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003012
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003013 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003014 if (context->getClientVersion() < Version(3, 1))
3015 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003016 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003017 return false;
3018 }
Geoff Lang3b573612016-10-31 14:08:10 -04003019 break;
3020
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003021 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003022 if (!context->getExtensions().eglImageExternal &&
3023 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003024 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003025 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003026 return false;
3027 }
3028 break;
3029 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003030 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003031 return false;
3032 }
3033
3034 return true;
3035}
3036
Geoff Langd8605522016-04-13 10:19:12 -04003037bool ValidateBindUniformLocationCHROMIUM(Context *context,
3038 GLuint program,
3039 GLint location,
3040 const GLchar *name)
3041{
3042 if (!context->getExtensions().bindUniformLocation)
3043 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003044 context->handleError(InvalidOperation()
3045 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003046 return false;
3047 }
3048
3049 Program *programObject = GetValidProgram(context, program);
3050 if (!programObject)
3051 {
3052 return false;
3053 }
3054
3055 if (location < 0)
3056 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003057 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003058 return false;
3059 }
3060
3061 const Caps &caps = context->getCaps();
3062 if (static_cast<size_t>(location) >=
3063 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003065 context->handleError(InvalidValue() << "Location must be less than "
3066 "(MAX_VERTEX_UNIFORM_VECTORS + "
3067 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003068 return false;
3069 }
3070
Geoff Langfc32e8b2017-05-31 14:16:59 -04003071 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3072 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003073 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003074 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003075 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003076 return false;
3077 }
3078
Geoff Langd8605522016-04-13 10:19:12 -04003079 if (strncmp(name, "gl_", 3) == 0)
3080 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003081 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003082 return false;
3083 }
3084
3085 return true;
3086}
3087
Jamie Madille2e406c2016-06-02 13:04:10 -04003088bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003089{
3090 if (!context->getExtensions().framebufferMixedSamples)
3091 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003092 context->handleError(InvalidOperation()
3093 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003094 return false;
3095 }
3096 switch (components)
3097 {
3098 case GL_RGB:
3099 case GL_RGBA:
3100 case GL_ALPHA:
3101 case GL_NONE:
3102 break;
3103 default:
3104 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003105 InvalidEnum()
3106 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003107 return false;
3108 }
3109
3110 return true;
3111}
3112
Sami Väisänene45e53b2016-05-25 10:36:04 +03003113// CHROMIUM_path_rendering
3114
Jamie Madill007530e2017-12-28 14:27:04 -05003115bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003116{
Jamie Madill007530e2017-12-28 14:27:04 -05003117 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003118 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003119 return false;
3120 }
Jamie Madill007530e2017-12-28 14:27:04 -05003121
Sami Väisänene45e53b2016-05-25 10:36:04 +03003122 if (matrix == nullptr)
3123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003124 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003125 return false;
3126 }
Jamie Madill007530e2017-12-28 14:27:04 -05003127
Sami Väisänene45e53b2016-05-25 10:36:04 +03003128 return true;
3129}
3130
Jamie Madill007530e2017-12-28 14:27:04 -05003131bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003132{
Jamie Madill007530e2017-12-28 14:27:04 -05003133 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003134}
3135
Jamie Madill007530e2017-12-28 14:27:04 -05003136bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003137{
3138 if (!context->getExtensions().pathRendering)
3139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003140 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003141 return false;
3142 }
3143
3144 // range = 0 is undefined in NV_path_rendering.
3145 // we add stricter semantic check here and require a non zero positive range.
3146 if (range <= 0)
3147 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003148 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003149 return false;
3150 }
3151
3152 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003155 return false;
3156 }
3157
3158 return true;
3159}
3160
Jamie Madill007530e2017-12-28 14:27:04 -05003161bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003162{
3163 if (!context->getExtensions().pathRendering)
3164 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003165 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003166 return false;
3167 }
3168
3169 // range = 0 is undefined in NV_path_rendering.
3170 // we add stricter semantic check here and require a non zero positive range.
3171 if (range <= 0)
3172 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003173 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003174 return false;
3175 }
3176
3177 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3178 checkedRange += range;
3179
3180 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3181 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003182 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003183 return false;
3184 }
3185 return true;
3186}
3187
Jamie Madill007530e2017-12-28 14:27:04 -05003188bool ValidatePathCommandsCHROMIUM(Context *context,
3189 GLuint path,
3190 GLsizei numCommands,
3191 const GLubyte *commands,
3192 GLsizei numCoords,
3193 GLenum coordType,
3194 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003195{
3196 if (!context->getExtensions().pathRendering)
3197 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003198 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003199 return false;
3200 }
Brandon Jones59770802018-04-02 13:18:42 -07003201 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003202 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003204 return false;
3205 }
3206
3207 if (numCommands < 0)
3208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003209 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003210 return false;
3211 }
3212 else if (numCommands > 0)
3213 {
3214 if (!commands)
3215 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003216 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003217 return false;
3218 }
3219 }
3220
3221 if (numCoords < 0)
3222 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003223 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003224 return false;
3225 }
3226 else if (numCoords > 0)
3227 {
3228 if (!coords)
3229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003230 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003231 return false;
3232 }
3233 }
3234
3235 std::uint32_t coordTypeSize = 0;
3236 switch (coordType)
3237 {
3238 case GL_BYTE:
3239 coordTypeSize = sizeof(GLbyte);
3240 break;
3241
3242 case GL_UNSIGNED_BYTE:
3243 coordTypeSize = sizeof(GLubyte);
3244 break;
3245
3246 case GL_SHORT:
3247 coordTypeSize = sizeof(GLshort);
3248 break;
3249
3250 case GL_UNSIGNED_SHORT:
3251 coordTypeSize = sizeof(GLushort);
3252 break;
3253
3254 case GL_FLOAT:
3255 coordTypeSize = sizeof(GLfloat);
3256 break;
3257
3258 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003259 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003260 return false;
3261 }
3262
3263 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3264 checkedSize += (coordTypeSize * numCoords);
3265 if (!checkedSize.IsValid())
3266 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003267 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003268 return false;
3269 }
3270
3271 // early return skips command data validation when it doesn't exist.
3272 if (!commands)
3273 return true;
3274
3275 GLsizei expectedNumCoords = 0;
3276 for (GLsizei i = 0; i < numCommands; ++i)
3277 {
3278 switch (commands[i])
3279 {
3280 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3281 break;
3282 case GL_MOVE_TO_CHROMIUM:
3283 case GL_LINE_TO_CHROMIUM:
3284 expectedNumCoords += 2;
3285 break;
3286 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3287 expectedNumCoords += 4;
3288 break;
3289 case GL_CUBIC_CURVE_TO_CHROMIUM:
3290 expectedNumCoords += 6;
3291 break;
3292 case GL_CONIC_CURVE_TO_CHROMIUM:
3293 expectedNumCoords += 5;
3294 break;
3295 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003296 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003297 return false;
3298 }
3299 }
3300 if (expectedNumCoords != numCoords)
3301 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003302 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003303 return false;
3304 }
3305
3306 return true;
3307}
3308
Jamie Madill007530e2017-12-28 14:27:04 -05003309bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003310{
3311 if (!context->getExtensions().pathRendering)
3312 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003313 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003314 return false;
3315 }
Brandon Jones59770802018-04-02 13:18:42 -07003316 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003318 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003319 return false;
3320 }
3321
3322 switch (pname)
3323 {
3324 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3325 if (value < 0.0f)
3326 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003327 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003328 return false;
3329 }
3330 break;
3331 case GL_PATH_END_CAPS_CHROMIUM:
3332 switch (static_cast<GLenum>(value))
3333 {
3334 case GL_FLAT_CHROMIUM:
3335 case GL_SQUARE_CHROMIUM:
3336 case GL_ROUND_CHROMIUM:
3337 break;
3338 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003339 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003340 return false;
3341 }
3342 break;
3343 case GL_PATH_JOIN_STYLE_CHROMIUM:
3344 switch (static_cast<GLenum>(value))
3345 {
3346 case GL_MITER_REVERT_CHROMIUM:
3347 case GL_BEVEL_CHROMIUM:
3348 case GL_ROUND_CHROMIUM:
3349 break;
3350 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003351 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003352 return false;
3353 }
Nico Weber41b072b2018-02-09 10:01:32 -05003354 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003355 case GL_PATH_MITER_LIMIT_CHROMIUM:
3356 if (value < 0.0f)
3357 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003358 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003359 return false;
3360 }
3361 break;
3362
3363 case GL_PATH_STROKE_BOUND_CHROMIUM:
3364 // no errors, only clamping.
3365 break;
3366
3367 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003368 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003369 return false;
3370 }
3371 return true;
3372}
3373
Jamie Madill007530e2017-12-28 14:27:04 -05003374bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3375{
3376 // TODO(jmadill): Use proper clamping cast.
3377 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3378}
3379
3380bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003381{
3382 if (!context->getExtensions().pathRendering)
3383 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003384 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003385 return false;
3386 }
3387
Brandon Jones59770802018-04-02 13:18:42 -07003388 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003389 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003390 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003391 return false;
3392 }
3393 if (!value)
3394 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003395 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003396 return false;
3397 }
3398
3399 switch (pname)
3400 {
3401 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3402 case GL_PATH_END_CAPS_CHROMIUM:
3403 case GL_PATH_JOIN_STYLE_CHROMIUM:
3404 case GL_PATH_MITER_LIMIT_CHROMIUM:
3405 case GL_PATH_STROKE_BOUND_CHROMIUM:
3406 break;
3407
3408 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003409 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003410 return false;
3411 }
3412
3413 return true;
3414}
3415
Jamie Madill007530e2017-12-28 14:27:04 -05003416bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3417{
3418 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3419 reinterpret_cast<GLfloat *>(value));
3420}
3421
3422bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003423{
3424 if (!context->getExtensions().pathRendering)
3425 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003426 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003427 return false;
3428 }
3429
3430 switch (func)
3431 {
3432 case GL_NEVER:
3433 case GL_ALWAYS:
3434 case GL_LESS:
3435 case GL_LEQUAL:
3436 case GL_EQUAL:
3437 case GL_GEQUAL:
3438 case GL_GREATER:
3439 case GL_NOTEQUAL:
3440 break;
3441 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003442 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003443 return false;
3444 }
3445
3446 return true;
3447}
3448
3449// Note that the spec specifies that for the path drawing commands
3450// if the path object is not an existing path object the command
3451// does nothing and no error is generated.
3452// However if the path object exists but has not been specified any
3453// commands then an error is generated.
3454
Jamie Madill007530e2017-12-28 14:27:04 -05003455bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003456{
3457 if (!context->getExtensions().pathRendering)
3458 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003459 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003460 return false;
3461 }
Brandon Jones59770802018-04-02 13:18:42 -07003462 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003463 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003464 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003465 return false;
3466 }
3467
3468 switch (fillMode)
3469 {
3470 case GL_COUNT_UP_CHROMIUM:
3471 case GL_COUNT_DOWN_CHROMIUM:
3472 break;
3473 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003474 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003475 return false;
3476 }
3477
3478 if (!isPow2(mask + 1))
3479 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003480 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003481 return false;
3482 }
3483
3484 return true;
3485}
3486
Jamie Madill007530e2017-12-28 14:27:04 -05003487bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003488{
3489 if (!context->getExtensions().pathRendering)
3490 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003491 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003492 return false;
3493 }
Brandon Jones59770802018-04-02 13:18:42 -07003494 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003495 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003496 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003497 return false;
3498 }
3499
3500 return true;
3501}
3502
Brandon Jonesd1049182018-03-28 10:02:20 -07003503bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3504{
3505 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3506}
3507
3508bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3509{
3510 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3511}
3512
Jamie Madill007530e2017-12-28 14:27:04 -05003513bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003514{
3515 if (!context->getExtensions().pathRendering)
3516 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003517 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003518 return false;
3519 }
Brandon Jones59770802018-04-02 13:18:42 -07003520 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003521 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003522 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003523 return false;
3524 }
3525
3526 switch (coverMode)
3527 {
3528 case GL_CONVEX_HULL_CHROMIUM:
3529 case GL_BOUNDING_BOX_CHROMIUM:
3530 break;
3531 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003532 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003533 return false;
3534 }
3535 return true;
3536}
3537
Jamie Madill007530e2017-12-28 14:27:04 -05003538bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3539 GLuint path,
3540 GLenum fillMode,
3541 GLuint mask,
3542 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003543{
Jamie Madill007530e2017-12-28 14:27:04 -05003544 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3545 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546}
3547
Jamie Madill007530e2017-12-28 14:27:04 -05003548bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3549 GLuint path,
3550 GLint reference,
3551 GLuint mask,
3552 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003553{
Jamie Madill007530e2017-12-28 14:27:04 -05003554 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3555 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003556}
3557
Brandon Jonesd1049182018-03-28 10:02:20 -07003558bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003559{
3560 if (!context->getExtensions().pathRendering)
3561 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003562 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003563 return false;
3564 }
3565 return true;
3566}
3567
Jamie Madill007530e2017-12-28 14:27:04 -05003568bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3569 GLsizei numPaths,
3570 GLenum pathNameType,
3571 const void *paths,
3572 GLuint pathBase,
3573 GLenum coverMode,
3574 GLenum transformType,
3575 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003576{
3577 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3578 transformType, transformValues))
3579 return false;
3580
3581 switch (coverMode)
3582 {
3583 case GL_CONVEX_HULL_CHROMIUM:
3584 case GL_BOUNDING_BOX_CHROMIUM:
3585 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3586 break;
3587 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003588 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003589 return false;
3590 }
3591
3592 return true;
3593}
3594
Jamie Madill007530e2017-12-28 14:27:04 -05003595bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3596 GLsizei numPaths,
3597 GLenum pathNameType,
3598 const void *paths,
3599 GLuint pathBase,
3600 GLenum coverMode,
3601 GLenum transformType,
3602 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003603{
3604 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3605 transformType, transformValues))
3606 return false;
3607
3608 switch (coverMode)
3609 {
3610 case GL_CONVEX_HULL_CHROMIUM:
3611 case GL_BOUNDING_BOX_CHROMIUM:
3612 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3613 break;
3614 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003615 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003616 return false;
3617 }
3618
3619 return true;
3620}
3621
Jamie Madill007530e2017-12-28 14:27:04 -05003622bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3623 GLsizei numPaths,
3624 GLenum pathNameType,
3625 const void *paths,
3626 GLuint pathBase,
3627 GLenum fillMode,
3628 GLuint mask,
3629 GLenum transformType,
3630 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003631{
3632
3633 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3634 transformType, transformValues))
3635 return false;
3636
3637 switch (fillMode)
3638 {
3639 case GL_COUNT_UP_CHROMIUM:
3640 case GL_COUNT_DOWN_CHROMIUM:
3641 break;
3642 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003643 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003644 return false;
3645 }
3646 if (!isPow2(mask + 1))
3647 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003648 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003649 return false;
3650 }
3651 return true;
3652}
3653
Jamie Madill007530e2017-12-28 14:27:04 -05003654bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3655 GLsizei numPaths,
3656 GLenum pathNameType,
3657 const void *paths,
3658 GLuint pathBase,
3659 GLint reference,
3660 GLuint mask,
3661 GLenum transformType,
3662 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003663{
3664 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3665 transformType, transformValues))
3666 return false;
3667
3668 // no more validation here.
3669
3670 return true;
3671}
3672
Jamie Madill007530e2017-12-28 14:27:04 -05003673bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3674 GLsizei numPaths,
3675 GLenum pathNameType,
3676 const void *paths,
3677 GLuint pathBase,
3678 GLenum fillMode,
3679 GLuint mask,
3680 GLenum coverMode,
3681 GLenum transformType,
3682 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003683{
3684 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3685 transformType, transformValues))
3686 return false;
3687
3688 switch (coverMode)
3689 {
3690 case GL_CONVEX_HULL_CHROMIUM:
3691 case GL_BOUNDING_BOX_CHROMIUM:
3692 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3693 break;
3694 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003695 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003696 return false;
3697 }
3698
3699 switch (fillMode)
3700 {
3701 case GL_COUNT_UP_CHROMIUM:
3702 case GL_COUNT_DOWN_CHROMIUM:
3703 break;
3704 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003705 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003706 return false;
3707 }
3708 if (!isPow2(mask + 1))
3709 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003710 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003711 return false;
3712 }
3713
3714 return true;
3715}
3716
Jamie Madill007530e2017-12-28 14:27:04 -05003717bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3718 GLsizei numPaths,
3719 GLenum pathNameType,
3720 const void *paths,
3721 GLuint pathBase,
3722 GLint reference,
3723 GLuint mask,
3724 GLenum coverMode,
3725 GLenum transformType,
3726 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003727{
3728 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3729 transformType, transformValues))
3730 return false;
3731
3732 switch (coverMode)
3733 {
3734 case GL_CONVEX_HULL_CHROMIUM:
3735 case GL_BOUNDING_BOX_CHROMIUM:
3736 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3737 break;
3738 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003739 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003740 return false;
3741 }
3742
3743 return true;
3744}
3745
Jamie Madill007530e2017-12-28 14:27:04 -05003746bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3747 GLuint program,
3748 GLint location,
3749 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003750{
3751 if (!context->getExtensions().pathRendering)
3752 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003753 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003754 return false;
3755 }
3756
3757 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3758 if (location >= MaxLocation)
3759 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003760 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003761 return false;
3762 }
3763
3764 const auto *programObject = context->getProgram(program);
3765 if (!programObject)
3766 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003767 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003768 return false;
3769 }
3770
3771 if (!name)
3772 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003773 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003774 return false;
3775 }
3776
3777 if (angle::BeginsWith(name, "gl_"))
3778 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003779 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003780 return false;
3781 }
3782
3783 return true;
3784}
3785
Jamie Madill007530e2017-12-28 14:27:04 -05003786bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3787 GLuint program,
3788 GLint location,
3789 GLenum genMode,
3790 GLint components,
3791 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003792{
3793 if (!context->getExtensions().pathRendering)
3794 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003795 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003796 return false;
3797 }
3798
3799 const auto *programObject = context->getProgram(program);
3800 if (!programObject || programObject->isFlaggedForDeletion())
3801 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003802 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003803 return false;
3804 }
3805
3806 if (!programObject->isLinked())
3807 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003808 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003809 return false;
3810 }
3811
3812 switch (genMode)
3813 {
3814 case GL_NONE:
3815 if (components != 0)
3816 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003817 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003818 return false;
3819 }
3820 break;
3821
3822 case GL_OBJECT_LINEAR_CHROMIUM:
3823 case GL_EYE_LINEAR_CHROMIUM:
3824 case GL_CONSTANT_CHROMIUM:
3825 if (components < 1 || components > 4)
3826 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003827 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003828 return false;
3829 }
3830 if (!coeffs)
3831 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003832 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003833 return false;
3834 }
3835 break;
3836
3837 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003838 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003839 return false;
3840 }
3841
3842 // If the location is -1 then the command is silently ignored
3843 // and no further validation is needed.
3844 if (location == -1)
3845 return true;
3846
Jamie Madillbd044ed2017-06-05 12:59:21 -04003847 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003848
3849 if (!binding.valid)
3850 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003851 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003852 return false;
3853 }
3854
3855 if (binding.type != GL_NONE)
3856 {
3857 GLint expectedComponents = 0;
3858 switch (binding.type)
3859 {
3860 case GL_FLOAT:
3861 expectedComponents = 1;
3862 break;
3863 case GL_FLOAT_VEC2:
3864 expectedComponents = 2;
3865 break;
3866 case GL_FLOAT_VEC3:
3867 expectedComponents = 3;
3868 break;
3869 case GL_FLOAT_VEC4:
3870 expectedComponents = 4;
3871 break;
3872 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003873 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003874 InvalidOperation()
3875 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003876 return false;
3877 }
3878 if (expectedComponents != components && genMode != GL_NONE)
3879 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003880 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003881 return false;
3882 }
3883 }
3884 return true;
3885}
3886
Geoff Lang97073d12016-04-20 10:42:34 -07003887bool ValidateCopyTextureCHROMIUM(Context *context,
3888 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003889 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003890 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003891 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003892 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003893 GLint internalFormat,
3894 GLenum destType,
3895 GLboolean unpackFlipY,
3896 GLboolean unpackPremultiplyAlpha,
3897 GLboolean unpackUnmultiplyAlpha)
3898{
3899 if (!context->getExtensions().copyTexture)
3900 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003901 context->handleError(InvalidOperation()
3902 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003903 return false;
3904 }
3905
Geoff Lang4f0e0032017-05-01 16:04:35 -04003906 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003907 if (source == nullptr)
3908 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003909 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003910 return false;
3911 }
3912
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003913 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003914 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003915 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003916 return false;
3917 }
3918
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003919 TextureType sourceType = source->getType();
3920 ASSERT(sourceType != TextureType::CubeMap);
3921 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003922
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003923 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003924 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003925 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003926 return false;
3927 }
3928
Geoff Lang4f0e0032017-05-01 16:04:35 -04003929 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3930 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3931 if (sourceWidth == 0 || sourceHeight == 0)
3932 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003933 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003934 return false;
3935 }
3936
3937 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3938 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003939 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003940 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003941 return false;
3942 }
3943
Geoff Lang63458a32017-10-30 15:16:53 -04003944 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3945 {
3946 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3947 return false;
3948 }
3949
Geoff Lang4f0e0032017-05-01 16:04:35 -04003950 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003951 if (dest == nullptr)
3952 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003953 context->handleError(InvalidValue()
3954 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003955 return false;
3956 }
3957
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003958 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003959 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003960 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003961 return false;
3962 }
3963
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003964 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003965 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003966 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003967 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003968 return false;
3969 }
3970
Geoff Lang97073d12016-04-20 10:42:34 -07003971 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3972 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003973 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003974 return false;
3975 }
3976
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003977 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003978 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003979 context->handleError(
3980 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003981 return false;
3982 }
3983
Geoff Lang97073d12016-04-20 10:42:34 -07003984 if (dest->getImmutableFormat())
3985 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003986 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003987 return false;
3988 }
3989
3990 return true;
3991}
3992
3993bool ValidateCopySubTextureCHROMIUM(Context *context,
3994 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003995 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003996 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003997 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003998 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003999 GLint xoffset,
4000 GLint yoffset,
4001 GLint x,
4002 GLint y,
4003 GLsizei width,
4004 GLsizei height,
4005 GLboolean unpackFlipY,
4006 GLboolean unpackPremultiplyAlpha,
4007 GLboolean unpackUnmultiplyAlpha)
4008{
4009 if (!context->getExtensions().copyTexture)
4010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004011 context->handleError(InvalidOperation()
4012 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004013 return false;
4014 }
4015
Geoff Lang4f0e0032017-05-01 16:04:35 -04004016 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004017 if (source == nullptr)
4018 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004019 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004020 return false;
4021 }
4022
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004023 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004024 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004025 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004026 return false;
4027 }
4028
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004029 TextureType sourceType = source->getType();
4030 ASSERT(sourceType != TextureType::CubeMap);
4031 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004032
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004033 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004034 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004035 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004036 return false;
4037 }
4038
4039 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4040 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004042 context->handleError(InvalidValue()
4043 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004044 return false;
4045 }
4046
4047 if (x < 0 || y < 0)
4048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004049 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004050 return false;
4051 }
4052
4053 if (width < 0 || height < 0)
4054 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004055 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004056 return false;
4057 }
4058
Geoff Lang4f0e0032017-05-01 16:04:35 -04004059 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4060 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004061 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004062 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004063 return false;
4064 }
4065
Geoff Lang4f0e0032017-05-01 16:04:35 -04004066 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4067 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004068 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004069 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004070 return false;
4071 }
4072
Geoff Lang63458a32017-10-30 15:16:53 -04004073 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4074 {
4075 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4076 return false;
4077 }
4078
Geoff Lang4f0e0032017-05-01 16:04:35 -04004079 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004080 if (dest == nullptr)
4081 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004082 context->handleError(InvalidValue()
4083 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004084 return false;
4085 }
4086
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004087 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004088 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004089 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004090 return false;
4091 }
4092
Brandon Jones28783792018-03-05 09:37:32 -08004093 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4094 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004095 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004096 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004097 return false;
4098 }
4099
Geoff Lang4f0e0032017-05-01 16:04:35 -04004100 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4101 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004102 context
4103 ->handleError(InvalidOperation()
4104 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004105 return false;
4106 }
4107
4108 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4109 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004110 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004111 context->handleError(InvalidOperation()
4112 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004113 return false;
4114 }
4115
4116 if (xoffset < 0 || yoffset < 0)
4117 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004118 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004119 return false;
4120 }
4121
Geoff Lang4f0e0032017-05-01 16:04:35 -04004122 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4123 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004124 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004125 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004126 return false;
4127 }
4128
4129 return true;
4130}
4131
Geoff Lang47110bf2016-04-20 11:13:22 -07004132bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4133{
4134 if (!context->getExtensions().copyCompressedTexture)
4135 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004136 context->handleError(InvalidOperation()
4137 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004138 return false;
4139 }
4140
4141 const gl::Texture *source = context->getTexture(sourceId);
4142 if (source == nullptr)
4143 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004144 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004145 return false;
4146 }
4147
Corentin Wallez99d492c2018-02-27 15:17:10 -05004148 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004149 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004150 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004151 return false;
4152 }
4153
Corentin Wallez99d492c2018-02-27 15:17:10 -05004154 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4155 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004156 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004157 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004158 return false;
4159 }
4160
Corentin Wallez99d492c2018-02-27 15:17:10 -05004161 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004162 if (!sourceFormat.info->compressed)
4163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004164 context->handleError(InvalidOperation()
4165 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004166 return false;
4167 }
4168
4169 const gl::Texture *dest = context->getTexture(destId);
4170 if (dest == nullptr)
4171 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004172 context->handleError(InvalidValue()
4173 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004174 return false;
4175 }
4176
Corentin Wallez99d492c2018-02-27 15:17:10 -05004177 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004178 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004179 context->handleError(InvalidValue()
4180 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004181 return false;
4182 }
4183
4184 if (dest->getImmutableFormat())
4185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004186 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004187 return false;
4188 }
4189
4190 return true;
4191}
4192
Jiawei Shao385b3e02018-03-21 09:43:28 +08004193bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004194{
4195 switch (type)
4196 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004197 case ShaderType::Vertex:
4198 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004199 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004200
Jiawei Shao385b3e02018-03-21 09:43:28 +08004201 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004202 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004203 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004204 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004205 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004206 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004207 break;
4208
Jiawei Shao385b3e02018-03-21 09:43:28 +08004209 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004210 if (!context->getExtensions().geometryShader)
4211 {
4212 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4213 return false;
4214 }
4215 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004216 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004217 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004218 return false;
4219 }
Jamie Madill29639852016-09-02 15:00:09 -04004220
4221 return true;
4222}
4223
Jamie Madill5b772312018-03-08 20:28:32 -05004224bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004225 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004226 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004227 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004228 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004229{
4230 if (size < 0)
4231 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004232 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004233 return false;
4234 }
4235
4236 switch (usage)
4237 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004238 case BufferUsage::StreamDraw:
4239 case BufferUsage::StaticDraw:
4240 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004241 break;
4242
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004243 case BufferUsage::StreamRead:
4244 case BufferUsage::StaticRead:
4245 case BufferUsage::DynamicRead:
4246 case BufferUsage::StreamCopy:
4247 case BufferUsage::StaticCopy:
4248 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004249 if (context->getClientMajorVersion() < 3)
4250 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004251 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004252 return false;
4253 }
4254 break;
4255
4256 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004257 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004258 return false;
4259 }
4260
Corentin Walleze4477002017-12-01 14:39:58 -05004261 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004262 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004263 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004264 return false;
4265 }
4266
4267 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4268
4269 if (!buffer)
4270 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004271 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004272 return false;
4273 }
4274
James Darpiniane8a93c62018-01-04 18:02:24 -08004275 if (context->getExtensions().webglCompatibility &&
4276 buffer->isBoundForTransformFeedbackAndOtherUse())
4277 {
4278 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4279 return false;
4280 }
4281
Jamie Madill29639852016-09-02 15:00:09 -04004282 return true;
4283}
4284
Jamie Madill5b772312018-03-08 20:28:32 -05004285bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004286 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004287 GLintptr offset,
4288 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004289 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004290{
Brandon Jones6cad5662017-06-14 13:25:13 -07004291 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004292 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004293 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4294 return false;
4295 }
4296
4297 if (offset < 0)
4298 {
4299 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004300 return false;
4301 }
4302
Corentin Walleze4477002017-12-01 14:39:58 -05004303 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004304 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004305 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004306 return false;
4307 }
4308
4309 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4310
4311 if (!buffer)
4312 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004313 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004314 return false;
4315 }
4316
4317 if (buffer->isMapped())
4318 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004319 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004320 return false;
4321 }
4322
James Darpiniane8a93c62018-01-04 18:02:24 -08004323 if (context->getExtensions().webglCompatibility &&
4324 buffer->isBoundForTransformFeedbackAndOtherUse())
4325 {
4326 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4327 return false;
4328 }
4329
Jamie Madill29639852016-09-02 15:00:09 -04004330 // Check for possible overflow of size + offset
4331 angle::CheckedNumeric<size_t> checkedSize(size);
4332 checkedSize += offset;
4333 if (!checkedSize.IsValid())
4334 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004335 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004336 return false;
4337 }
4338
4339 if (size + offset > buffer->getSize())
4340 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004341 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004342 return false;
4343 }
4344
Martin Radev4c4c8e72016-08-04 12:25:34 +03004345 return true;
4346}
4347
Geoff Lang111a99e2017-10-17 10:58:41 -04004348bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004349{
Geoff Langc339c4e2016-11-29 10:37:36 -05004350 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004351 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004352 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004353 return false;
4354 }
4355
Geoff Lang111a99e2017-10-17 10:58:41 -04004356 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004357 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004358 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004359 return false;
4360 }
4361
4362 return true;
4363}
4364
Jamie Madill5b772312018-03-08 20:28:32 -05004365bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004366{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004367 if (context->getClientMajorVersion() < 2)
4368 {
4369 return ValidateMultitextureUnit(context, texture);
4370 }
4371
Jamie Madillef300b12016-10-07 15:12:09 -04004372 if (texture < GL_TEXTURE0 ||
4373 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4374 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004375 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004376 return false;
4377 }
4378
4379 return true;
4380}
4381
Jamie Madill5b772312018-03-08 20:28:32 -05004382bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004383{
4384 Program *programObject = GetValidProgram(context, program);
4385 if (!programObject)
4386 {
4387 return false;
4388 }
4389
4390 Shader *shaderObject = GetValidShader(context, shader);
4391 if (!shaderObject)
4392 {
4393 return false;
4394 }
4395
Jiawei Shao385b3e02018-03-21 09:43:28 +08004396 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004397 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004398 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4399 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004400 }
4401
4402 return true;
4403}
4404
Jamie Madill5b772312018-03-08 20:28:32 -05004405bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004406{
4407 if (index >= MAX_VERTEX_ATTRIBS)
4408 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004409 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004410 return false;
4411 }
4412
4413 if (strncmp(name, "gl_", 3) == 0)
4414 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004415 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004416 return false;
4417 }
4418
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004419 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004420 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004421 const size_t length = strlen(name);
4422
4423 if (!IsValidESSLString(name, length))
4424 {
4425 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4426 // for shader-related entry points
4427 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4428 return false;
4429 }
4430
4431 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4432 {
4433 return false;
4434 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004435 }
4436
Jamie Madill01a80ee2016-11-07 12:06:18 -05004437 return GetValidProgram(context, program) != nullptr;
4438}
4439
Jamie Madill5b772312018-03-08 20:28:32 -05004440bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004441{
Corentin Walleze4477002017-12-01 14:39:58 -05004442 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004443 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004444 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004445 return false;
4446 }
4447
4448 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4449 !context->isBufferGenerated(buffer))
4450 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004451 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004452 return false;
4453 }
4454
4455 return true;
4456}
4457
Jamie Madill5b772312018-03-08 20:28:32 -05004458bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004459{
Geoff Lange8afa902017-09-27 15:00:43 -04004460 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004461 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004462 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004463 return false;
4464 }
4465
4466 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4467 !context->isFramebufferGenerated(framebuffer))
4468 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004469 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004470 return false;
4471 }
4472
4473 return true;
4474}
4475
Jamie Madill5b772312018-03-08 20:28:32 -05004476bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004477{
4478 if (target != GL_RENDERBUFFER)
4479 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004480 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004481 return false;
4482 }
4483
4484 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4485 !context->isRenderbufferGenerated(renderbuffer))
4486 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004487 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004488 return false;
4489 }
4490
4491 return true;
4492}
4493
Jamie Madill5b772312018-03-08 20:28:32 -05004494static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004495{
4496 switch (mode)
4497 {
4498 case GL_FUNC_ADD:
4499 case GL_FUNC_SUBTRACT:
4500 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004501 return true;
4502
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004503 case GL_MIN:
4504 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004505 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004506
4507 default:
4508 return false;
4509 }
4510}
4511
Jamie Madill5b772312018-03-08 20:28:32 -05004512bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004513{
4514 return true;
4515}
4516
Jamie Madill5b772312018-03-08 20:28:32 -05004517bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004518{
Geoff Lang50cac572017-09-26 17:37:43 -04004519 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004520 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004521 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004522 return false;
4523 }
4524
4525 return true;
4526}
4527
Jamie Madill5b772312018-03-08 20:28:32 -05004528bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004529{
Geoff Lang50cac572017-09-26 17:37:43 -04004530 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004531 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004532 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004533 return false;
4534 }
4535
Geoff Lang50cac572017-09-26 17:37:43 -04004536 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004537 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004538 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004539 return false;
4540 }
4541
4542 return true;
4543}
4544
Jamie Madill5b772312018-03-08 20:28:32 -05004545bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004546{
4547 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4548}
4549
4550static bool ValidSrcBlendFunc(GLenum srcBlend)
4551{
4552 switch (srcBlend)
4553 {
4554 case GL_ZERO:
4555 case GL_ONE:
4556 case GL_SRC_COLOR:
4557 case GL_ONE_MINUS_SRC_COLOR:
4558 case GL_DST_COLOR:
4559 case GL_ONE_MINUS_DST_COLOR:
4560 case GL_SRC_ALPHA:
4561 case GL_ONE_MINUS_SRC_ALPHA:
4562 case GL_DST_ALPHA:
4563 case GL_ONE_MINUS_DST_ALPHA:
4564 case GL_CONSTANT_COLOR:
4565 case GL_ONE_MINUS_CONSTANT_COLOR:
4566 case GL_CONSTANT_ALPHA:
4567 case GL_ONE_MINUS_CONSTANT_ALPHA:
4568 case GL_SRC_ALPHA_SATURATE:
4569 return true;
4570
4571 default:
4572 return false;
4573 }
4574}
4575
4576static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4577{
4578 switch (dstBlend)
4579 {
4580 case GL_ZERO:
4581 case GL_ONE:
4582 case GL_SRC_COLOR:
4583 case GL_ONE_MINUS_SRC_COLOR:
4584 case GL_DST_COLOR:
4585 case GL_ONE_MINUS_DST_COLOR:
4586 case GL_SRC_ALPHA:
4587 case GL_ONE_MINUS_SRC_ALPHA:
4588 case GL_DST_ALPHA:
4589 case GL_ONE_MINUS_DST_ALPHA:
4590 case GL_CONSTANT_COLOR:
4591 case GL_ONE_MINUS_CONSTANT_COLOR:
4592 case GL_CONSTANT_ALPHA:
4593 case GL_ONE_MINUS_CONSTANT_ALPHA:
4594 return true;
4595
4596 case GL_SRC_ALPHA_SATURATE:
4597 return (contextMajorVersion >= 3);
4598
4599 default:
4600 return false;
4601 }
4602}
4603
Jamie Madill5b772312018-03-08 20:28:32 -05004604bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004605 GLenum srcRGB,
4606 GLenum dstRGB,
4607 GLenum srcAlpha,
4608 GLenum dstAlpha)
4609{
4610 if (!ValidSrcBlendFunc(srcRGB))
4611 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004612 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004613 return false;
4614 }
4615
4616 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4617 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004618 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004619 return false;
4620 }
4621
4622 if (!ValidSrcBlendFunc(srcAlpha))
4623 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004624 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004625 return false;
4626 }
4627
4628 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4629 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004630 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004631 return false;
4632 }
4633
Frank Henigman146e8a12017-03-02 23:22:37 -05004634 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4635 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004636 {
4637 bool constantColorUsed =
4638 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4639 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4640
4641 bool constantAlphaUsed =
4642 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4643 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4644
4645 if (constantColorUsed && constantAlphaUsed)
4646 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004647 const char *msg;
4648 if (context->getExtensions().webglCompatibility)
4649 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004650 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004651 }
4652 else
4653 {
4654 msg =
4655 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4656 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4657 "implementation.";
4658 ERR() << msg;
4659 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004660 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004661 return false;
4662 }
4663 }
4664
4665 return true;
4666}
4667
Geoff Langc339c4e2016-11-29 10:37:36 -05004668bool ValidateGetString(Context *context, GLenum name)
4669{
4670 switch (name)
4671 {
4672 case GL_VENDOR:
4673 case GL_RENDERER:
4674 case GL_VERSION:
4675 case GL_SHADING_LANGUAGE_VERSION:
4676 case GL_EXTENSIONS:
4677 break;
4678
4679 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4680 if (!context->getExtensions().requestExtension)
4681 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004682 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004683 return false;
4684 }
4685 break;
4686
4687 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004688 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004689 return false;
4690 }
4691
4692 return true;
4693}
4694
Jamie Madill5b772312018-03-08 20:28:32 -05004695bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004696{
4697 if (width <= 0.0f || isNaN(width))
4698 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004699 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004700 return false;
4701 }
4702
4703 return true;
4704}
4705
Jamie Madill5b772312018-03-08 20:28:32 -05004706bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004707 GLuint index,
4708 GLint size,
4709 GLenum type,
4710 GLboolean normalized,
4711 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004712 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004713{
Shao80957d92017-02-20 21:25:59 +08004714 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004715 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004716 return false;
4717 }
4718
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004719 if (stride < 0)
4720 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004721 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004722 return false;
4723 }
4724
Shao80957d92017-02-20 21:25:59 +08004725 const Caps &caps = context->getCaps();
4726 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004727 {
Shao80957d92017-02-20 21:25:59 +08004728 if (stride > caps.maxVertexAttribStride)
4729 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004730 context->handleError(InvalidValue()
4731 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004732 return false;
4733 }
4734
4735 if (index >= caps.maxVertexAttribBindings)
4736 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004737 context->handleError(InvalidValue()
4738 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004739 return false;
4740 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004741 }
4742
4743 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4744 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4745 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4746 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004747 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4748 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004749 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4750 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004751 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004752 context
4753 ->handleError(InvalidOperation()
4754 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004755 return false;
4756 }
4757
4758 if (context->getExtensions().webglCompatibility)
4759 {
4760 // WebGL 1.0 [Section 6.14] Fixed point support
4761 // The WebGL API does not support the GL_FIXED data type.
4762 if (type == GL_FIXED)
4763 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004764 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004765 return false;
4766 }
4767
Geoff Lang2d62ab72017-03-23 16:54:40 -04004768 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004769 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004770 return false;
4771 }
4772 }
4773
4774 return true;
4775}
4776
Jamie Madill5b772312018-03-08 20:28:32 -05004777bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004778{
4779 if (context->getExtensions().webglCompatibility && zNear > zFar)
4780 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004781 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004782 return false;
4783 }
4784
4785 return true;
4786}
4787
Jamie Madill5b772312018-03-08 20:28:32 -05004788bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004789 GLenum target,
4790 GLenum internalformat,
4791 GLsizei width,
4792 GLsizei height)
4793{
4794 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4795 height);
4796}
4797
Jamie Madill5b772312018-03-08 20:28:32 -05004798bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004799 GLenum target,
4800 GLsizei samples,
4801 GLenum internalformat,
4802 GLsizei width,
4803 GLsizei height)
4804{
4805 if (!context->getExtensions().framebufferMultisample)
4806 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004807 context->handleError(InvalidOperation()
4808 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004809 return false;
4810 }
4811
4812 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4813 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4814 // generated.
4815 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4816 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004817 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004818 return false;
4819 }
4820
4821 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4822 // the specified storage. This is different than ES 3.0 in which a sample number higher
4823 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4824 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4825 if (context->getClientMajorVersion() >= 3)
4826 {
4827 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4828 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4829 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004830 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004831 return false;
4832 }
4833 }
4834
4835 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4836 width, height);
4837}
4838
Jamie Madill5b772312018-03-08 20:28:32 -05004839bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004840{
Geoff Lange8afa902017-09-27 15:00:43 -04004841 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004842 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004843 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004844 return false;
4845 }
4846
4847 return true;
4848}
4849
Jamie Madill5b772312018-03-08 20:28:32 -05004850bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004851{
4852 return true;
4853}
4854
Jamie Madill5b772312018-03-08 20:28:32 -05004855bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004856{
4857 return true;
4858}
4859
Jamie Madill5b772312018-03-08 20:28:32 -05004860bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004861{
4862 return true;
4863}
4864
Jamie Madill5b772312018-03-08 20:28:32 -05004865bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004866 GLboolean red,
4867 GLboolean green,
4868 GLboolean blue,
4869 GLboolean alpha)
4870{
4871 return true;
4872}
4873
Jamie Madill5b772312018-03-08 20:28:32 -05004874bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004875{
4876 return true;
4877}
4878
Jamie Madill5b772312018-03-08 20:28:32 -05004879bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004880{
4881 return true;
4882}
4883
Jamie Madill5b772312018-03-08 20:28:32 -05004884bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004885{
4886 switch (mode)
4887 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004888 case CullFaceMode::Front:
4889 case CullFaceMode::Back:
4890 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004891 break;
4892
4893 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004894 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004895 return false;
4896 }
4897
4898 return true;
4899}
4900
Jamie Madill5b772312018-03-08 20:28:32 -05004901bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004902{
4903 if (program == 0)
4904 {
4905 return false;
4906 }
4907
4908 if (!context->getProgram(program))
4909 {
4910 if (context->getShader(program))
4911 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004912 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004913 return false;
4914 }
4915 else
4916 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004917 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004918 return false;
4919 }
4920 }
4921
4922 return true;
4923}
4924
Jamie Madill5b772312018-03-08 20:28:32 -05004925bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004926{
4927 if (shader == 0)
4928 {
4929 return false;
4930 }
4931
4932 if (!context->getShader(shader))
4933 {
4934 if (context->getProgram(shader))
4935 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004936 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004937 return false;
4938 }
4939 else
4940 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004941 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004942 return false;
4943 }
4944 }
4945
4946 return true;
4947}
4948
Jamie Madill5b772312018-03-08 20:28:32 -05004949bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004950{
4951 switch (func)
4952 {
4953 case GL_NEVER:
4954 case GL_ALWAYS:
4955 case GL_LESS:
4956 case GL_LEQUAL:
4957 case GL_EQUAL:
4958 case GL_GREATER:
4959 case GL_GEQUAL:
4960 case GL_NOTEQUAL:
4961 break;
4962
4963 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004964 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004965 return false;
4966 }
4967
4968 return true;
4969}
4970
Jamie Madill5b772312018-03-08 20:28:32 -05004971bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004972{
4973 return true;
4974}
4975
Jamie Madill5b772312018-03-08 20:28:32 -05004976bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004977{
4978 Program *programObject = GetValidProgram(context, program);
4979 if (!programObject)
4980 {
4981 return false;
4982 }
4983
4984 Shader *shaderObject = GetValidShader(context, shader);
4985 if (!shaderObject)
4986 {
4987 return false;
4988 }
4989
Jiawei Shao385b3e02018-03-21 09:43:28 +08004990 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004991 if (attachedShader != shaderObject)
4992 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004993 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004994 return false;
4995 }
4996
4997 return true;
4998}
4999
Jamie Madill5b772312018-03-08 20:28:32 -05005000bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005001{
5002 if (index >= MAX_VERTEX_ATTRIBS)
5003 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005004 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005005 return false;
5006 }
5007
5008 return true;
5009}
5010
Jamie Madill5b772312018-03-08 20:28:32 -05005011bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005012{
5013 if (index >= MAX_VERTEX_ATTRIBS)
5014 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005015 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005016 return false;
5017 }
5018
5019 return true;
5020}
5021
Jamie Madill5b772312018-03-08 20:28:32 -05005022bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005023{
5024 return true;
5025}
5026
Jamie Madill5b772312018-03-08 20:28:32 -05005027bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005028{
5029 return true;
5030}
5031
Jamie Madill5b772312018-03-08 20:28:32 -05005032bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005033{
5034 switch (mode)
5035 {
5036 case GL_CW:
5037 case GL_CCW:
5038 break;
5039 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005040 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005041 return false;
5042 }
5043
5044 return true;
5045}
5046
Jamie Madill5b772312018-03-08 20:28:32 -05005047bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005048 GLuint program,
5049 GLuint index,
5050 GLsizei bufsize,
5051 GLsizei *length,
5052 GLint *size,
5053 GLenum *type,
5054 GLchar *name)
5055{
5056 if (bufsize < 0)
5057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005058 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005059 return false;
5060 }
5061
5062 Program *programObject = GetValidProgram(context, program);
5063
5064 if (!programObject)
5065 {
5066 return false;
5067 }
5068
5069 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5070 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005071 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005072 return false;
5073 }
5074
5075 return true;
5076}
5077
Jamie Madill5b772312018-03-08 20:28:32 -05005078bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005079 GLuint program,
5080 GLuint index,
5081 GLsizei bufsize,
5082 GLsizei *length,
5083 GLint *size,
5084 GLenum *type,
5085 GLchar *name)
5086{
5087 if (bufsize < 0)
5088 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005089 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005090 return false;
5091 }
5092
5093 Program *programObject = GetValidProgram(context, program);
5094
5095 if (!programObject)
5096 {
5097 return false;
5098 }
5099
5100 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5101 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005102 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005103 return false;
5104 }
5105
5106 return true;
5107}
5108
Jamie Madill5b772312018-03-08 20:28:32 -05005109bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110 GLuint program,
5111 GLsizei maxcount,
5112 GLsizei *count,
5113 GLuint *shaders)
5114{
5115 if (maxcount < 0)
5116 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005117 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005118 return false;
5119 }
5120
5121 Program *programObject = GetValidProgram(context, program);
5122
5123 if (!programObject)
5124 {
5125 return false;
5126 }
5127
5128 return true;
5129}
5130
Jamie Madill5b772312018-03-08 20:28:32 -05005131bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005132{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005133 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5134 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005135 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005137 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005138 return false;
5139 }
5140
Jamie Madillc1d770e2017-04-13 17:31:24 -04005141 Program *programObject = GetValidProgram(context, program);
5142
5143 if (!programObject)
5144 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005145 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005146 return false;
5147 }
5148
5149 if (!programObject->isLinked())
5150 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005152 return false;
5153 }
5154
5155 return true;
5156}
5157
Jamie Madill5b772312018-03-08 20:28:32 -05005158bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005159{
5160 GLenum nativeType;
5161 unsigned int numParams = 0;
5162 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5163}
5164
Jamie Madill5b772312018-03-08 20:28:32 -05005165bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005166{
5167 return true;
5168}
5169
Jamie Madill5b772312018-03-08 20:28:32 -05005170bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005171{
5172 GLenum nativeType;
5173 unsigned int numParams = 0;
5174 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5175}
5176
Jamie Madill5b772312018-03-08 20:28:32 -05005177bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005178{
5179 GLenum nativeType;
5180 unsigned int numParams = 0;
5181 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5182}
5183
Jamie Madill5b772312018-03-08 20:28:32 -05005184bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005185 GLuint program,
5186 GLsizei bufsize,
5187 GLsizei *length,
5188 GLchar *infolog)
5189{
5190 if (bufsize < 0)
5191 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005192 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005193 return false;
5194 }
5195
5196 Program *programObject = GetValidProgram(context, program);
5197 if (!programObject)
5198 {
5199 return false;
5200 }
5201
5202 return true;
5203}
5204
Jamie Madill5b772312018-03-08 20:28:32 -05005205bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005206 GLuint shader,
5207 GLsizei bufsize,
5208 GLsizei *length,
5209 GLchar *infolog)
5210{
5211 if (bufsize < 0)
5212 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005213 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005214 return false;
5215 }
5216
5217 Shader *shaderObject = GetValidShader(context, shader);
5218 if (!shaderObject)
5219 {
5220 return false;
5221 }
5222
5223 return true;
5224}
5225
Jamie Madill5b772312018-03-08 20:28:32 -05005226bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005227 GLenum shadertype,
5228 GLenum precisiontype,
5229 GLint *range,
5230 GLint *precision)
5231{
5232 switch (shadertype)
5233 {
5234 case GL_VERTEX_SHADER:
5235 case GL_FRAGMENT_SHADER:
5236 break;
5237 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005238 context->handleError(InvalidOperation()
5239 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005240 return false;
5241 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005242 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005243 return false;
5244 }
5245
5246 switch (precisiontype)
5247 {
5248 case GL_LOW_FLOAT:
5249 case GL_MEDIUM_FLOAT:
5250 case GL_HIGH_FLOAT:
5251 case GL_LOW_INT:
5252 case GL_MEDIUM_INT:
5253 case GL_HIGH_INT:
5254 break;
5255
5256 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005257 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005258 return false;
5259 }
5260
5261 return true;
5262}
5263
Jamie Madill5b772312018-03-08 20:28:32 -05005264bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005265 GLuint shader,
5266 GLsizei bufsize,
5267 GLsizei *length,
5268 GLchar *source)
5269{
5270 if (bufsize < 0)
5271 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005272 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005273 return false;
5274 }
5275
5276 Shader *shaderObject = GetValidShader(context, shader);
5277 if (!shaderObject)
5278 {
5279 return false;
5280 }
5281
5282 return true;
5283}
5284
Jamie Madill5b772312018-03-08 20:28:32 -05005285bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005286{
5287 if (strstr(name, "gl_") == name)
5288 {
5289 return false;
5290 }
5291
Geoff Langfc32e8b2017-05-31 14:16:59 -04005292 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5293 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005294 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005295 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005296 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005297 return false;
5298 }
5299
Jamie Madillc1d770e2017-04-13 17:31:24 -04005300 Program *programObject = GetValidProgram(context, program);
5301
5302 if (!programObject)
5303 {
5304 return false;
5305 }
5306
5307 if (!programObject->isLinked())
5308 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005309 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005310 return false;
5311 }
5312
5313 return true;
5314}
5315
Jamie Madill5b772312018-03-08 20:28:32 -05005316bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005317{
5318 switch (mode)
5319 {
5320 case GL_FASTEST:
5321 case GL_NICEST:
5322 case GL_DONT_CARE:
5323 break;
5324
5325 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005326 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005327 return false;
5328 }
5329
5330 switch (target)
5331 {
5332 case GL_GENERATE_MIPMAP_HINT:
5333 break;
5334
Geoff Lange7bd2182017-06-16 16:13:13 -04005335 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5336 if (context->getClientVersion() < ES_3_0 &&
5337 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005338 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005339 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005340 return false;
5341 }
5342 break;
5343
5344 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005345 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005346 return false;
5347 }
5348
5349 return true;
5350}
5351
Jamie Madill5b772312018-03-08 20:28:32 -05005352bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005353{
5354 return true;
5355}
5356
Jamie Madill5b772312018-03-08 20:28:32 -05005357bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005358{
5359 return true;
5360}
5361
Jamie Madill5b772312018-03-08 20:28:32 -05005362bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005363{
5364 return true;
5365}
5366
Jamie Madill5b772312018-03-08 20:28:32 -05005367bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368{
5369 return true;
5370}
5371
Jamie Madill5b772312018-03-08 20:28:32 -05005372bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005373{
5374 return true;
5375}
5376
Jamie Madill5b772312018-03-08 20:28:32 -05005377bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378{
5379 return true;
5380}
5381
Jamie Madill5b772312018-03-08 20:28:32 -05005382bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005383{
5384 if (context->getClientMajorVersion() < 3)
5385 {
5386 switch (pname)
5387 {
5388 case GL_UNPACK_IMAGE_HEIGHT:
5389 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005390 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005391 return false;
5392
5393 case GL_UNPACK_ROW_LENGTH:
5394 case GL_UNPACK_SKIP_ROWS:
5395 case GL_UNPACK_SKIP_PIXELS:
5396 if (!context->getExtensions().unpackSubimage)
5397 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005398 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005399 return false;
5400 }
5401 break;
5402
5403 case GL_PACK_ROW_LENGTH:
5404 case GL_PACK_SKIP_ROWS:
5405 case GL_PACK_SKIP_PIXELS:
5406 if (!context->getExtensions().packSubimage)
5407 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005408 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005409 return false;
5410 }
5411 break;
5412 }
5413 }
5414
5415 if (param < 0)
5416 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005417 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005418 return false;
5419 }
5420
5421 switch (pname)
5422 {
5423 case GL_UNPACK_ALIGNMENT:
5424 if (param != 1 && param != 2 && param != 4 && param != 8)
5425 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005426 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005427 return false;
5428 }
5429 break;
5430
5431 case GL_PACK_ALIGNMENT:
5432 if (param != 1 && param != 2 && param != 4 && param != 8)
5433 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005434 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005435 return false;
5436 }
5437 break;
5438
5439 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005440 if (!context->getExtensions().packReverseRowOrder)
5441 {
5442 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5443 }
5444 break;
5445
Jamie Madillc1d770e2017-04-13 17:31:24 -04005446 case GL_UNPACK_ROW_LENGTH:
5447 case GL_UNPACK_IMAGE_HEIGHT:
5448 case GL_UNPACK_SKIP_IMAGES:
5449 case GL_UNPACK_SKIP_ROWS:
5450 case GL_UNPACK_SKIP_PIXELS:
5451 case GL_PACK_ROW_LENGTH:
5452 case GL_PACK_SKIP_ROWS:
5453 case GL_PACK_SKIP_PIXELS:
5454 break;
5455
5456 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005457 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005458 return false;
5459 }
5460
5461 return true;
5462}
5463
Jamie Madill5b772312018-03-08 20:28:32 -05005464bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005465{
5466 return true;
5467}
5468
Jamie Madill5b772312018-03-08 20:28:32 -05005469bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470{
5471 return true;
5472}
5473
Jamie Madill5b772312018-03-08 20:28:32 -05005474bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005475{
5476 return true;
5477}
5478
Jamie Madill5b772312018-03-08 20:28:32 -05005479bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005480{
5481 if (width < 0 || height < 0)
5482 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005483 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
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 ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005491 GLsizei n,
5492 const GLuint *shaders,
5493 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005494 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005495 GLsizei length)
5496{
5497 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5498 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5499 shaderBinaryFormats.end())
5500 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005501 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005502 return false;
5503 }
5504
5505 return true;
5506}
5507
Jamie Madill5b772312018-03-08 20:28:32 -05005508bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005509 GLuint shader,
5510 GLsizei count,
5511 const GLchar *const *string,
5512 const GLint *length)
5513{
5514 if (count < 0)
5515 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005516 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005517 return false;
5518 }
5519
Geoff Langfc32e8b2017-05-31 14:16:59 -04005520 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5521 // shader-related entry points
5522 if (context->getExtensions().webglCompatibility)
5523 {
5524 for (GLsizei i = 0; i < count; i++)
5525 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005526 size_t len =
5527 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005528
5529 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005530 if (!IsValidESSLShaderSourceString(string[i], len,
5531 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005532 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005533 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005534 return false;
5535 }
5536 }
5537 }
5538
Jamie Madillc1d770e2017-04-13 17:31:24 -04005539 Shader *shaderObject = GetValidShader(context, shader);
5540 if (!shaderObject)
5541 {
5542 return false;
5543 }
5544
5545 return true;
5546}
5547
Jamie Madill5b772312018-03-08 20:28:32 -05005548bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005549{
5550 if (!IsValidStencilFunc(func))
5551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005552 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005553 return false;
5554 }
5555
5556 return true;
5557}
5558
Jamie Madill5b772312018-03-08 20:28:32 -05005559bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005560{
5561 if (!IsValidStencilFace(face))
5562 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005563 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005564 return false;
5565 }
5566
5567 if (!IsValidStencilFunc(func))
5568 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005569 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005570 return false;
5571 }
5572
5573 return true;
5574}
5575
Jamie Madill5b772312018-03-08 20:28:32 -05005576bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005577{
5578 return true;
5579}
5580
Jamie Madill5b772312018-03-08 20:28:32 -05005581bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005582{
5583 if (!IsValidStencilFace(face))
5584 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005585 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005586 return false;
5587 }
5588
5589 return true;
5590}
5591
Jamie Madill5b772312018-03-08 20:28:32 -05005592bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005593{
5594 if (!IsValidStencilOp(fail))
5595 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005596 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005597 return false;
5598 }
5599
5600 if (!IsValidStencilOp(zfail))
5601 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005602 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005603 return false;
5604 }
5605
5606 if (!IsValidStencilOp(zpass))
5607 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005609 return false;
5610 }
5611
5612 return true;
5613}
5614
Jamie Madill5b772312018-03-08 20:28:32 -05005615bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005616 GLenum face,
5617 GLenum fail,
5618 GLenum zfail,
5619 GLenum zpass)
5620{
5621 if (!IsValidStencilFace(face))
5622 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005623 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005624 return false;
5625 }
5626
5627 return ValidateStencilOp(context, fail, zfail, zpass);
5628}
5629
Jamie Madill5b772312018-03-08 20:28:32 -05005630bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005631{
5632 return ValidateUniform(context, GL_FLOAT, location, 1);
5633}
5634
Jamie Madill5b772312018-03-08 20:28:32 -05005635bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005636{
5637 return ValidateUniform(context, GL_FLOAT, location, count);
5638}
5639
Jamie Madill5b772312018-03-08 20:28:32 -05005640bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005641{
5642 return ValidateUniform1iv(context, location, 1, &x);
5643}
5644
Jamie Madill5b772312018-03-08 20:28:32 -05005645bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005646{
5647 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5648}
5649
Jamie Madill5b772312018-03-08 20:28:32 -05005650bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005651{
5652 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5653}
5654
Jamie Madill5b772312018-03-08 20:28:32 -05005655bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005656{
5657 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5658}
5659
Jamie Madill5b772312018-03-08 20:28:32 -05005660bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005661{
5662 return ValidateUniform(context, GL_INT_VEC2, location, count);
5663}
5664
Jamie Madill5b772312018-03-08 20:28:32 -05005665bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005666{
5667 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5668}
5669
Jamie Madill5b772312018-03-08 20:28:32 -05005670bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005671{
5672 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5673}
5674
Jamie Madill5b772312018-03-08 20:28:32 -05005675bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005676{
5677 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5678}
5679
Jamie Madill5b772312018-03-08 20:28:32 -05005680bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005681{
5682 return ValidateUniform(context, GL_INT_VEC3, location, count);
5683}
5684
Jamie Madill5b772312018-03-08 20:28:32 -05005685bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005686{
5687 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5688}
5689
Jamie Madill5b772312018-03-08 20:28:32 -05005690bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005691{
5692 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5693}
5694
Jamie Madill5b772312018-03-08 20:28:32 -05005695bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005696{
5697 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5698}
5699
Jamie Madill5b772312018-03-08 20:28:32 -05005700bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005701{
5702 return ValidateUniform(context, GL_INT_VEC4, location, count);
5703}
5704
Jamie Madill5b772312018-03-08 20:28:32 -05005705bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005706 GLint location,
5707 GLsizei count,
5708 GLboolean transpose,
5709 const GLfloat *value)
5710{
5711 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5712}
5713
Jamie Madill5b772312018-03-08 20:28:32 -05005714bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005715 GLint location,
5716 GLsizei count,
5717 GLboolean transpose,
5718 const GLfloat *value)
5719{
5720 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5721}
5722
Jamie Madill5b772312018-03-08 20:28:32 -05005723bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005724 GLint location,
5725 GLsizei count,
5726 GLboolean transpose,
5727 const GLfloat *value)
5728{
5729 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5730}
5731
Jamie Madill5b772312018-03-08 20:28:32 -05005732bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005733{
5734 Program *programObject = GetValidProgram(context, program);
5735
5736 if (!programObject)
5737 {
5738 return false;
5739 }
5740
5741 return true;
5742}
5743
Jamie Madill5b772312018-03-08 20:28:32 -05005744bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005745{
5746 return ValidateVertexAttribIndex(context, index);
5747}
5748
Jamie Madill5b772312018-03-08 20:28:32 -05005749bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005750{
5751 return ValidateVertexAttribIndex(context, index);
5752}
5753
Jamie Madill5b772312018-03-08 20:28:32 -05005754bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005755{
5756 return ValidateVertexAttribIndex(context, index);
5757}
5758
Jamie Madill5b772312018-03-08 20:28:32 -05005759bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005760{
5761 return ValidateVertexAttribIndex(context, index);
5762}
5763
Jamie Madill5b772312018-03-08 20:28:32 -05005764bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005765{
5766 return ValidateVertexAttribIndex(context, index);
5767}
5768
Jamie Madill5b772312018-03-08 20:28:32 -05005769bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005770{
5771 return ValidateVertexAttribIndex(context, index);
5772}
5773
Jamie Madill5b772312018-03-08 20:28:32 -05005774bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005775 GLuint index,
5776 GLfloat x,
5777 GLfloat y,
5778 GLfloat z,
5779 GLfloat w)
5780{
5781 return ValidateVertexAttribIndex(context, index);
5782}
5783
Jamie Madill5b772312018-03-08 20:28:32 -05005784bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005785{
5786 return ValidateVertexAttribIndex(context, index);
5787}
5788
Jamie Madill5b772312018-03-08 20:28:32 -05005789bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005790{
5791 if (width < 0 || height < 0)
5792 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005793 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005794 return false;
5795 }
5796
5797 return true;
5798}
5799
Jamie Madill5b772312018-03-08 20:28:32 -05005800bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005801{
5802 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5803}
5804
Jamie Madill5b772312018-03-08 20:28:32 -05005805bool ValidateDrawElements(Context *context,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005806 GLenum mode,
5807 GLsizei count,
5808 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005809 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005810{
5811 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5812}
5813
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005814bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005815 GLenum target,
5816 GLenum attachment,
5817 GLenum pname,
5818 GLint *params)
5819{
5820 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5821 nullptr);
5822}
5823
Jamie Madill5b772312018-03-08 20:28:32 -05005824bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005825{
5826 return ValidateGetProgramivBase(context, program, pname, nullptr);
5827}
5828
Jamie Madill5b772312018-03-08 20:28:32 -05005829bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005830 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005831 GLint level,
5832 GLenum internalformat,
5833 GLint x,
5834 GLint y,
5835 GLsizei width,
5836 GLsizei height,
5837 GLint border)
5838{
5839 if (context->getClientMajorVersion() < 3)
5840 {
5841 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5842 0, x, y, width, height, border);
5843 }
5844
5845 ASSERT(context->getClientMajorVersion() == 3);
5846 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5847 0, x, y, width, height, border);
5848}
5849
5850bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005851 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005852 GLint level,
5853 GLint xoffset,
5854 GLint yoffset,
5855 GLint x,
5856 GLint y,
5857 GLsizei width,
5858 GLsizei height)
5859{
5860 if (context->getClientMajorVersion() < 3)
5861 {
5862 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5863 yoffset, x, y, width, height, 0);
5864 }
5865
5866 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5867 yoffset, 0, x, y, width, height, 0);
5868}
5869
5870bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5871{
5872 return ValidateGenOrDelete(context, n);
5873}
5874
5875bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5876{
5877 return ValidateGenOrDelete(context, n);
5878}
5879
5880bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5881{
5882 return ValidateGenOrDelete(context, n);
5883}
5884
5885bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5886{
5887 return ValidateGenOrDelete(context, n);
5888}
5889
5890bool ValidateDisable(Context *context, GLenum cap)
5891{
5892 if (!ValidCap(context, cap, false))
5893 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005894 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005895 return false;
5896 }
5897
5898 return true;
5899}
5900
5901bool ValidateEnable(Context *context, GLenum cap)
5902{
5903 if (!ValidCap(context, cap, false))
5904 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005905 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005906 return false;
5907 }
5908
5909 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5910 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5911 {
5912 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005913 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005914
5915 // We also output an error message to the debugger window if tracing is active, so that
5916 // developers can see the error message.
5917 ERR() << errorMessage;
5918 return false;
5919 }
5920
5921 return true;
5922}
5923
5924bool ValidateFramebufferRenderbuffer(Context *context,
5925 GLenum target,
5926 GLenum attachment,
5927 GLenum renderbuffertarget,
5928 GLuint renderbuffer)
5929{
Geoff Lange8afa902017-09-27 15:00:43 -04005930 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005931 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005932 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5933 return false;
5934 }
5935
5936 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5937 {
5938 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005939 return false;
5940 }
5941
5942 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5943 renderbuffertarget, renderbuffer);
5944}
5945
5946bool ValidateFramebufferTexture2D(Context *context,
5947 GLenum target,
5948 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005949 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005950 GLuint texture,
5951 GLint level)
5952{
5953 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5954 // extension
5955 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5956 level != 0)
5957 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005958 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005959 return false;
5960 }
5961
5962 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5963 {
5964 return false;
5965 }
5966
5967 if (texture != 0)
5968 {
5969 gl::Texture *tex = context->getTexture(texture);
5970 ASSERT(tex);
5971
5972 const gl::Caps &caps = context->getCaps();
5973
5974 switch (textarget)
5975 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005976 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005977 {
5978 if (level > gl::log2(caps.max2DTextureSize))
5979 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005980 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005981 return false;
5982 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005983 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005984 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005985 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005986 return false;
5987 }
5988 }
5989 break;
5990
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005991 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005992 {
5993 if (level != 0)
5994 {
5995 context->handleError(InvalidValue());
5996 return false;
5997 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005998 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005999 {
6000 context->handleError(InvalidOperation()
6001 << "Textarget must match the texture target type.");
6002 return false;
6003 }
6004 }
6005 break;
6006
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006007 case TextureTarget::CubeMapNegativeX:
6008 case TextureTarget::CubeMapNegativeY:
6009 case TextureTarget::CubeMapNegativeZ:
6010 case TextureTarget::CubeMapPositiveX:
6011 case TextureTarget::CubeMapPositiveY:
6012 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 {
6014 if (level > gl::log2(caps.maxCubeMapTextureSize))
6015 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006016 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006017 return false;
6018 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006019 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006021 context->handleError(InvalidOperation()
6022 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006023 return false;
6024 }
6025 }
6026 break;
6027
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006028 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006029 {
6030 if (context->getClientVersion() < ES_3_1)
6031 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006032 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006033 return false;
6034 }
6035
6036 if (level != 0)
6037 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006038 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006039 return false;
6040 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006041 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006043 context->handleError(InvalidOperation()
6044 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 return false;
6046 }
6047 }
6048 break;
6049
6050 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006051 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006052 return false;
6053 }
6054
6055 const Format &format = tex->getFormat(textarget, level);
6056 if (format.info->compressed)
6057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006058 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006059 return false;
6060 }
6061 }
6062
6063 return true;
6064}
6065
6066bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6067{
6068 return ValidateGenOrDelete(context, n);
6069}
6070
6071bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6072{
6073 return ValidateGenOrDelete(context, n);
6074}
6075
6076bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6077{
6078 return ValidateGenOrDelete(context, n);
6079}
6080
6081bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6082{
6083 return ValidateGenOrDelete(context, n);
6084}
6085
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006086bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006087{
6088 if (!ValidTextureTarget(context, target))
6089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006090 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006091 return false;
6092 }
6093
6094 Texture *texture = context->getTargetTexture(target);
6095
6096 if (texture == nullptr)
6097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006098 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006099 return false;
6100 }
6101
6102 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6103
6104 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6105 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6106 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6107 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006108 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006109 return false;
6110 }
6111
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006112 TextureTarget baseTarget = (target == TextureType::CubeMap)
6113 ? TextureTarget::CubeMapPositiveX
6114 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006115 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6116 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6117 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006118 {
6119 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6120 return false;
6121 }
6122
Geoff Lang536eca12017-09-13 11:23:35 -04006123 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6124 bool formatUnsized = !format.sized;
6125 bool formatColorRenderableAndFilterable =
6126 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6127 format.renderSupport(context->getClientVersion(), context->getExtensions());
6128 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006129 {
Geoff Lang536eca12017-09-13 11:23:35 -04006130 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006131 return false;
6132 }
6133
Geoff Lang536eca12017-09-13 11:23:35 -04006134 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6135 // generation
6136 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6137 {
6138 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6139 return false;
6140 }
6141
6142 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6143 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006144 bool supportsSRGBMipmapGeneration =
6145 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006146 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006147 {
Geoff Lang536eca12017-09-13 11:23:35 -04006148 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006149 return false;
6150 }
6151
6152 // Non-power of 2 ES2 check
6153 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6154 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6155 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6156 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006157 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6158 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006160 return false;
6161 }
6162
6163 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006164 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006165 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006166 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006167 return false;
6168 }
6169
6170 return true;
6171}
6172
Jamie Madill5b772312018-03-08 20:28:32 -05006173bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006174 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006175 GLenum pname,
6176 GLint *params)
6177{
6178 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6179}
6180
6181bool ValidateGetRenderbufferParameteriv(Context *context,
6182 GLenum target,
6183 GLenum pname,
6184 GLint *params)
6185{
6186 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6187}
6188
6189bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6190{
6191 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6192}
6193
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006194bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006195{
6196 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6197}
6198
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006199bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006200{
6201 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6202}
6203
6204bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6205{
6206 return ValidateGetUniformBase(context, program, location);
6207}
6208
6209bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6210{
6211 return ValidateGetUniformBase(context, program, location);
6212}
6213
6214bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6215{
6216 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6217}
6218
6219bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6220{
6221 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6222}
6223
6224bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6225{
6226 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6227}
6228
6229bool ValidateIsEnabled(Context *context, GLenum cap)
6230{
6231 if (!ValidCap(context, cap, true))
6232 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006233 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006234 return false;
6235 }
6236
6237 return true;
6238}
6239
6240bool ValidateLinkProgram(Context *context, GLuint program)
6241{
6242 if (context->hasActiveTransformFeedback(program))
6243 {
6244 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006245 context->handleError(InvalidOperation() << "Cannot link program while program is "
6246 "associated with an active transform "
6247 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006248 return false;
6249 }
6250
6251 Program *programObject = GetValidProgram(context, program);
6252 if (!programObject)
6253 {
6254 return false;
6255 }
6256
6257 return true;
6258}
6259
Jamie Madill4928b7c2017-06-20 12:57:39 -04006260bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006261 GLint x,
6262 GLint y,
6263 GLsizei width,
6264 GLsizei height,
6265 GLenum format,
6266 GLenum type,
6267 void *pixels)
6268{
6269 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6270 nullptr, pixels);
6271}
6272
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006273bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006274{
6275 return ValidateTexParameterBase(context, target, pname, -1, &param);
6276}
6277
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006278bool ValidateTexParameterfv(Context *context,
6279 TextureType target,
6280 GLenum pname,
6281 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006282{
6283 return ValidateTexParameterBase(context, target, pname, -1, params);
6284}
6285
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006286bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006287{
6288 return ValidateTexParameterBase(context, target, pname, -1, &param);
6289}
6290
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006291bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006292{
6293 return ValidateTexParameterBase(context, target, pname, -1, params);
6294}
6295
6296bool ValidateUseProgram(Context *context, GLuint program)
6297{
6298 if (program != 0)
6299 {
6300 Program *programObject = context->getProgram(program);
6301 if (!programObject)
6302 {
6303 // ES 3.1.0 section 7.3 page 72
6304 if (context->getShader(program))
6305 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006306 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006307 return false;
6308 }
6309 else
6310 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006311 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006312 return false;
6313 }
6314 }
6315 if (!programObject->isLinked())
6316 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006317 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006318 return false;
6319 }
6320 }
6321 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6322 {
6323 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006324 context
6325 ->handleError(InvalidOperation()
6326 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006327 return false;
6328 }
6329
6330 return true;
6331}
6332
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006333bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6334{
6335 if (!context->getExtensions().fence)
6336 {
6337 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6338 return false;
6339 }
6340
6341 if (n < 0)
6342 {
6343 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6344 return false;
6345 }
6346
6347 return true;
6348}
6349
6350bool ValidateFinishFenceNV(Context *context, GLuint fence)
6351{
6352 if (!context->getExtensions().fence)
6353 {
6354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6355 return false;
6356 }
6357
6358 FenceNV *fenceObject = context->getFenceNV(fence);
6359
6360 if (fenceObject == nullptr)
6361 {
6362 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6363 return false;
6364 }
6365
6366 if (!fenceObject->isSet())
6367 {
6368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6369 return false;
6370 }
6371
6372 return true;
6373}
6374
6375bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6376{
6377 if (!context->getExtensions().fence)
6378 {
6379 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6380 return false;
6381 }
6382
6383 if (n < 0)
6384 {
6385 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6386 return false;
6387 }
6388
6389 return true;
6390}
6391
6392bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6393{
6394 if (!context->getExtensions().fence)
6395 {
6396 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6397 return false;
6398 }
6399
6400 FenceNV *fenceObject = context->getFenceNV(fence);
6401
6402 if (fenceObject == nullptr)
6403 {
6404 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6405 return false;
6406 }
6407
6408 if (!fenceObject->isSet())
6409 {
6410 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6411 return false;
6412 }
6413
6414 switch (pname)
6415 {
6416 case GL_FENCE_STATUS_NV:
6417 case GL_FENCE_CONDITION_NV:
6418 break;
6419
6420 default:
6421 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6422 return false;
6423 }
6424
6425 return true;
6426}
6427
6428bool ValidateGetGraphicsResetStatusEXT(Context *context)
6429{
6430 if (!context->getExtensions().robustness)
6431 {
6432 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6433 return false;
6434 }
6435
6436 return true;
6437}
6438
6439bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6440 GLuint shader,
6441 GLsizei bufsize,
6442 GLsizei *length,
6443 GLchar *source)
6444{
6445 if (!context->getExtensions().translatedShaderSource)
6446 {
6447 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6448 return false;
6449 }
6450
6451 if (bufsize < 0)
6452 {
6453 context->handleError(InvalidValue());
6454 return false;
6455 }
6456
6457 Shader *shaderObject = context->getShader(shader);
6458
6459 if (!shaderObject)
6460 {
6461 context->handleError(InvalidOperation());
6462 return false;
6463 }
6464
6465 return true;
6466}
6467
6468bool ValidateIsFenceNV(Context *context, GLuint fence)
6469{
6470 if (!context->getExtensions().fence)
6471 {
6472 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6473 return false;
6474 }
6475
6476 return true;
6477}
6478
Jamie Madill007530e2017-12-28 14:27:04 -05006479bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6480{
6481 if (!context->getExtensions().fence)
6482 {
6483 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6484 return false;
6485 }
6486
6487 if (condition != GL_ALL_COMPLETED_NV)
6488 {
6489 context->handleError(InvalidEnum());
6490 return false;
6491 }
6492
6493 FenceNV *fenceObject = context->getFenceNV(fence);
6494
6495 if (fenceObject == nullptr)
6496 {
6497 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6498 return false;
6499 }
6500
6501 return true;
6502}
6503
6504bool ValidateTestFenceNV(Context *context, GLuint fence)
6505{
6506 if (!context->getExtensions().fence)
6507 {
6508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6509 return false;
6510 }
6511
6512 FenceNV *fenceObject = context->getFenceNV(fence);
6513
6514 if (fenceObject == nullptr)
6515 {
6516 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6517 return false;
6518 }
6519
6520 if (fenceObject->isSet() != GL_TRUE)
6521 {
6522 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6523 return false;
6524 }
6525
6526 return true;
6527}
6528
6529bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006530 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006531 GLsizei levels,
6532 GLenum internalformat,
6533 GLsizei width,
6534 GLsizei height)
6535{
6536 if (!context->getExtensions().textureStorage)
6537 {
6538 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6539 return false;
6540 }
6541
6542 if (context->getClientMajorVersion() < 3)
6543 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006544 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006545 height);
6546 }
6547
6548 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006549 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006550 1);
6551}
6552
6553bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6554{
6555 if (!context->getExtensions().instancedArrays)
6556 {
6557 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6558 return false;
6559 }
6560
6561 if (index >= MAX_VERTEX_ATTRIBS)
6562 {
6563 context->handleError(InvalidValue());
6564 return false;
6565 }
6566
6567 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6568 {
6569 if (index == 0 && divisor != 0)
6570 {
6571 const char *errorMessage =
6572 "The current context doesn't support setting a non-zero divisor on the "
6573 "attribute with index zero. "
6574 "Please reorder the attributes in your vertex shader so that attribute zero "
6575 "can have a zero divisor.";
6576 context->handleError(InvalidOperation() << errorMessage);
6577
6578 // We also output an error message to the debugger window if tracing is active, so
6579 // that developers can see the error message.
6580 ERR() << errorMessage;
6581 return false;
6582 }
6583 }
6584
6585 return true;
6586}
6587
6588bool ValidateTexImage3DOES(Context *context,
6589 GLenum target,
6590 GLint level,
6591 GLenum internalformat,
6592 GLsizei width,
6593 GLsizei height,
6594 GLsizei depth,
6595 GLint border,
6596 GLenum format,
6597 GLenum type,
6598 const void *pixels)
6599{
6600 UNIMPLEMENTED(); // FIXME
6601 return false;
6602}
6603
6604bool ValidatePopGroupMarkerEXT(Context *context)
6605{
6606 if (!context->getExtensions().debugMarker)
6607 {
6608 // The debug marker calls should not set error state
6609 // However, it seems reasonable to set an error state if the extension is not enabled
6610 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6611 return false;
6612 }
6613
6614 return true;
6615}
6616
Jamie Madillfa920eb2018-01-04 11:45:50 -05006617bool ValidateTexStorage1DEXT(Context *context,
6618 GLenum target,
6619 GLsizei levels,
6620 GLenum internalformat,
6621 GLsizei width)
6622{
6623 UNIMPLEMENTED();
6624 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6625 return false;
6626}
6627
6628bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006629 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006630 GLsizei levels,
6631 GLenum internalformat,
6632 GLsizei width,
6633 GLsizei height,
6634 GLsizei depth)
6635{
6636 if (!context->getExtensions().textureStorage)
6637 {
6638 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6639 return false;
6640 }
6641
6642 if (context->getClientMajorVersion() < 3)
6643 {
6644 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6645 return false;
6646 }
6647
6648 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6649 depth);
6650}
6651
Jamie Madillc29968b2016-01-20 11:17:23 -05006652} // namespace gl