blob: 0e87fc448edd734934eef360ec841c4aa0c597b1 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070078 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030079 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madill5b772312018-03-08 20:28:32 -0500458bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700795 // GLES1 emulation: GLES1-specific caps
796 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700797 case GL_VERTEX_ARRAY:
798 case GL_NORMAL_ARRAY:
799 case GL_COLOR_ARRAY:
800 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700801 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700802 case GL_LIGHTING:
803 case GL_LIGHT0:
804 case GL_LIGHT1:
805 case GL_LIGHT2:
806 case GL_LIGHT3:
807 case GL_LIGHT4:
808 case GL_LIGHT5:
809 case GL_LIGHT6:
810 case GL_LIGHT7:
811 case GL_NORMALIZE:
812 case GL_RESCALE_NORMAL:
813 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700814 case GL_CLIP_PLANE0:
815 case GL_CLIP_PLANE1:
816 case GL_CLIP_PLANE2:
817 case GL_CLIP_PLANE3:
818 case GL_CLIP_PLANE4:
819 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700820 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700821 case GL_POINT_SMOOTH:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700822 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700823 case GL_POINT_SIZE_ARRAY_OES:
824 return context->getClientVersion() < Version(2, 0) &&
825 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700826 case GL_TEXTURE_CUBE_MAP:
827 return context->getClientVersion() < Version(2, 0) &&
828 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700829 case GL_POINT_SPRITE_OES:
830 return context->getClientVersion() < Version(2, 0) &&
831 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400832 default:
833 return false;
834 }
835}
836
Geoff Langfc32e8b2017-05-31 14:16:59 -0400837// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
838// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400839bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400840{
841 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400842 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
843 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400844 {
845 return true;
846 }
847
848 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
849 if (c >= 9 && c <= 13)
850 {
851 return true;
852 }
853
854 return false;
855}
856
Geoff Langcab92ee2017-07-19 17:32:07 -0400857bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400858{
Geoff Langa71a98e2017-06-19 15:15:00 -0400859 for (size_t i = 0; i < len; i++)
860 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400861 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400862 {
863 return false;
864 }
865 }
866
867 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400868}
869
Geoff Langcab92ee2017-07-19 17:32:07 -0400870bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
871{
872 enum class ParseState
873 {
874 // Have not seen an ASCII non-whitespace character yet on
875 // this line. Possible that we might see a preprocessor
876 // directive.
877 BEGINING_OF_LINE,
878
879 // Have seen at least one ASCII non-whitespace character
880 // on this line.
881 MIDDLE_OF_LINE,
882
883 // Handling a preprocessor directive. Passes through all
884 // characters up to the end of the line. Disables comment
885 // processing.
886 IN_PREPROCESSOR_DIRECTIVE,
887
888 // Handling a single-line comment. The comment text is
889 // replaced with a single space.
890 IN_SINGLE_LINE_COMMENT,
891
892 // Handling a multi-line comment. Newlines are passed
893 // through to preserve line numbers.
894 IN_MULTI_LINE_COMMENT
895 };
896
897 ParseState state = ParseState::BEGINING_OF_LINE;
898 size_t pos = 0;
899
900 while (pos < len)
901 {
902 char c = str[pos];
903 char next = pos + 1 < len ? str[pos + 1] : 0;
904
905 // Check for newlines
906 if (c == '\n' || c == '\r')
907 {
908 if (state != ParseState::IN_MULTI_LINE_COMMENT)
909 {
910 state = ParseState::BEGINING_OF_LINE;
911 }
912
913 pos++;
914 continue;
915 }
916
917 switch (state)
918 {
919 case ParseState::BEGINING_OF_LINE:
920 if (c == ' ')
921 {
922 // Maintain the BEGINING_OF_LINE state until a non-space is seen
923 pos++;
924 }
925 else if (c == '#')
926 {
927 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
928 pos++;
929 }
930 else
931 {
932 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
933 state = ParseState::MIDDLE_OF_LINE;
934 }
935 break;
936
937 case ParseState::MIDDLE_OF_LINE:
938 if (c == '/' && next == '/')
939 {
940 state = ParseState::IN_SINGLE_LINE_COMMENT;
941 pos++;
942 }
943 else if (c == '/' && next == '*')
944 {
945 state = ParseState::IN_MULTI_LINE_COMMENT;
946 pos++;
947 }
948 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
949 {
950 // Skip line continuation characters
951 }
952 else if (!IsValidESSLCharacter(c))
953 {
954 return false;
955 }
956 pos++;
957 break;
958
959 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700960 // Line-continuation characters may not be permitted.
961 // Otherwise, just pass it through. Do not parse comments in this state.
962 if (!lineContinuationAllowed && c == '\\')
963 {
964 return false;
965 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400966 pos++;
967 break;
968
969 case ParseState::IN_SINGLE_LINE_COMMENT:
970 // Line-continuation characters are processed before comment processing.
971 // Advance string if a new line character is immediately behind
972 // line-continuation character.
973 if (c == '\\' && (next == '\n' || next == '\r'))
974 {
975 pos++;
976 }
977 pos++;
978 break;
979
980 case ParseState::IN_MULTI_LINE_COMMENT:
981 if (c == '*' && next == '/')
982 {
983 state = ParseState::MIDDLE_OF_LINE;
984 pos++;
985 }
986 pos++;
987 break;
988 }
989 }
990
991 return true;
992}
993
Jamie Madill5b772312018-03-08 20:28:32 -0500994bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700995{
996 ASSERT(context->isWebGL());
997
998 // WebGL 1.0 [Section 6.16] GLSL Constructs
999 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1000 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1001 {
1002 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1003 return false;
1004 }
1005
1006 return true;
1007}
1008
Jamie Madill5b772312018-03-08 20:28:32 -05001009bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001010{
1011 ASSERT(context->isWebGL());
1012
1013 if (context->isWebGL1() && length > 256)
1014 {
1015 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1016 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1017 // locations.
1018 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1019
1020 return false;
1021 }
1022 else if (length > 1024)
1023 {
1024 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1025 // uniform and attribute locations.
1026 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1027 return false;
1028 }
1029
1030 return true;
1031}
1032
Jamie Madill007530e2017-12-28 14:27:04 -05001033bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1034{
1035 if (!context->getExtensions().pathRendering)
1036 {
1037 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1038 return false;
1039 }
1040
1041 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1042 {
1043 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1044 return false;
1045 }
1046 return true;
1047}
Jamie Madillc29968b2016-01-20 11:17:23 -05001048} // anonymous namespace
1049
Geoff Langff5b2d52016-09-07 11:32:23 -04001050bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001051 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001052 GLint level,
1053 GLenum internalformat,
1054 bool isCompressed,
1055 bool isSubImage,
1056 GLint xoffset,
1057 GLint yoffset,
1058 GLsizei width,
1059 GLsizei height,
1060 GLint border,
1061 GLenum format,
1062 GLenum type,
1063 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001064 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001065{
Jamie Madill6f38f822014-06-06 17:12:20 -04001066 if (!ValidTexture2DDestinationTarget(context, target))
1067 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001068 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001069 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001070 }
1071
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001072 TextureType texType = TextureTargetToType(target);
1073 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001075 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001076 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001077 }
1078
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001079 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001080 {
1081 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1082 return false;
1083 }
1084
1085 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001086 std::numeric_limits<GLsizei>::max() - yoffset < height)
1087 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001088 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001089 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001090 }
1091
Geoff Lang6e898aa2017-06-02 11:17:26 -04001092 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1093 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1094 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1095 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1096 // case.
1097 bool nonEqualFormatsAllowed =
1098 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1099 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1100
1101 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001103 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001104 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001105 }
1106
Geoff Langaae65a42014-05-26 12:43:44 -04001107 const gl::Caps &caps = context->getCaps();
1108
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001109 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001110 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001111 case TextureType::_2D:
1112 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1113 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1114 {
1115 context->handleError(InvalidValue());
1116 return false;
1117 }
1118 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001119
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001120 case TextureType::Rectangle:
1121 ASSERT(level == 0);
1122 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1123 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1124 {
1125 context->handleError(InvalidValue());
1126 return false;
1127 }
1128 if (isCompressed)
1129 {
1130 context->handleError(InvalidEnum()
1131 << "Rectangle texture cannot have a compressed format.");
1132 return false;
1133 }
1134 break;
1135
1136 case TextureType::CubeMap:
1137 if (!isSubImage && width != height)
1138 {
1139 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1140 return false;
1141 }
1142
1143 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1144 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1145 {
1146 context->handleError(InvalidValue());
1147 return false;
1148 }
1149 break;
1150
1151 default:
1152 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001153 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001154 }
1155
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001156 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001157 if (!texture)
1158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001160 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001161 }
1162
Geoff Langa9be0dc2014-12-17 12:34:40 -05001163 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001164 {
Geoff Langca271392017-04-05 12:30:00 -04001165 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1166 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001168 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001169 return false;
1170 }
1171
Geoff Langa9be0dc2014-12-17 12:34:40 -05001172 if (format != GL_NONE)
1173 {
Geoff Langca271392017-04-05 12:30:00 -04001174 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1175 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001176 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001177 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001178 return false;
1179 }
1180 }
1181
1182 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1183 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001185 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001186 return false;
1187 }
Geoff Langfb052642017-10-24 13:42:09 -04001188
1189 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001190 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001191 {
1192 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1193 return false;
1194 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001195 }
1196 else
1197 {
Geoff Lang69cce582015-09-17 13:20:36 -04001198 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001200 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001201 return false;
1202 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001203 }
1204
1205 // Verify zero border
1206 if (border != 0)
1207 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001208 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001209 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001210 }
1211
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001212 if (isCompressed)
1213 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001214 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001215 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1216 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001217
1218 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1219
1220 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001221 {
Geoff Lange88e4542018-05-03 15:05:57 -04001222 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1223 return false;
1224 }
1225
1226 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1227 context->getExtensions()))
1228 {
1229 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1230 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001231 }
Geoff Lang966c9402017-04-18 12:38:27 -04001232
1233 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001234 {
Geoff Lange88e4542018-05-03 15:05:57 -04001235 // From the OES_compressed_ETC1_RGB8_texture spec:
1236 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1237 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1238 // ETC1_RGB8_OES.
1239 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1240 {
1241 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1242 return false;
1243 }
1244
Geoff Lang966c9402017-04-18 12:38:27 -04001245 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1246 height, texture->getWidth(target, level),
1247 texture->getHeight(target, level)))
1248 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001249 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001250 return false;
1251 }
1252
1253 if (format != actualInternalFormat)
1254 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001255 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001256 return false;
1257 }
1258 }
1259 else
1260 {
1261 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1262 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001263 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001264 return false;
1265 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001266 }
1267 }
1268 else
1269 {
1270 // validate <type> by itself (used as secondary key below)
1271 switch (type)
1272 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001273 case GL_UNSIGNED_BYTE:
1274 case GL_UNSIGNED_SHORT_5_6_5:
1275 case GL_UNSIGNED_SHORT_4_4_4_4:
1276 case GL_UNSIGNED_SHORT_5_5_5_1:
1277 case GL_UNSIGNED_SHORT:
1278 case GL_UNSIGNED_INT:
1279 case GL_UNSIGNED_INT_24_8_OES:
1280 case GL_HALF_FLOAT_OES:
1281 case GL_FLOAT:
1282 break;
1283 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001284 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001285 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001286 }
1287
1288 // validate <format> + <type> combinations
1289 // - invalid <format> -> sets INVALID_ENUM
1290 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1291 switch (format)
1292 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001293 case GL_ALPHA:
1294 case GL_LUMINANCE:
1295 case GL_LUMINANCE_ALPHA:
1296 switch (type)
1297 {
1298 case GL_UNSIGNED_BYTE:
1299 case GL_FLOAT:
1300 case GL_HALF_FLOAT_OES:
1301 break;
1302 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001303 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001304 return false;
1305 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001306 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001307 case GL_RED:
1308 case GL_RG:
1309 if (!context->getExtensions().textureRG)
1310 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001311 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001312 return false;
1313 }
1314 switch (type)
1315 {
1316 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001317 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001318 case GL_FLOAT:
1319 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001320 if (!context->getExtensions().textureFloat)
1321 {
1322 context->handleError(InvalidEnum());
1323 return false;
1324 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001325 break;
1326 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001327 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001328 return false;
1329 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001330 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001331 case GL_RGB:
1332 switch (type)
1333 {
1334 case GL_UNSIGNED_BYTE:
1335 case GL_UNSIGNED_SHORT_5_6_5:
1336 case GL_FLOAT:
1337 case GL_HALF_FLOAT_OES:
1338 break;
1339 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001340 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001341 return false;
1342 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001343 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001344 case GL_RGBA:
1345 switch (type)
1346 {
1347 case GL_UNSIGNED_BYTE:
1348 case GL_UNSIGNED_SHORT_4_4_4_4:
1349 case GL_UNSIGNED_SHORT_5_5_5_1:
1350 case GL_FLOAT:
1351 case GL_HALF_FLOAT_OES:
1352 break;
1353 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001355 return false;
1356 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001357 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001358 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001359 if (!context->getExtensions().textureFormatBGRA8888)
1360 {
1361 context->handleError(InvalidEnum());
1362 return false;
1363 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001364 switch (type)
1365 {
1366 case GL_UNSIGNED_BYTE:
1367 break;
1368 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001369 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001370 return false;
1371 }
1372 break;
1373 case GL_SRGB_EXT:
1374 case GL_SRGB_ALPHA_EXT:
1375 if (!context->getExtensions().sRGB)
1376 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001377 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001378 return false;
1379 }
1380 switch (type)
1381 {
1382 case GL_UNSIGNED_BYTE:
1383 break;
1384 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001385 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001386 return false;
1387 }
1388 break;
1389 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1390 // handled below
1391 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1392 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1393 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1394 break;
1395 case GL_DEPTH_COMPONENT:
1396 switch (type)
1397 {
1398 case GL_UNSIGNED_SHORT:
1399 case GL_UNSIGNED_INT:
1400 break;
1401 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001402 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001403 return false;
1404 }
1405 break;
1406 case GL_DEPTH_STENCIL_OES:
1407 switch (type)
1408 {
1409 case GL_UNSIGNED_INT_24_8_OES:
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 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001417 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001418 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001419 }
1420
1421 switch (format)
1422 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001423 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1424 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1425 if (context->getExtensions().textureCompressionDXT1)
1426 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001427 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001428 return false;
1429 }
1430 else
1431 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001432 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 return false;
1434 }
1435 break;
1436 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1437 if (context->getExtensions().textureCompressionDXT3)
1438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001439 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001440 return false;
1441 }
1442 else
1443 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001444 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001445 return false;
1446 }
1447 break;
1448 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1449 if (context->getExtensions().textureCompressionDXT5)
1450 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001451 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001452 return false;
1453 }
1454 else
1455 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001456 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001457 return false;
1458 }
1459 break;
1460 case GL_ETC1_RGB8_OES:
1461 if (context->getExtensions().compressedETC1RGB8Texture)
1462 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001463 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001464 return false;
1465 }
1466 else
1467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001468 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001469 return false;
1470 }
1471 break;
1472 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001473 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1474 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1475 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1476 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001477 if (context->getExtensions().lossyETCDecode)
1478 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001479 context->handleError(InvalidOperation()
1480 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001481 return false;
1482 }
1483 else
1484 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001485 context->handleError(InvalidEnum()
1486 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 return false;
1488 }
1489 break;
1490 case GL_DEPTH_COMPONENT:
1491 case GL_DEPTH_STENCIL_OES:
1492 if (!context->getExtensions().depthTextures)
1493 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001494 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001495 return false;
1496 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001497 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001498 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001499 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001500 return false;
1501 }
1502 // OES_depth_texture supports loading depth data and multiple levels,
1503 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001504 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001505 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001506 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1507 return false;
1508 }
1509 if (level != 0)
1510 {
1511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001512 return false;
1513 }
1514 break;
1515 default:
1516 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001517 }
1518
Geoff Lang6e898aa2017-06-02 11:17:26 -04001519 if (!isSubImage)
1520 {
1521 switch (internalformat)
1522 {
1523 case GL_RGBA32F:
1524 if (!context->getExtensions().colorBufferFloatRGBA)
1525 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001526 context->handleError(InvalidValue()
1527 << "Sized GL_RGBA32F internal format requires "
1528 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001529 return false;
1530 }
1531 if (type != GL_FLOAT)
1532 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001533 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001534 return false;
1535 }
1536 if (format != GL_RGBA)
1537 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001538 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001539 return false;
1540 }
1541 break;
1542
1543 case GL_RGB32F:
1544 if (!context->getExtensions().colorBufferFloatRGB)
1545 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001546 context->handleError(InvalidValue()
1547 << "Sized GL_RGB32F internal format requires "
1548 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001549 return false;
1550 }
1551 if (type != GL_FLOAT)
1552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001553 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001554 return false;
1555 }
1556 if (format != GL_RGB)
1557 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001558 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001559 return false;
1560 }
1561 break;
1562
1563 default:
1564 break;
1565 }
1566 }
1567
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001568 if (type == GL_FLOAT)
1569 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001570 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001571 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001572 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001573 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001574 }
1575 }
1576 else if (type == GL_HALF_FLOAT_OES)
1577 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001578 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001579 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001580 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001581 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001582 }
1583 }
1584 }
1585
Geoff Langdbcced82017-06-06 15:55:54 -04001586 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001587 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001588 imageSize))
1589 {
1590 return false;
1591 }
1592
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001593 return true;
1594}
1595
He Yunchaoced53ae2016-11-29 15:00:51 +08001596bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001597 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001598 GLsizei levels,
1599 GLenum internalformat,
1600 GLsizei width,
1601 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001602{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001603 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1604 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001605 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001606 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001607 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001608 }
1609
1610 if (width < 1 || height < 1 || levels < 1)
1611 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001612 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001613 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001614 }
1615
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001616 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001617 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001618 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001619 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001620 }
1621
1622 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1623 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001624 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001625 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001626 }
1627
Geoff Langca271392017-04-05 12:30:00 -04001628 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001629 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001630 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001631 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001632 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 }
1634
Geoff Langaae65a42014-05-26 12:43:44 -04001635 const gl::Caps &caps = context->getCaps();
1636
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001637 switch (target)
1638 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001639 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001640 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1641 static_cast<GLuint>(height) > caps.max2DTextureSize)
1642 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001643 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001644 return false;
1645 }
1646 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001647 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001648 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1649 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1650 {
1651 context->handleError(InvalidValue());
1652 return false;
1653 }
1654 if (formatInfo.compressed)
1655 {
1656 context->handleError(InvalidEnum()
1657 << "Rectangle texture cannot have a compressed format.");
1658 return false;
1659 }
1660 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001661 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001662 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1663 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1664 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001665 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001666 return false;
1667 }
1668 break;
1669 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001670 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001671 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001672 }
1673
Geoff Langc0b9ef42014-07-02 10:02:37 -04001674 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001675 {
1676 if (!gl::isPow2(width) || !gl::isPow2(height))
1677 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001678 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001679 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001680 }
1681 }
1682
1683 switch (internalformat)
1684 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001685 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1686 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1687 if (!context->getExtensions().textureCompressionDXT1)
1688 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001689 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001690 return false;
1691 }
1692 break;
1693 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1694 if (!context->getExtensions().textureCompressionDXT3)
1695 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001696 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001697 return false;
1698 }
1699 break;
1700 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1701 if (!context->getExtensions().textureCompressionDXT5)
1702 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001703 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001704 return false;
1705 }
1706 break;
1707 case GL_ETC1_RGB8_OES:
1708 if (!context->getExtensions().compressedETC1RGB8Texture)
1709 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001710 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001711 return false;
1712 }
1713 break;
1714 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001715 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1716 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1717 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1718 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001719 if (!context->getExtensions().lossyETCDecode)
1720 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001721 context->handleError(InvalidEnum()
1722 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001723 return false;
1724 }
1725 break;
1726 case GL_RGBA32F_EXT:
1727 case GL_RGB32F_EXT:
1728 case GL_ALPHA32F_EXT:
1729 case GL_LUMINANCE32F_EXT:
1730 case GL_LUMINANCE_ALPHA32F_EXT:
1731 if (!context->getExtensions().textureFloat)
1732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001733 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001734 return false;
1735 }
1736 break;
1737 case GL_RGBA16F_EXT:
1738 case GL_RGB16F_EXT:
1739 case GL_ALPHA16F_EXT:
1740 case GL_LUMINANCE16F_EXT:
1741 case GL_LUMINANCE_ALPHA16F_EXT:
1742 if (!context->getExtensions().textureHalfFloat)
1743 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001744 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001745 return false;
1746 }
1747 break;
1748 case GL_R8_EXT:
1749 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001750 if (!context->getExtensions().textureRG)
1751 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001752 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001753 return false;
1754 }
1755 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001756 case GL_R16F_EXT:
1757 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001758 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1759 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001760 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001761 return false;
1762 }
1763 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001764 case GL_R32F_EXT:
1765 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001766 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001767 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001768 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 return false;
1770 }
1771 break;
1772 case GL_DEPTH_COMPONENT16:
1773 case GL_DEPTH_COMPONENT32_OES:
1774 case GL_DEPTH24_STENCIL8_OES:
1775 if (!context->getExtensions().depthTextures)
1776 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001777 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001778 return false;
1779 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001780 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001781 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001782 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001783 return false;
1784 }
1785 // ANGLE_depth_texture only supports 1-level textures
1786 if (levels != 1)
1787 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001788 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001789 return false;
1790 }
1791 break;
1792 default:
1793 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001794 }
1795
Geoff Lang691e58c2014-12-19 17:03:25 -05001796 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001797 if (!texture || texture->id() == 0)
1798 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001799 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001800 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001801 }
1802
Geoff Lang69cce582015-09-17 13:20:36 -04001803 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001804 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001805 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001806 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001807 }
1808
1809 return true;
1810}
1811
He Yunchaoced53ae2016-11-29 15:00:51 +08001812bool ValidateDiscardFramebufferEXT(Context *context,
1813 GLenum target,
1814 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001815 const GLenum *attachments)
1816{
Jamie Madillc29968b2016-01-20 11:17:23 -05001817 if (!context->getExtensions().discardFramebuffer)
1818 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001819 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001820 return false;
1821 }
1822
Austin Kinross08332632015-05-05 13:35:47 -07001823 bool defaultFramebuffer = false;
1824
1825 switch (target)
1826 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001827 case GL_FRAMEBUFFER:
1828 defaultFramebuffer =
1829 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1830 break;
1831 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001832 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001833 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001834 }
1835
He Yunchaoced53ae2016-11-29 15:00:51 +08001836 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1837 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001838}
1839
Austin Kinrossbc781f32015-10-26 09:27:38 -07001840bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1841{
1842 if (!context->getExtensions().vertexArrayObject)
1843 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001844 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001845 return false;
1846 }
1847
1848 return ValidateBindVertexArrayBase(context, array);
1849}
1850
Jamie Madilld7576732017-08-26 18:49:50 -04001851bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001852{
1853 if (!context->getExtensions().vertexArrayObject)
1854 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001855 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001856 return false;
1857 }
1858
Olli Etuaho41997e72016-03-10 13:38:39 +02001859 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001860}
1861
Jamie Madilld7576732017-08-26 18:49:50 -04001862bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001863{
1864 if (!context->getExtensions().vertexArrayObject)
1865 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001866 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001867 return false;
1868 }
1869
Olli Etuaho41997e72016-03-10 13:38:39 +02001870 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001871}
1872
Jamie Madilld7576732017-08-26 18:49:50 -04001873bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001874{
1875 if (!context->getExtensions().vertexArrayObject)
1876 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001877 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001878 return false;
1879 }
1880
1881 return true;
1882}
Geoff Langc5629752015-12-07 16:29:04 -05001883
1884bool ValidateProgramBinaryOES(Context *context,
1885 GLuint program,
1886 GLenum binaryFormat,
1887 const void *binary,
1888 GLint length)
1889{
1890 if (!context->getExtensions().getProgramBinary)
1891 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001892 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001893 return false;
1894 }
1895
1896 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1897}
1898
1899bool ValidateGetProgramBinaryOES(Context *context,
1900 GLuint program,
1901 GLsizei bufSize,
1902 GLsizei *length,
1903 GLenum *binaryFormat,
1904 void *binary)
1905{
1906 if (!context->getExtensions().getProgramBinary)
1907 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001908 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001909 return false;
1910 }
1911
1912 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1913}
Geoff Lange102fee2015-12-10 11:23:30 -05001914
Geoff Lang70d0f492015-12-10 17:45:46 -05001915static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1916{
1917 switch (source)
1918 {
1919 case GL_DEBUG_SOURCE_API:
1920 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1921 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1922 case GL_DEBUG_SOURCE_OTHER:
1923 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1924 return !mustBeThirdPartyOrApplication;
1925
1926 case GL_DEBUG_SOURCE_THIRD_PARTY:
1927 case GL_DEBUG_SOURCE_APPLICATION:
1928 return true;
1929
1930 default:
1931 return false;
1932 }
1933}
1934
1935static bool ValidDebugType(GLenum type)
1936{
1937 switch (type)
1938 {
1939 case GL_DEBUG_TYPE_ERROR:
1940 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1941 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1942 case GL_DEBUG_TYPE_PERFORMANCE:
1943 case GL_DEBUG_TYPE_PORTABILITY:
1944 case GL_DEBUG_TYPE_OTHER:
1945 case GL_DEBUG_TYPE_MARKER:
1946 case GL_DEBUG_TYPE_PUSH_GROUP:
1947 case GL_DEBUG_TYPE_POP_GROUP:
1948 return true;
1949
1950 default:
1951 return false;
1952 }
1953}
1954
1955static bool ValidDebugSeverity(GLenum severity)
1956{
1957 switch (severity)
1958 {
1959 case GL_DEBUG_SEVERITY_HIGH:
1960 case GL_DEBUG_SEVERITY_MEDIUM:
1961 case GL_DEBUG_SEVERITY_LOW:
1962 case GL_DEBUG_SEVERITY_NOTIFICATION:
1963 return true;
1964
1965 default:
1966 return false;
1967 }
1968}
1969
Geoff Lange102fee2015-12-10 11:23:30 -05001970bool ValidateDebugMessageControlKHR(Context *context,
1971 GLenum source,
1972 GLenum type,
1973 GLenum severity,
1974 GLsizei count,
1975 const GLuint *ids,
1976 GLboolean enabled)
1977{
1978 if (!context->getExtensions().debug)
1979 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001980 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001981 return false;
1982 }
1983
Geoff Lang70d0f492015-12-10 17:45:46 -05001984 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1985 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001986 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001987 return false;
1988 }
1989
1990 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1991 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001992 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001993 return false;
1994 }
1995
1996 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1997 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001998 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001999 return false;
2000 }
2001
2002 if (count > 0)
2003 {
2004 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002006 context->handleError(
2007 InvalidOperation()
2008 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002009 return false;
2010 }
2011
2012 if (severity != GL_DONT_CARE)
2013 {
Jamie Madill437fa652016-05-03 15:13:24 -04002014 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002015 InvalidOperation()
2016 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002017 return false;
2018 }
2019 }
2020
Geoff Lange102fee2015-12-10 11:23:30 -05002021 return true;
2022}
2023
2024bool ValidateDebugMessageInsertKHR(Context *context,
2025 GLenum source,
2026 GLenum type,
2027 GLuint id,
2028 GLenum severity,
2029 GLsizei length,
2030 const GLchar *buf)
2031{
2032 if (!context->getExtensions().debug)
2033 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002034 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002035 return false;
2036 }
2037
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002038 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002039 {
2040 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2041 // not generate an error.
2042 return false;
2043 }
2044
2045 if (!ValidDebugSeverity(severity))
2046 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002047 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002048 return false;
2049 }
2050
2051 if (!ValidDebugType(type))
2052 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002053 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002054 return false;
2055 }
2056
2057 if (!ValidDebugSource(source, true))
2058 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002059 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002060 return false;
2061 }
2062
2063 size_t messageLength = (length < 0) ? strlen(buf) : length;
2064 if (messageLength > context->getExtensions().maxDebugMessageLength)
2065 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002066 context->handleError(InvalidValue()
2067 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002068 return false;
2069 }
2070
Geoff Lange102fee2015-12-10 11:23:30 -05002071 return true;
2072}
2073
2074bool ValidateDebugMessageCallbackKHR(Context *context,
2075 GLDEBUGPROCKHR callback,
2076 const void *userParam)
2077{
2078 if (!context->getExtensions().debug)
2079 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002081 return false;
2082 }
2083
Geoff Lange102fee2015-12-10 11:23:30 -05002084 return true;
2085}
2086
2087bool ValidateGetDebugMessageLogKHR(Context *context,
2088 GLuint count,
2089 GLsizei bufSize,
2090 GLenum *sources,
2091 GLenum *types,
2092 GLuint *ids,
2093 GLenum *severities,
2094 GLsizei *lengths,
2095 GLchar *messageLog)
2096{
2097 if (!context->getExtensions().debug)
2098 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002099 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002100 return false;
2101 }
2102
Geoff Lang70d0f492015-12-10 17:45:46 -05002103 if (bufSize < 0 && messageLog != nullptr)
2104 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002105 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002106 return false;
2107 }
2108
Geoff Lange102fee2015-12-10 11:23:30 -05002109 return true;
2110}
2111
2112bool ValidatePushDebugGroupKHR(Context *context,
2113 GLenum source,
2114 GLuint id,
2115 GLsizei length,
2116 const GLchar *message)
2117{
2118 if (!context->getExtensions().debug)
2119 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002120 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002121 return false;
2122 }
2123
Geoff Lang70d0f492015-12-10 17:45:46 -05002124 if (!ValidDebugSource(source, true))
2125 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002126 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002127 return false;
2128 }
2129
2130 size_t messageLength = (length < 0) ? strlen(message) : length;
2131 if (messageLength > context->getExtensions().maxDebugMessageLength)
2132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002133 context->handleError(InvalidValue()
2134 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002135 return false;
2136 }
2137
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002138 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002139 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2140 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002141 context
2142 ->handleError(StackOverflow()
2143 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002144 return false;
2145 }
2146
Geoff Lange102fee2015-12-10 11:23:30 -05002147 return true;
2148}
2149
2150bool ValidatePopDebugGroupKHR(Context *context)
2151{
2152 if (!context->getExtensions().debug)
2153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002155 return false;
2156 }
2157
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002158 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002159 if (currentStackSize <= 1)
2160 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002161 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002162 return false;
2163 }
2164
2165 return true;
2166}
2167
2168static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2169{
2170 switch (identifier)
2171 {
2172 case GL_BUFFER:
2173 if (context->getBuffer(name) == nullptr)
2174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002175 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002176 return false;
2177 }
2178 return true;
2179
2180 case GL_SHADER:
2181 if (context->getShader(name) == nullptr)
2182 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002183 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002184 return false;
2185 }
2186 return true;
2187
2188 case GL_PROGRAM:
2189 if (context->getProgram(name) == nullptr)
2190 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002191 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002192 return false;
2193 }
2194 return true;
2195
2196 case GL_VERTEX_ARRAY:
2197 if (context->getVertexArray(name) == nullptr)
2198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002199 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002200 return false;
2201 }
2202 return true;
2203
2204 case GL_QUERY:
2205 if (context->getQuery(name) == nullptr)
2206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002207 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002208 return false;
2209 }
2210 return true;
2211
2212 case GL_TRANSFORM_FEEDBACK:
2213 if (context->getTransformFeedback(name) == nullptr)
2214 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002215 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002216 return false;
2217 }
2218 return true;
2219
2220 case GL_SAMPLER:
2221 if (context->getSampler(name) == nullptr)
2222 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002223 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002224 return false;
2225 }
2226 return true;
2227
2228 case GL_TEXTURE:
2229 if (context->getTexture(name) == nullptr)
2230 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002231 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002232 return false;
2233 }
2234 return true;
2235
2236 case GL_RENDERBUFFER:
2237 if (context->getRenderbuffer(name) == nullptr)
2238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002239 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002240 return false;
2241 }
2242 return true;
2243
2244 case GL_FRAMEBUFFER:
2245 if (context->getFramebuffer(name) == nullptr)
2246 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002247 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002248 return false;
2249 }
2250 return true;
2251
2252 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002253 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002254 return false;
2255 }
Geoff Lange102fee2015-12-10 11:23:30 -05002256}
2257
Martin Radev9d901792016-07-15 15:58:58 +03002258static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2259{
2260 size_t labelLength = 0;
2261
2262 if (length < 0)
2263 {
2264 if (label != nullptr)
2265 {
2266 labelLength = strlen(label);
2267 }
2268 }
2269 else
2270 {
2271 labelLength = static_cast<size_t>(length);
2272 }
2273
2274 if (labelLength > context->getExtensions().maxLabelLength)
2275 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002276 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002277 return false;
2278 }
2279
2280 return true;
2281}
2282
Geoff Lange102fee2015-12-10 11:23:30 -05002283bool ValidateObjectLabelKHR(Context *context,
2284 GLenum identifier,
2285 GLuint name,
2286 GLsizei length,
2287 const GLchar *label)
2288{
2289 if (!context->getExtensions().debug)
2290 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002291 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002292 return false;
2293 }
2294
Geoff Lang70d0f492015-12-10 17:45:46 -05002295 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2296 {
2297 return false;
2298 }
2299
Martin Radev9d901792016-07-15 15:58:58 +03002300 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002301 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002302 return false;
2303 }
2304
Geoff Lange102fee2015-12-10 11:23:30 -05002305 return true;
2306}
2307
2308bool ValidateGetObjectLabelKHR(Context *context,
2309 GLenum identifier,
2310 GLuint name,
2311 GLsizei bufSize,
2312 GLsizei *length,
2313 GLchar *label)
2314{
2315 if (!context->getExtensions().debug)
2316 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002317 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002318 return false;
2319 }
2320
Geoff Lang70d0f492015-12-10 17:45:46 -05002321 if (bufSize < 0)
2322 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002323 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002324 return false;
2325 }
2326
2327 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2328 {
2329 return false;
2330 }
2331
Martin Radev9d901792016-07-15 15:58:58 +03002332 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002333}
2334
2335static bool ValidateObjectPtrName(Context *context, const void *ptr)
2336{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002337 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002338 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002339 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002340 return false;
2341 }
2342
Geoff Lange102fee2015-12-10 11:23:30 -05002343 return true;
2344}
2345
2346bool ValidateObjectPtrLabelKHR(Context *context,
2347 const void *ptr,
2348 GLsizei length,
2349 const GLchar *label)
2350{
2351 if (!context->getExtensions().debug)
2352 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002354 return false;
2355 }
2356
Geoff Lang70d0f492015-12-10 17:45:46 -05002357 if (!ValidateObjectPtrName(context, ptr))
2358 {
2359 return false;
2360 }
2361
Martin Radev9d901792016-07-15 15:58:58 +03002362 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002363 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002364 return false;
2365 }
2366
Geoff Lange102fee2015-12-10 11:23:30 -05002367 return true;
2368}
2369
2370bool ValidateGetObjectPtrLabelKHR(Context *context,
2371 const void *ptr,
2372 GLsizei bufSize,
2373 GLsizei *length,
2374 GLchar *label)
2375{
2376 if (!context->getExtensions().debug)
2377 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002378 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002379 return false;
2380 }
2381
Geoff Lang70d0f492015-12-10 17:45:46 -05002382 if (bufSize < 0)
2383 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002384 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002385 return false;
2386 }
2387
2388 if (!ValidateObjectPtrName(context, ptr))
2389 {
2390 return false;
2391 }
2392
Martin Radev9d901792016-07-15 15:58:58 +03002393 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002394}
2395
2396bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2397{
2398 if (!context->getExtensions().debug)
2399 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002401 return false;
2402 }
2403
Geoff Lang70d0f492015-12-10 17:45:46 -05002404 // TODO: represent this in Context::getQueryParameterInfo.
2405 switch (pname)
2406 {
2407 case GL_DEBUG_CALLBACK_FUNCTION:
2408 case GL_DEBUG_CALLBACK_USER_PARAM:
2409 break;
2410
2411 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002412 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002413 return false;
2414 }
2415
Geoff Lange102fee2015-12-10 11:23:30 -05002416 return true;
2417}
Jamie Madillc29968b2016-01-20 11:17:23 -05002418
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002419bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2420 GLenum pname,
2421 GLsizei bufSize,
2422 GLsizei *length,
2423 void **params)
2424{
2425 UNIMPLEMENTED();
2426 return false;
2427}
2428
Jamie Madillc29968b2016-01-20 11:17:23 -05002429bool ValidateBlitFramebufferANGLE(Context *context,
2430 GLint srcX0,
2431 GLint srcY0,
2432 GLint srcX1,
2433 GLint srcY1,
2434 GLint dstX0,
2435 GLint dstY0,
2436 GLint dstX1,
2437 GLint dstY1,
2438 GLbitfield mask,
2439 GLenum filter)
2440{
2441 if (!context->getExtensions().framebufferBlit)
2442 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002443 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002444 return false;
2445 }
2446
2447 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2448 {
2449 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002450 context->handleError(InvalidOperation() << "Scaling and flipping in "
2451 "BlitFramebufferANGLE not supported by this "
2452 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002453 return false;
2454 }
2455
2456 if (filter == GL_LINEAR)
2457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002458 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002459 return false;
2460 }
2461
Jamie Madill51f40ec2016-06-15 14:06:00 -04002462 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2463 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002464
2465 if (mask & GL_COLOR_BUFFER_BIT)
2466 {
2467 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2468 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2469
2470 if (readColorAttachment && drawColorAttachment)
2471 {
2472 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002473 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002474 readColorAttachment->type() != GL_RENDERBUFFER &&
2475 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2476 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002477 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002478 return false;
2479 }
2480
Geoff Langa15472a2015-08-11 11:48:03 -04002481 for (size_t drawbufferIdx = 0;
2482 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 {
Geoff Langa15472a2015-08-11 11:48:03 -04002484 const FramebufferAttachment *attachment =
2485 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2486 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002487 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002488 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002489 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002490 attachment->type() != GL_RENDERBUFFER &&
2491 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2492 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002493 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002494 return false;
2495 }
2496
2497 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002498 if (!Format::EquivalentForBlit(attachment->getFormat(),
2499 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002500 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002501 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002502 return false;
2503 }
2504 }
2505 }
2506
Jamie Madill427064d2018-04-13 16:20:34 -04002507 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002508 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002509 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2510 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2511 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002512 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002513 return false;
2514 }
2515 }
2516 }
2517
2518 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2519 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2520 for (size_t i = 0; i < 2; i++)
2521 {
2522 if (mask & masks[i])
2523 {
2524 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002525 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002526 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002527 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002528
2529 if (readBuffer && drawBuffer)
2530 {
2531 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2532 dstX0, dstY0, dstX1, dstY1))
2533 {
2534 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002535 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2536 "stencil blits are supported by "
2537 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 return false;
2539 }
2540
2541 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2542 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002543 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002544 return false;
2545 }
2546 }
2547 }
2548 }
2549
2550 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2551 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002552}
Jamie Madillc29968b2016-01-20 11:17:23 -05002553
Jamie Madill5b772312018-03-08 20:28:32 -05002554bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002555{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002556 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002557
Jamie Madill427064d2018-04-13 16:20:34 -04002558 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002559 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002560 return false;
2561 }
2562
2563 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2564 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002565 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002566 return false;
2567 }
2568
Geoff Lang76e65652017-03-27 14:58:02 -04002569 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2570 {
2571 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2572 GL_SIGNED_NORMALIZED};
2573
Corentin Wallez59c41592017-07-11 13:19:54 -04002574 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002575 drawBufferIdx++)
2576 {
2577 if (!ValidateWebGLFramebufferAttachmentClearType(
2578 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2579 {
2580 return false;
2581 }
2582 }
2583 }
2584
Jamie Madillc29968b2016-01-20 11:17:23 -05002585 return true;
2586}
2587
Jamie Madill5b772312018-03-08 20:28:32 -05002588bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002589{
2590 if (!context->getExtensions().drawBuffers)
2591 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002592 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002593 return false;
2594 }
2595
2596 return ValidateDrawBuffersBase(context, n, bufs);
2597}
2598
Jamie Madill73a84962016-02-12 09:27:23 -05002599bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002600 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002601 GLint level,
2602 GLint internalformat,
2603 GLsizei width,
2604 GLsizei height,
2605 GLint border,
2606 GLenum format,
2607 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002608 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002609{
Martin Radev1be913c2016-07-11 17:59:16 +03002610 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002611 {
2612 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002613 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002614 }
2615
Martin Radev1be913c2016-07-11 17:59:16 +03002616 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002617 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002618 0, 0, width, height, 1, border, format, type, -1,
2619 pixels);
2620}
2621
Brandon Jones416aaf92018-04-10 08:10:16 -07002622bool ValidateTexImage2DRobustANGLE(Context *context,
2623 TextureTarget target,
2624 GLint level,
2625 GLint internalformat,
2626 GLsizei width,
2627 GLsizei height,
2628 GLint border,
2629 GLenum format,
2630 GLenum type,
2631 GLsizei bufSize,
2632 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002633{
2634 if (!ValidateRobustEntryPoint(context, bufSize))
2635 {
2636 return false;
2637 }
2638
2639 if (context->getClientMajorVersion() < 3)
2640 {
2641 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2642 0, 0, width, height, border, format, type, bufSize,
2643 pixels);
2644 }
2645
2646 ASSERT(context->getClientMajorVersion() >= 3);
2647 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2648 0, 0, width, height, 1, border, format, type, bufSize,
2649 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002650}
2651
2652bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002653 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002654 GLint level,
2655 GLint xoffset,
2656 GLint yoffset,
2657 GLsizei width,
2658 GLsizei height,
2659 GLenum format,
2660 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002661 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002662{
2663
Martin Radev1be913c2016-07-11 17:59:16 +03002664 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002665 {
2666 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002667 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002668 }
2669
Martin Radev1be913c2016-07-11 17:59:16 +03002670 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002671 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002672 yoffset, 0, width, height, 1, 0, format, type, -1,
2673 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002674}
2675
Geoff Langc52f6f12016-10-14 10:18:00 -04002676bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002677 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002678 GLint level,
2679 GLint xoffset,
2680 GLint yoffset,
2681 GLsizei width,
2682 GLsizei height,
2683 GLenum format,
2684 GLenum type,
2685 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002686 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002687{
2688 if (!ValidateRobustEntryPoint(context, bufSize))
2689 {
2690 return false;
2691 }
2692
2693 if (context->getClientMajorVersion() < 3)
2694 {
2695 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2696 yoffset, width, height, 0, format, type, bufSize,
2697 pixels);
2698 }
2699
2700 ASSERT(context->getClientMajorVersion() >= 3);
2701 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2702 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2703 pixels);
2704}
2705
Jamie Madill73a84962016-02-12 09:27:23 -05002706bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002707 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002708 GLint level,
2709 GLenum internalformat,
2710 GLsizei width,
2711 GLsizei height,
2712 GLint border,
2713 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002714 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002715{
Martin Radev1be913c2016-07-11 17:59:16 +03002716 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002717 {
2718 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002719 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002720 {
2721 return false;
2722 }
2723 }
2724 else
2725 {
Martin Radev1be913c2016-07-11 17:59:16 +03002726 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002727 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002728 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002729 data))
2730 {
2731 return false;
2732 }
2733 }
2734
Geoff Langca271392017-04-05 12:30:00 -04002735 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002736
2737 GLuint blockSize = 0;
2738 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002739 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002740 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002741 return false;
2742 }
2743
Jamie Madillca2ff382018-07-11 09:01:17 -04002744 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002745 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002746 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002747 return false;
2748 }
2749
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002750 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002751 {
2752 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2753 return false;
2754 }
2755
Jamie Madill73a84962016-02-12 09:27:23 -05002756 return true;
2757}
2758
Corentin Wallezb2931602017-04-11 15:58:57 -04002759bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002760 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002761 GLint level,
2762 GLenum internalformat,
2763 GLsizei width,
2764 GLsizei height,
2765 GLint border,
2766 GLsizei imageSize,
2767 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002768 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002769{
2770 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2771 {
2772 return false;
2773 }
2774
2775 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2776 border, imageSize, data);
2777}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002778
Corentin Wallezb2931602017-04-11 15:58:57 -04002779bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002780 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002781 GLint level,
2782 GLint xoffset,
2783 GLint yoffset,
2784 GLsizei width,
2785 GLsizei height,
2786 GLenum format,
2787 GLsizei imageSize,
2788 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002789 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002790{
2791 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2792 {
2793 return false;
2794 }
2795
2796 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2797 format, imageSize, data);
2798}
2799
Jamie Madill73a84962016-02-12 09:27:23 -05002800bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002801 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002802 GLint level,
2803 GLint xoffset,
2804 GLint yoffset,
2805 GLsizei width,
2806 GLsizei height,
2807 GLenum format,
2808 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002809 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002810{
Martin Radev1be913c2016-07-11 17:59:16 +03002811 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002812 {
2813 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002814 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002815 {
2816 return false;
2817 }
2818 }
2819 else
2820 {
Martin Radev1be913c2016-07-11 17:59:16 +03002821 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002822 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002823 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002824 data))
2825 {
2826 return false;
2827 }
2828 }
2829
Geoff Langca271392017-04-05 12:30:00 -04002830 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002831 GLuint blockSize = 0;
2832 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002833 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002834 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002835 return false;
2836 }
2837
Jamie Madillca2ff382018-07-11 09:01:17 -04002838 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002839 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002840 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002841 return false;
2842 }
2843
2844 return true;
2845}
2846
Corentin Wallez336129f2017-10-17 15:55:40 -04002847bool ValidateGetBufferPointervOES(Context *context,
2848 BufferBinding target,
2849 GLenum pname,
2850 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002851{
Geoff Lang496c02d2016-10-20 11:38:11 -07002852 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002853}
2854
Corentin Wallez336129f2017-10-17 15:55:40 -04002855bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002856{
2857 if (!context->getExtensions().mapBuffer)
2858 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002859 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002860 return false;
2861 }
2862
Corentin Walleze4477002017-12-01 14:39:58 -05002863 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002864 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002865 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002866 return false;
2867 }
2868
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002869 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002870
2871 if (buffer == nullptr)
2872 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002873 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002874 return false;
2875 }
2876
2877 if (access != GL_WRITE_ONLY_OES)
2878 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002879 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002880 return false;
2881 }
2882
2883 if (buffer->isMapped())
2884 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002885 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002886 return false;
2887 }
2888
Geoff Lang79f71042017-08-14 16:43:43 -04002889 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002890}
2891
Corentin Wallez336129f2017-10-17 15:55:40 -04002892bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002893{
2894 if (!context->getExtensions().mapBuffer)
2895 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002896 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002897 return false;
2898 }
2899
2900 return ValidateUnmapBufferBase(context, target);
2901}
2902
2903bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002904 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002905 GLintptr offset,
2906 GLsizeiptr length,
2907 GLbitfield access)
2908{
2909 if (!context->getExtensions().mapBufferRange)
2910 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002911 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002912 return false;
2913 }
2914
2915 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2916}
2917
Corentin Wallez336129f2017-10-17 15:55:40 -04002918bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002919{
2920 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2921 ASSERT(buffer != nullptr);
2922
2923 // Check if this buffer is currently being used as a transform feedback output buffer
2924 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2925 if (transformFeedback != nullptr && transformFeedback->isActive())
2926 {
2927 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2928 {
2929 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2930 if (transformFeedbackBuffer.get() == buffer)
2931 {
2932 context->handleError(InvalidOperation()
2933 << "Buffer is currently bound for transform feedback.");
2934 return false;
2935 }
2936 }
2937 }
2938
James Darpiniane8a93c62018-01-04 18:02:24 -08002939 if (context->getExtensions().webglCompatibility &&
2940 buffer->isBoundForTransformFeedbackAndOtherUse())
2941 {
2942 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2943 return false;
2944 }
2945
Geoff Lang79f71042017-08-14 16:43:43 -04002946 return true;
2947}
2948
Olli Etuaho4f667482016-03-30 15:56:35 +03002949bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002950 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002951 GLintptr offset,
2952 GLsizeiptr length)
2953{
2954 if (!context->getExtensions().mapBufferRange)
2955 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002956 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002957 return false;
2958 }
2959
2960 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2961}
2962
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002963bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002964{
2965 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002966 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002967 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002968 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002969 return false;
2970 }
2971
Geoff Langf41a7152016-09-19 15:11:17 -04002972 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2973 !context->isTextureGenerated(texture))
2974 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002975 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002976 return false;
2977 }
2978
Ian Ewell54f87462016-03-10 13:47:21 -05002979 switch (target)
2980 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002981 case TextureType::_2D:
2982 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002983 break;
2984
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002985 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002986 if (!context->getExtensions().textureRectangle)
2987 {
2988 context->handleError(InvalidEnum()
2989 << "Context does not support GL_ANGLE_texture_rectangle");
2990 return false;
2991 }
2992 break;
2993
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002994 case TextureType::_3D:
2995 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002996 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002997 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002998 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002999 return false;
3000 }
3001 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003002
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003003 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003004 if (context->getClientVersion() < Version(3, 1))
3005 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003006 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003007 return false;
3008 }
Geoff Lang3b573612016-10-31 14:08:10 -04003009 break;
3010
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003011 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003012 if (!context->getExtensions().eglImageExternal &&
3013 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003014 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003015 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003016 return false;
3017 }
3018 break;
3019 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003020 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003021 return false;
3022 }
3023
3024 return true;
3025}
3026
Geoff Langd8605522016-04-13 10:19:12 -04003027bool ValidateBindUniformLocationCHROMIUM(Context *context,
3028 GLuint program,
3029 GLint location,
3030 const GLchar *name)
3031{
3032 if (!context->getExtensions().bindUniformLocation)
3033 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003034 context->handleError(InvalidOperation()
3035 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003036 return false;
3037 }
3038
3039 Program *programObject = GetValidProgram(context, program);
3040 if (!programObject)
3041 {
3042 return false;
3043 }
3044
3045 if (location < 0)
3046 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003047 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003048 return false;
3049 }
3050
3051 const Caps &caps = context->getCaps();
3052 if (static_cast<size_t>(location) >=
3053 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3054 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003055 context->handleError(InvalidValue() << "Location must be less than "
3056 "(MAX_VERTEX_UNIFORM_VECTORS + "
3057 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003058 return false;
3059 }
3060
Geoff Langfc32e8b2017-05-31 14:16:59 -04003061 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3062 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003063 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003064 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003065 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003066 return false;
3067 }
3068
Geoff Langd8605522016-04-13 10:19:12 -04003069 if (strncmp(name, "gl_", 3) == 0)
3070 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003071 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003072 return false;
3073 }
3074
3075 return true;
3076}
3077
Jamie Madille2e406c2016-06-02 13:04:10 -04003078bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003079{
3080 if (!context->getExtensions().framebufferMixedSamples)
3081 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003082 context->handleError(InvalidOperation()
3083 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003084 return false;
3085 }
3086 switch (components)
3087 {
3088 case GL_RGB:
3089 case GL_RGBA:
3090 case GL_ALPHA:
3091 case GL_NONE:
3092 break;
3093 default:
3094 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003095 InvalidEnum()
3096 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003097 return false;
3098 }
3099
3100 return true;
3101}
3102
Sami Väisänene45e53b2016-05-25 10:36:04 +03003103// CHROMIUM_path_rendering
3104
Jamie Madill007530e2017-12-28 14:27:04 -05003105bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003106{
Jamie Madill007530e2017-12-28 14:27:04 -05003107 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003108 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003109 return false;
3110 }
Jamie Madill007530e2017-12-28 14:27:04 -05003111
Sami Väisänene45e53b2016-05-25 10:36:04 +03003112 if (matrix == nullptr)
3113 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003114 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003115 return false;
3116 }
Jamie Madill007530e2017-12-28 14:27:04 -05003117
Sami Väisänene45e53b2016-05-25 10:36:04 +03003118 return true;
3119}
3120
Jamie Madill007530e2017-12-28 14:27:04 -05003121bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003122{
Jamie Madill007530e2017-12-28 14:27:04 -05003123 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003124}
3125
Jamie Madill007530e2017-12-28 14:27:04 -05003126bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003127{
3128 if (!context->getExtensions().pathRendering)
3129 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003130 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003131 return false;
3132 }
3133
3134 // range = 0 is undefined in NV_path_rendering.
3135 // we add stricter semantic check here and require a non zero positive range.
3136 if (range <= 0)
3137 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003138 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003139 return false;
3140 }
3141
3142 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003145 return false;
3146 }
3147
3148 return true;
3149}
3150
Jamie Madill007530e2017-12-28 14:27:04 -05003151bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003152{
3153 if (!context->getExtensions().pathRendering)
3154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003155 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003156 return false;
3157 }
3158
3159 // range = 0 is undefined in NV_path_rendering.
3160 // we add stricter semantic check here and require a non zero positive range.
3161 if (range <= 0)
3162 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003163 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003164 return false;
3165 }
3166
3167 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3168 checkedRange += range;
3169
3170 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3171 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003172 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003173 return false;
3174 }
3175 return true;
3176}
3177
Jamie Madill007530e2017-12-28 14:27:04 -05003178bool ValidatePathCommandsCHROMIUM(Context *context,
3179 GLuint path,
3180 GLsizei numCommands,
3181 const GLubyte *commands,
3182 GLsizei numCoords,
3183 GLenum coordType,
3184 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003185{
3186 if (!context->getExtensions().pathRendering)
3187 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003188 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003189 return false;
3190 }
Brandon Jones59770802018-04-02 13:18:42 -07003191 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003192 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003193 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003194 return false;
3195 }
3196
3197 if (numCommands < 0)
3198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003199 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003200 return false;
3201 }
3202 else if (numCommands > 0)
3203 {
3204 if (!commands)
3205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003206 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003207 return false;
3208 }
3209 }
3210
3211 if (numCoords < 0)
3212 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003213 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003214 return false;
3215 }
3216 else if (numCoords > 0)
3217 {
3218 if (!coords)
3219 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003220 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003221 return false;
3222 }
3223 }
3224
3225 std::uint32_t coordTypeSize = 0;
3226 switch (coordType)
3227 {
3228 case GL_BYTE:
3229 coordTypeSize = sizeof(GLbyte);
3230 break;
3231
3232 case GL_UNSIGNED_BYTE:
3233 coordTypeSize = sizeof(GLubyte);
3234 break;
3235
3236 case GL_SHORT:
3237 coordTypeSize = sizeof(GLshort);
3238 break;
3239
3240 case GL_UNSIGNED_SHORT:
3241 coordTypeSize = sizeof(GLushort);
3242 break;
3243
3244 case GL_FLOAT:
3245 coordTypeSize = sizeof(GLfloat);
3246 break;
3247
3248 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003249 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003250 return false;
3251 }
3252
3253 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3254 checkedSize += (coordTypeSize * numCoords);
3255 if (!checkedSize.IsValid())
3256 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003257 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003258 return false;
3259 }
3260
3261 // early return skips command data validation when it doesn't exist.
3262 if (!commands)
3263 return true;
3264
3265 GLsizei expectedNumCoords = 0;
3266 for (GLsizei i = 0; i < numCommands; ++i)
3267 {
3268 switch (commands[i])
3269 {
3270 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3271 break;
3272 case GL_MOVE_TO_CHROMIUM:
3273 case GL_LINE_TO_CHROMIUM:
3274 expectedNumCoords += 2;
3275 break;
3276 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3277 expectedNumCoords += 4;
3278 break;
3279 case GL_CUBIC_CURVE_TO_CHROMIUM:
3280 expectedNumCoords += 6;
3281 break;
3282 case GL_CONIC_CURVE_TO_CHROMIUM:
3283 expectedNumCoords += 5;
3284 break;
3285 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003286 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003287 return false;
3288 }
3289 }
3290 if (expectedNumCoords != numCoords)
3291 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003292 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003293 return false;
3294 }
3295
3296 return true;
3297}
3298
Jamie Madill007530e2017-12-28 14:27:04 -05003299bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003300{
3301 if (!context->getExtensions().pathRendering)
3302 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003303 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003304 return false;
3305 }
Brandon Jones59770802018-04-02 13:18:42 -07003306 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003307 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003308 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003309 return false;
3310 }
3311
3312 switch (pname)
3313 {
3314 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3315 if (value < 0.0f)
3316 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003317 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003318 return false;
3319 }
3320 break;
3321 case GL_PATH_END_CAPS_CHROMIUM:
3322 switch (static_cast<GLenum>(value))
3323 {
3324 case GL_FLAT_CHROMIUM:
3325 case GL_SQUARE_CHROMIUM:
3326 case GL_ROUND_CHROMIUM:
3327 break;
3328 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003329 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003330 return false;
3331 }
3332 break;
3333 case GL_PATH_JOIN_STYLE_CHROMIUM:
3334 switch (static_cast<GLenum>(value))
3335 {
3336 case GL_MITER_REVERT_CHROMIUM:
3337 case GL_BEVEL_CHROMIUM:
3338 case GL_ROUND_CHROMIUM:
3339 break;
3340 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003341 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003342 return false;
3343 }
Nico Weber41b072b2018-02-09 10:01:32 -05003344 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003345 case GL_PATH_MITER_LIMIT_CHROMIUM:
3346 if (value < 0.0f)
3347 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003348 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003349 return false;
3350 }
3351 break;
3352
3353 case GL_PATH_STROKE_BOUND_CHROMIUM:
3354 // no errors, only clamping.
3355 break;
3356
3357 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003358 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003359 return false;
3360 }
3361 return true;
3362}
3363
Jamie Madill007530e2017-12-28 14:27:04 -05003364bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3365{
3366 // TODO(jmadill): Use proper clamping cast.
3367 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3368}
3369
3370bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003371{
3372 if (!context->getExtensions().pathRendering)
3373 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003374 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003375 return false;
3376 }
3377
Brandon Jones59770802018-04-02 13:18:42 -07003378 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003379 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003380 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003381 return false;
3382 }
3383 if (!value)
3384 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003385 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003386 return false;
3387 }
3388
3389 switch (pname)
3390 {
3391 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3392 case GL_PATH_END_CAPS_CHROMIUM:
3393 case GL_PATH_JOIN_STYLE_CHROMIUM:
3394 case GL_PATH_MITER_LIMIT_CHROMIUM:
3395 case GL_PATH_STROKE_BOUND_CHROMIUM:
3396 break;
3397
3398 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003399 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003400 return false;
3401 }
3402
3403 return true;
3404}
3405
Jamie Madill007530e2017-12-28 14:27:04 -05003406bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3407{
3408 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3409 reinterpret_cast<GLfloat *>(value));
3410}
3411
3412bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003413{
3414 if (!context->getExtensions().pathRendering)
3415 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003416 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003417 return false;
3418 }
3419
3420 switch (func)
3421 {
3422 case GL_NEVER:
3423 case GL_ALWAYS:
3424 case GL_LESS:
3425 case GL_LEQUAL:
3426 case GL_EQUAL:
3427 case GL_GEQUAL:
3428 case GL_GREATER:
3429 case GL_NOTEQUAL:
3430 break;
3431 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003432 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003433 return false;
3434 }
3435
3436 return true;
3437}
3438
3439// Note that the spec specifies that for the path drawing commands
3440// if the path object is not an existing path object the command
3441// does nothing and no error is generated.
3442// However if the path object exists but has not been specified any
3443// commands then an error is generated.
3444
Jamie Madill007530e2017-12-28 14:27:04 -05003445bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003446{
3447 if (!context->getExtensions().pathRendering)
3448 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003449 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003450 return false;
3451 }
Brandon Jones59770802018-04-02 13:18:42 -07003452 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003453 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003454 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003455 return false;
3456 }
3457
3458 switch (fillMode)
3459 {
3460 case GL_COUNT_UP_CHROMIUM:
3461 case GL_COUNT_DOWN_CHROMIUM:
3462 break;
3463 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003464 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003465 return false;
3466 }
3467
3468 if (!isPow2(mask + 1))
3469 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003470 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471 return false;
3472 }
3473
3474 return true;
3475}
3476
Jamie Madill007530e2017-12-28 14:27:04 -05003477bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003478{
3479 if (!context->getExtensions().pathRendering)
3480 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003481 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003482 return false;
3483 }
Brandon Jones59770802018-04-02 13:18:42 -07003484 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003485 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003486 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003487 return false;
3488 }
3489
3490 return true;
3491}
3492
Brandon Jonesd1049182018-03-28 10:02:20 -07003493bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3494{
3495 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3496}
3497
3498bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3499{
3500 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3501}
3502
Jamie Madill007530e2017-12-28 14:27:04 -05003503bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003504{
3505 if (!context->getExtensions().pathRendering)
3506 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003507 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003508 return false;
3509 }
Brandon Jones59770802018-04-02 13:18:42 -07003510 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003511 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003512 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003513 return false;
3514 }
3515
3516 switch (coverMode)
3517 {
3518 case GL_CONVEX_HULL_CHROMIUM:
3519 case GL_BOUNDING_BOX_CHROMIUM:
3520 break;
3521 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003522 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003523 return false;
3524 }
3525 return true;
3526}
3527
Jamie Madill007530e2017-12-28 14:27:04 -05003528bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3529 GLuint path,
3530 GLenum fillMode,
3531 GLuint mask,
3532 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003533{
Jamie Madill007530e2017-12-28 14:27:04 -05003534 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3535 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003536}
3537
Jamie Madill007530e2017-12-28 14:27:04 -05003538bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3539 GLuint path,
3540 GLint reference,
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 ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3545 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546}
3547
Brandon Jonesd1049182018-03-28 10:02:20 -07003548bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003549{
3550 if (!context->getExtensions().pathRendering)
3551 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003552 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003553 return false;
3554 }
3555 return true;
3556}
3557
Jamie Madill007530e2017-12-28 14:27:04 -05003558bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3559 GLsizei numPaths,
3560 GLenum pathNameType,
3561 const void *paths,
3562 GLuint pathBase,
3563 GLenum coverMode,
3564 GLenum transformType,
3565 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003566{
3567 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3568 transformType, transformValues))
3569 return false;
3570
3571 switch (coverMode)
3572 {
3573 case GL_CONVEX_HULL_CHROMIUM:
3574 case GL_BOUNDING_BOX_CHROMIUM:
3575 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3576 break;
3577 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003578 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003579 return false;
3580 }
3581
3582 return true;
3583}
3584
Jamie Madill007530e2017-12-28 14:27:04 -05003585bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3586 GLsizei numPaths,
3587 GLenum pathNameType,
3588 const void *paths,
3589 GLuint pathBase,
3590 GLenum coverMode,
3591 GLenum transformType,
3592 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003593{
3594 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3595 transformType, transformValues))
3596 return false;
3597
3598 switch (coverMode)
3599 {
3600 case GL_CONVEX_HULL_CHROMIUM:
3601 case GL_BOUNDING_BOX_CHROMIUM:
3602 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3603 break;
3604 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003605 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003606 return false;
3607 }
3608
3609 return true;
3610}
3611
Jamie Madill007530e2017-12-28 14:27:04 -05003612bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3613 GLsizei numPaths,
3614 GLenum pathNameType,
3615 const void *paths,
3616 GLuint pathBase,
3617 GLenum fillMode,
3618 GLuint mask,
3619 GLenum transformType,
3620 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003621{
3622
3623 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3624 transformType, transformValues))
3625 return false;
3626
3627 switch (fillMode)
3628 {
3629 case GL_COUNT_UP_CHROMIUM:
3630 case GL_COUNT_DOWN_CHROMIUM:
3631 break;
3632 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003633 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003634 return false;
3635 }
3636 if (!isPow2(mask + 1))
3637 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003638 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003639 return false;
3640 }
3641 return true;
3642}
3643
Jamie Madill007530e2017-12-28 14:27:04 -05003644bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3645 GLsizei numPaths,
3646 GLenum pathNameType,
3647 const void *paths,
3648 GLuint pathBase,
3649 GLint reference,
3650 GLuint mask,
3651 GLenum transformType,
3652 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003653{
3654 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3655 transformType, transformValues))
3656 return false;
3657
3658 // no more validation here.
3659
3660 return true;
3661}
3662
Jamie Madill007530e2017-12-28 14:27:04 -05003663bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3664 GLsizei numPaths,
3665 GLenum pathNameType,
3666 const void *paths,
3667 GLuint pathBase,
3668 GLenum fillMode,
3669 GLuint mask,
3670 GLenum coverMode,
3671 GLenum transformType,
3672 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003673{
3674 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3675 transformType, transformValues))
3676 return false;
3677
3678 switch (coverMode)
3679 {
3680 case GL_CONVEX_HULL_CHROMIUM:
3681 case GL_BOUNDING_BOX_CHROMIUM:
3682 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3683 break;
3684 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003685 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003686 return false;
3687 }
3688
3689 switch (fillMode)
3690 {
3691 case GL_COUNT_UP_CHROMIUM:
3692 case GL_COUNT_DOWN_CHROMIUM:
3693 break;
3694 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003695 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003696 return false;
3697 }
3698 if (!isPow2(mask + 1))
3699 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003700 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003701 return false;
3702 }
3703
3704 return true;
3705}
3706
Jamie Madill007530e2017-12-28 14:27:04 -05003707bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3708 GLsizei numPaths,
3709 GLenum pathNameType,
3710 const void *paths,
3711 GLuint pathBase,
3712 GLint reference,
3713 GLuint mask,
3714 GLenum coverMode,
3715 GLenum transformType,
3716 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003717{
3718 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3719 transformType, transformValues))
3720 return false;
3721
3722 switch (coverMode)
3723 {
3724 case GL_CONVEX_HULL_CHROMIUM:
3725 case GL_BOUNDING_BOX_CHROMIUM:
3726 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3727 break;
3728 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003729 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003730 return false;
3731 }
3732
3733 return true;
3734}
3735
Jamie Madill007530e2017-12-28 14:27:04 -05003736bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3737 GLuint program,
3738 GLint location,
3739 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003740{
3741 if (!context->getExtensions().pathRendering)
3742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003743 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003744 return false;
3745 }
3746
3747 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3748 if (location >= MaxLocation)
3749 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003750 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003751 return false;
3752 }
3753
3754 const auto *programObject = context->getProgram(program);
3755 if (!programObject)
3756 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003757 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003758 return false;
3759 }
3760
3761 if (!name)
3762 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003763 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003764 return false;
3765 }
3766
3767 if (angle::BeginsWith(name, "gl_"))
3768 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003769 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003770 return false;
3771 }
3772
3773 return true;
3774}
3775
Jamie Madill007530e2017-12-28 14:27:04 -05003776bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3777 GLuint program,
3778 GLint location,
3779 GLenum genMode,
3780 GLint components,
3781 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003782{
3783 if (!context->getExtensions().pathRendering)
3784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003785 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003786 return false;
3787 }
3788
3789 const auto *programObject = context->getProgram(program);
3790 if (!programObject || programObject->isFlaggedForDeletion())
3791 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003792 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003793 return false;
3794 }
3795
3796 if (!programObject->isLinked())
3797 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003798 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003799 return false;
3800 }
3801
3802 switch (genMode)
3803 {
3804 case GL_NONE:
3805 if (components != 0)
3806 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003807 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003808 return false;
3809 }
3810 break;
3811
3812 case GL_OBJECT_LINEAR_CHROMIUM:
3813 case GL_EYE_LINEAR_CHROMIUM:
3814 case GL_CONSTANT_CHROMIUM:
3815 if (components < 1 || components > 4)
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 if (!coeffs)
3821 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003822 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003823 return false;
3824 }
3825 break;
3826
3827 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003828 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003829 return false;
3830 }
3831
3832 // If the location is -1 then the command is silently ignored
3833 // and no further validation is needed.
3834 if (location == -1)
3835 return true;
3836
Jamie Madillbd044ed2017-06-05 12:59:21 -04003837 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003838
3839 if (!binding.valid)
3840 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003841 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003842 return false;
3843 }
3844
3845 if (binding.type != GL_NONE)
3846 {
3847 GLint expectedComponents = 0;
3848 switch (binding.type)
3849 {
3850 case GL_FLOAT:
3851 expectedComponents = 1;
3852 break;
3853 case GL_FLOAT_VEC2:
3854 expectedComponents = 2;
3855 break;
3856 case GL_FLOAT_VEC3:
3857 expectedComponents = 3;
3858 break;
3859 case GL_FLOAT_VEC4:
3860 expectedComponents = 4;
3861 break;
3862 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003863 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003864 InvalidOperation()
3865 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003866 return false;
3867 }
3868 if (expectedComponents != components && genMode != GL_NONE)
3869 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003870 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003871 return false;
3872 }
3873 }
3874 return true;
3875}
3876
Geoff Lang97073d12016-04-20 10:42:34 -07003877bool ValidateCopyTextureCHROMIUM(Context *context,
3878 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003879 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003880 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003881 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003882 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003883 GLint internalFormat,
3884 GLenum destType,
3885 GLboolean unpackFlipY,
3886 GLboolean unpackPremultiplyAlpha,
3887 GLboolean unpackUnmultiplyAlpha)
3888{
3889 if (!context->getExtensions().copyTexture)
3890 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003891 context->handleError(InvalidOperation()
3892 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003893 return false;
3894 }
3895
Geoff Lang4f0e0032017-05-01 16:04:35 -04003896 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003897 if (source == nullptr)
3898 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003899 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003900 return false;
3901 }
3902
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003903 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003904 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003905 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003906 return false;
3907 }
3908
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003909 TextureType sourceType = source->getType();
3910 ASSERT(sourceType != TextureType::CubeMap);
3911 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003912
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003913 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003914 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003915 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003916 return false;
3917 }
3918
Geoff Lang4f0e0032017-05-01 16:04:35 -04003919 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3920 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3921 if (sourceWidth == 0 || sourceHeight == 0)
3922 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003923 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003924 return false;
3925 }
3926
3927 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3928 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003929 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003930 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003931 return false;
3932 }
3933
Geoff Lang63458a32017-10-30 15:16:53 -04003934 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3935 {
3936 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3937 return false;
3938 }
3939
Geoff Lang4f0e0032017-05-01 16:04:35 -04003940 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003941 if (dest == nullptr)
3942 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003943 context->handleError(InvalidValue()
3944 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003945 return false;
3946 }
3947
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003948 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003949 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003950 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003951 return false;
3952 }
3953
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003954 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003955 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003956 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003957 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003958 return false;
3959 }
3960
Geoff Lang97073d12016-04-20 10:42:34 -07003961 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3962 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003963 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003964 return false;
3965 }
3966
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003967 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003968 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003969 context->handleError(
3970 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003971 return false;
3972 }
3973
Geoff Lang97073d12016-04-20 10:42:34 -07003974 if (dest->getImmutableFormat())
3975 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003976 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003977 return false;
3978 }
3979
3980 return true;
3981}
3982
3983bool ValidateCopySubTextureCHROMIUM(Context *context,
3984 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003985 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003986 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003987 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003988 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003989 GLint xoffset,
3990 GLint yoffset,
3991 GLint x,
3992 GLint y,
3993 GLsizei width,
3994 GLsizei height,
3995 GLboolean unpackFlipY,
3996 GLboolean unpackPremultiplyAlpha,
3997 GLboolean unpackUnmultiplyAlpha)
3998{
3999 if (!context->getExtensions().copyTexture)
4000 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004001 context->handleError(InvalidOperation()
4002 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004003 return false;
4004 }
4005
Geoff Lang4f0e0032017-05-01 16:04:35 -04004006 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004007 if (source == nullptr)
4008 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004009 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004010 return false;
4011 }
4012
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004013 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004014 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004015 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004016 return false;
4017 }
4018
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004019 TextureType sourceType = source->getType();
4020 ASSERT(sourceType != TextureType::CubeMap);
4021 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004022
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004023 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004024 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004025 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004026 return false;
4027 }
4028
4029 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4030 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004031 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004032 context->handleError(InvalidValue()
4033 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004034 return false;
4035 }
4036
4037 if (x < 0 || y < 0)
4038 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004039 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004040 return false;
4041 }
4042
4043 if (width < 0 || height < 0)
4044 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004045 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004046 return false;
4047 }
4048
Geoff Lang4f0e0032017-05-01 16:04:35 -04004049 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4050 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004051 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004052 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004053 return false;
4054 }
4055
Geoff Lang4f0e0032017-05-01 16:04:35 -04004056 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4057 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004058 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004059 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004060 return false;
4061 }
4062
Geoff Lang63458a32017-10-30 15:16:53 -04004063 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4064 {
4065 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4066 return false;
4067 }
4068
Geoff Lang4f0e0032017-05-01 16:04:35 -04004069 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004070 if (dest == nullptr)
4071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004072 context->handleError(InvalidValue()
4073 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004074 return false;
4075 }
4076
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004077 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004078 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004079 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004080 return false;
4081 }
4082
Brandon Jones28783792018-03-05 09:37:32 -08004083 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4084 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004085 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004086 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004087 return false;
4088 }
4089
Geoff Lang4f0e0032017-05-01 16:04:35 -04004090 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4091 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004092 context
4093 ->handleError(InvalidOperation()
4094 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004095 return false;
4096 }
4097
4098 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4099 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004101 context->handleError(InvalidOperation()
4102 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004103 return false;
4104 }
4105
4106 if (xoffset < 0 || yoffset < 0)
4107 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004108 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004109 return false;
4110 }
4111
Geoff Lang4f0e0032017-05-01 16:04:35 -04004112 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4113 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004114 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004115 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004116 return false;
4117 }
4118
4119 return true;
4120}
4121
Geoff Lang47110bf2016-04-20 11:13:22 -07004122bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4123{
4124 if (!context->getExtensions().copyCompressedTexture)
4125 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004126 context->handleError(InvalidOperation()
4127 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004128 return false;
4129 }
4130
4131 const gl::Texture *source = context->getTexture(sourceId);
4132 if (source == nullptr)
4133 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004134 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004135 return false;
4136 }
4137
Corentin Wallez99d492c2018-02-27 15:17:10 -05004138 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004140 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004141 return false;
4142 }
4143
Corentin Wallez99d492c2018-02-27 15:17:10 -05004144 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4145 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004146 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004147 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004148 return false;
4149 }
4150
Corentin Wallez99d492c2018-02-27 15:17:10 -05004151 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004152 if (!sourceFormat.info->compressed)
4153 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004154 context->handleError(InvalidOperation()
4155 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004156 return false;
4157 }
4158
4159 const gl::Texture *dest = context->getTexture(destId);
4160 if (dest == nullptr)
4161 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004162 context->handleError(InvalidValue()
4163 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004164 return false;
4165 }
4166
Corentin Wallez99d492c2018-02-27 15:17:10 -05004167 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004168 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004169 context->handleError(InvalidValue()
4170 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004171 return false;
4172 }
4173
4174 if (dest->getImmutableFormat())
4175 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004176 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004177 return false;
4178 }
4179
4180 return true;
4181}
4182
Jiawei Shao385b3e02018-03-21 09:43:28 +08004183bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004184{
4185 switch (type)
4186 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004187 case ShaderType::Vertex:
4188 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004189 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004190
Jiawei Shao385b3e02018-03-21 09:43:28 +08004191 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004192 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004193 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004194 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004195 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004196 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004197 break;
4198
Jiawei Shao385b3e02018-03-21 09:43:28 +08004199 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004200 if (!context->getExtensions().geometryShader)
4201 {
4202 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4203 return false;
4204 }
4205 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004206 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004207 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004208 return false;
4209 }
Jamie Madill29639852016-09-02 15:00:09 -04004210
4211 return true;
4212}
4213
Jamie Madill5b772312018-03-08 20:28:32 -05004214bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004215 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004216 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004217 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004218 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004219{
4220 if (size < 0)
4221 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004222 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004223 return false;
4224 }
4225
4226 switch (usage)
4227 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004228 case BufferUsage::StreamDraw:
4229 case BufferUsage::StaticDraw:
4230 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004231 break;
4232
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004233 case BufferUsage::StreamRead:
4234 case BufferUsage::StaticRead:
4235 case BufferUsage::DynamicRead:
4236 case BufferUsage::StreamCopy:
4237 case BufferUsage::StaticCopy:
4238 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004239 if (context->getClientMajorVersion() < 3)
4240 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004241 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004242 return false;
4243 }
4244 break;
4245
4246 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004247 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004248 return false;
4249 }
4250
Corentin Walleze4477002017-12-01 14:39:58 -05004251 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004252 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004253 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004254 return false;
4255 }
4256
4257 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4258
4259 if (!buffer)
4260 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004261 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004262 return false;
4263 }
4264
James Darpiniane8a93c62018-01-04 18:02:24 -08004265 if (context->getExtensions().webglCompatibility &&
4266 buffer->isBoundForTransformFeedbackAndOtherUse())
4267 {
4268 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4269 return false;
4270 }
4271
Jamie Madill29639852016-09-02 15:00:09 -04004272 return true;
4273}
4274
Jamie Madill5b772312018-03-08 20:28:32 -05004275bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004276 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004277 GLintptr offset,
4278 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004279 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004280{
Brandon Jones6cad5662017-06-14 13:25:13 -07004281 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004282 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004283 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4284 return false;
4285 }
4286
4287 if (offset < 0)
4288 {
4289 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004290 return false;
4291 }
4292
Corentin Walleze4477002017-12-01 14:39:58 -05004293 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004294 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004295 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004296 return false;
4297 }
4298
4299 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4300
4301 if (!buffer)
4302 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004303 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004304 return false;
4305 }
4306
4307 if (buffer->isMapped())
4308 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004309 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004310 return false;
4311 }
4312
James Darpiniane8a93c62018-01-04 18:02:24 -08004313 if (context->getExtensions().webglCompatibility &&
4314 buffer->isBoundForTransformFeedbackAndOtherUse())
4315 {
4316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4317 return false;
4318 }
4319
Jamie Madill29639852016-09-02 15:00:09 -04004320 // Check for possible overflow of size + offset
4321 angle::CheckedNumeric<size_t> checkedSize(size);
4322 checkedSize += offset;
4323 if (!checkedSize.IsValid())
4324 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004325 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004326 return false;
4327 }
4328
4329 if (size + offset > buffer->getSize())
4330 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004331 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004332 return false;
4333 }
4334
Martin Radev4c4c8e72016-08-04 12:25:34 +03004335 return true;
4336}
4337
Geoff Lang111a99e2017-10-17 10:58:41 -04004338bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004339{
Geoff Langc339c4e2016-11-29 10:37:36 -05004340 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004341 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004342 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004343 return false;
4344 }
4345
Geoff Lang111a99e2017-10-17 10:58:41 -04004346 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004347 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004348 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004349 return false;
4350 }
4351
4352 return true;
4353}
4354
Jamie Madill5b772312018-03-08 20:28:32 -05004355bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004356{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004357 if (context->getClientMajorVersion() < 2)
4358 {
4359 return ValidateMultitextureUnit(context, texture);
4360 }
4361
Jamie Madillef300b12016-10-07 15:12:09 -04004362 if (texture < GL_TEXTURE0 ||
4363 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4364 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004365 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004366 return false;
4367 }
4368
4369 return true;
4370}
4371
Jamie Madill5b772312018-03-08 20:28:32 -05004372bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004373{
4374 Program *programObject = GetValidProgram(context, program);
4375 if (!programObject)
4376 {
4377 return false;
4378 }
4379
4380 Shader *shaderObject = GetValidShader(context, shader);
4381 if (!shaderObject)
4382 {
4383 return false;
4384 }
4385
Jiawei Shao385b3e02018-03-21 09:43:28 +08004386 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004387 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4389 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004390 }
4391
4392 return true;
4393}
4394
Jamie Madill5b772312018-03-08 20:28:32 -05004395bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004396{
4397 if (index >= MAX_VERTEX_ATTRIBS)
4398 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004399 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004400 return false;
4401 }
4402
4403 if (strncmp(name, "gl_", 3) == 0)
4404 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004405 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004406 return false;
4407 }
4408
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004409 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004410 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004411 const size_t length = strlen(name);
4412
4413 if (!IsValidESSLString(name, length))
4414 {
4415 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4416 // for shader-related entry points
4417 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4418 return false;
4419 }
4420
4421 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4422 {
4423 return false;
4424 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004425 }
4426
Jamie Madill01a80ee2016-11-07 12:06:18 -05004427 return GetValidProgram(context, program) != nullptr;
4428}
4429
Jamie Madill5b772312018-03-08 20:28:32 -05004430bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004431{
Corentin Walleze4477002017-12-01 14:39:58 -05004432 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004433 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004434 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004435 return false;
4436 }
4437
4438 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4439 !context->isBufferGenerated(buffer))
4440 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004441 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004442 return false;
4443 }
4444
4445 return true;
4446}
4447
Jamie Madill5b772312018-03-08 20:28:32 -05004448bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004449{
Geoff Lange8afa902017-09-27 15:00:43 -04004450 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004451 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004452 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004453 return false;
4454 }
4455
4456 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4457 !context->isFramebufferGenerated(framebuffer))
4458 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004459 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004460 return false;
4461 }
4462
4463 return true;
4464}
4465
Jamie Madill5b772312018-03-08 20:28:32 -05004466bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004467{
4468 if (target != GL_RENDERBUFFER)
4469 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004470 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004471 return false;
4472 }
4473
4474 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4475 !context->isRenderbufferGenerated(renderbuffer))
4476 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004477 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004478 return false;
4479 }
4480
4481 return true;
4482}
4483
Jamie Madill5b772312018-03-08 20:28:32 -05004484static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004485{
4486 switch (mode)
4487 {
4488 case GL_FUNC_ADD:
4489 case GL_FUNC_SUBTRACT:
4490 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004491 return true;
4492
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004493 case GL_MIN:
4494 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004495 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004496
4497 default:
4498 return false;
4499 }
4500}
4501
Jamie Madill5b772312018-03-08 20:28:32 -05004502bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004503{
4504 return true;
4505}
4506
Jamie Madill5b772312018-03-08 20:28:32 -05004507bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004508{
Geoff Lang50cac572017-09-26 17:37:43 -04004509 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004510 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004511 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004512 return false;
4513 }
4514
4515 return true;
4516}
4517
Jamie Madill5b772312018-03-08 20:28:32 -05004518bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004519{
Geoff Lang50cac572017-09-26 17:37:43 -04004520 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004521 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004522 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004523 return false;
4524 }
4525
Geoff Lang50cac572017-09-26 17:37:43 -04004526 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004527 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004528 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004529 return false;
4530 }
4531
4532 return true;
4533}
4534
Jamie Madill5b772312018-03-08 20:28:32 -05004535bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004536{
4537 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4538}
4539
4540static bool ValidSrcBlendFunc(GLenum srcBlend)
4541{
4542 switch (srcBlend)
4543 {
4544 case GL_ZERO:
4545 case GL_ONE:
4546 case GL_SRC_COLOR:
4547 case GL_ONE_MINUS_SRC_COLOR:
4548 case GL_DST_COLOR:
4549 case GL_ONE_MINUS_DST_COLOR:
4550 case GL_SRC_ALPHA:
4551 case GL_ONE_MINUS_SRC_ALPHA:
4552 case GL_DST_ALPHA:
4553 case GL_ONE_MINUS_DST_ALPHA:
4554 case GL_CONSTANT_COLOR:
4555 case GL_ONE_MINUS_CONSTANT_COLOR:
4556 case GL_CONSTANT_ALPHA:
4557 case GL_ONE_MINUS_CONSTANT_ALPHA:
4558 case GL_SRC_ALPHA_SATURATE:
4559 return true;
4560
4561 default:
4562 return false;
4563 }
4564}
4565
4566static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4567{
4568 switch (dstBlend)
4569 {
4570 case GL_ZERO:
4571 case GL_ONE:
4572 case GL_SRC_COLOR:
4573 case GL_ONE_MINUS_SRC_COLOR:
4574 case GL_DST_COLOR:
4575 case GL_ONE_MINUS_DST_COLOR:
4576 case GL_SRC_ALPHA:
4577 case GL_ONE_MINUS_SRC_ALPHA:
4578 case GL_DST_ALPHA:
4579 case GL_ONE_MINUS_DST_ALPHA:
4580 case GL_CONSTANT_COLOR:
4581 case GL_ONE_MINUS_CONSTANT_COLOR:
4582 case GL_CONSTANT_ALPHA:
4583 case GL_ONE_MINUS_CONSTANT_ALPHA:
4584 return true;
4585
4586 case GL_SRC_ALPHA_SATURATE:
4587 return (contextMajorVersion >= 3);
4588
4589 default:
4590 return false;
4591 }
4592}
4593
Jamie Madill5b772312018-03-08 20:28:32 -05004594bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004595 GLenum srcRGB,
4596 GLenum dstRGB,
4597 GLenum srcAlpha,
4598 GLenum dstAlpha)
4599{
4600 if (!ValidSrcBlendFunc(srcRGB))
4601 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004602 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004603 return false;
4604 }
4605
4606 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4607 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004609 return false;
4610 }
4611
4612 if (!ValidSrcBlendFunc(srcAlpha))
4613 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004614 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004615 return false;
4616 }
4617
4618 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4619 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004620 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004621 return false;
4622 }
4623
Frank Henigman146e8a12017-03-02 23:22:37 -05004624 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4625 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004626 {
4627 bool constantColorUsed =
4628 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4629 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4630
4631 bool constantAlphaUsed =
4632 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4633 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4634
4635 if (constantColorUsed && constantAlphaUsed)
4636 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004637 const char *msg;
4638 if (context->getExtensions().webglCompatibility)
4639 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004640 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004641 }
4642 else
4643 {
4644 msg =
4645 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4646 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4647 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004648 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004649 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004650 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004651 return false;
4652 }
4653 }
4654
4655 return true;
4656}
4657
Geoff Langc339c4e2016-11-29 10:37:36 -05004658bool ValidateGetString(Context *context, GLenum name)
4659{
4660 switch (name)
4661 {
4662 case GL_VENDOR:
4663 case GL_RENDERER:
4664 case GL_VERSION:
4665 case GL_SHADING_LANGUAGE_VERSION:
4666 case GL_EXTENSIONS:
4667 break;
4668
4669 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4670 if (!context->getExtensions().requestExtension)
4671 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004672 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004673 return false;
4674 }
4675 break;
4676
4677 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004678 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004679 return false;
4680 }
4681
4682 return true;
4683}
4684
Jamie Madill5b772312018-03-08 20:28:32 -05004685bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004686{
4687 if (width <= 0.0f || isNaN(width))
4688 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004689 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004690 return false;
4691 }
4692
4693 return true;
4694}
4695
Jamie Madill5b772312018-03-08 20:28:32 -05004696bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004697 GLuint index,
4698 GLint size,
4699 GLenum type,
4700 GLboolean normalized,
4701 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004702 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004703{
Shao80957d92017-02-20 21:25:59 +08004704 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004705 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004706 return false;
4707 }
4708
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004709 if (stride < 0)
4710 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004711 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004712 return false;
4713 }
4714
Shao80957d92017-02-20 21:25:59 +08004715 const Caps &caps = context->getCaps();
4716 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004717 {
Shao80957d92017-02-20 21:25:59 +08004718 if (stride > caps.maxVertexAttribStride)
4719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004720 context->handleError(InvalidValue()
4721 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004722 return false;
4723 }
4724
4725 if (index >= caps.maxVertexAttribBindings)
4726 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004727 context->handleError(InvalidValue()
4728 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004729 return false;
4730 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004731 }
4732
4733 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4734 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4735 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4736 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004737 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4738 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004739 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4740 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004741 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004742 context
4743 ->handleError(InvalidOperation()
4744 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004745 return false;
4746 }
4747
4748 if (context->getExtensions().webglCompatibility)
4749 {
4750 // WebGL 1.0 [Section 6.14] Fixed point support
4751 // The WebGL API does not support the GL_FIXED data type.
4752 if (type == GL_FIXED)
4753 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004754 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004755 return false;
4756 }
4757
Geoff Lang2d62ab72017-03-23 16:54:40 -04004758 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004759 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004760 return false;
4761 }
4762 }
4763
4764 return true;
4765}
4766
Jamie Madill5b772312018-03-08 20:28:32 -05004767bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004768{
4769 if (context->getExtensions().webglCompatibility && zNear > zFar)
4770 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004771 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004772 return false;
4773 }
4774
4775 return true;
4776}
4777
Jamie Madill5b772312018-03-08 20:28:32 -05004778bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004779 GLenum target,
4780 GLenum internalformat,
4781 GLsizei width,
4782 GLsizei height)
4783{
4784 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4785 height);
4786}
4787
Jamie Madill5b772312018-03-08 20:28:32 -05004788bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004789 GLenum target,
4790 GLsizei samples,
4791 GLenum internalformat,
4792 GLsizei width,
4793 GLsizei height)
4794{
4795 if (!context->getExtensions().framebufferMultisample)
4796 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004797 context->handleError(InvalidOperation()
4798 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004799 return false;
4800 }
4801
4802 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4803 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4804 // generated.
4805 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4806 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004807 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004808 return false;
4809 }
4810
4811 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4812 // the specified storage. This is different than ES 3.0 in which a sample number higher
4813 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4814 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4815 if (context->getClientMajorVersion() >= 3)
4816 {
4817 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4818 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4819 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004820 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004821 return false;
4822 }
4823 }
4824
4825 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4826 width, height);
4827}
4828
Jamie Madill5b772312018-03-08 20:28:32 -05004829bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004830{
Geoff Lange8afa902017-09-27 15:00:43 -04004831 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004832 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004833 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004834 return false;
4835 }
4836
4837 return true;
4838}
4839
Jamie Madill5b772312018-03-08 20:28:32 -05004840bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004841{
4842 return true;
4843}
4844
Jamie Madill5b772312018-03-08 20:28:32 -05004845bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004846{
4847 return true;
4848}
4849
Jamie Madill5b772312018-03-08 20:28:32 -05004850bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004851{
4852 return true;
4853}
4854
Jamie Madill5b772312018-03-08 20:28:32 -05004855bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004856 GLboolean red,
4857 GLboolean green,
4858 GLboolean blue,
4859 GLboolean alpha)
4860{
4861 return true;
4862}
4863
Jamie Madill5b772312018-03-08 20:28:32 -05004864bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004865{
4866 return true;
4867}
4868
Jamie Madill5b772312018-03-08 20:28:32 -05004869bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004870{
4871 return true;
4872}
4873
Jamie Madill5b772312018-03-08 20:28:32 -05004874bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004875{
4876 switch (mode)
4877 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004878 case CullFaceMode::Front:
4879 case CullFaceMode::Back:
4880 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004881 break;
4882
4883 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004884 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004885 return false;
4886 }
4887
4888 return true;
4889}
4890
Jamie Madill5b772312018-03-08 20:28:32 -05004891bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004892{
4893 if (program == 0)
4894 {
4895 return false;
4896 }
4897
4898 if (!context->getProgram(program))
4899 {
4900 if (context->getShader(program))
4901 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004902 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004903 return false;
4904 }
4905 else
4906 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004907 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004908 return false;
4909 }
4910 }
4911
4912 return true;
4913}
4914
Jamie Madill5b772312018-03-08 20:28:32 -05004915bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004916{
4917 if (shader == 0)
4918 {
4919 return false;
4920 }
4921
4922 if (!context->getShader(shader))
4923 {
4924 if (context->getProgram(shader))
4925 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004926 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004927 return false;
4928 }
4929 else
4930 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004931 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004932 return false;
4933 }
4934 }
4935
4936 return true;
4937}
4938
Jamie Madill5b772312018-03-08 20:28:32 -05004939bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004940{
4941 switch (func)
4942 {
4943 case GL_NEVER:
4944 case GL_ALWAYS:
4945 case GL_LESS:
4946 case GL_LEQUAL:
4947 case GL_EQUAL:
4948 case GL_GREATER:
4949 case GL_GEQUAL:
4950 case GL_NOTEQUAL:
4951 break;
4952
4953 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004954 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004955 return false;
4956 }
4957
4958 return true;
4959}
4960
Jamie Madill5b772312018-03-08 20:28:32 -05004961bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004962{
4963 return true;
4964}
4965
Jamie Madill5b772312018-03-08 20:28:32 -05004966bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004967{
4968 Program *programObject = GetValidProgram(context, program);
4969 if (!programObject)
4970 {
4971 return false;
4972 }
4973
4974 Shader *shaderObject = GetValidShader(context, shader);
4975 if (!shaderObject)
4976 {
4977 return false;
4978 }
4979
Jiawei Shao385b3e02018-03-21 09:43:28 +08004980 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004981 if (attachedShader != shaderObject)
4982 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004983 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004984 return false;
4985 }
4986
4987 return true;
4988}
4989
Jamie Madill5b772312018-03-08 20:28:32 -05004990bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004991{
4992 if (index >= MAX_VERTEX_ATTRIBS)
4993 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004994 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004995 return false;
4996 }
4997
4998 return true;
4999}
5000
Jamie Madill5b772312018-03-08 20:28:32 -05005001bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005002{
5003 if (index >= MAX_VERTEX_ATTRIBS)
5004 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005005 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005006 return false;
5007 }
5008
5009 return true;
5010}
5011
Jamie Madill5b772312018-03-08 20:28:32 -05005012bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005013{
5014 return true;
5015}
5016
Jamie Madill5b772312018-03-08 20:28:32 -05005017bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005018{
5019 return true;
5020}
5021
Jamie Madill5b772312018-03-08 20:28:32 -05005022bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005023{
5024 switch (mode)
5025 {
5026 case GL_CW:
5027 case GL_CCW:
5028 break;
5029 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005030 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005031 return false;
5032 }
5033
5034 return true;
5035}
5036
Jamie Madill5b772312018-03-08 20:28:32 -05005037bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005038 GLuint program,
5039 GLuint index,
5040 GLsizei bufsize,
5041 GLsizei *length,
5042 GLint *size,
5043 GLenum *type,
5044 GLchar *name)
5045{
5046 if (bufsize < 0)
5047 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005048 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005049 return false;
5050 }
5051
5052 Program *programObject = GetValidProgram(context, program);
5053
5054 if (!programObject)
5055 {
5056 return false;
5057 }
5058
5059 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5060 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005061 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005062 return false;
5063 }
5064
5065 return true;
5066}
5067
Jamie Madill5b772312018-03-08 20:28:32 -05005068bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005069 GLuint program,
5070 GLuint index,
5071 GLsizei bufsize,
5072 GLsizei *length,
5073 GLint *size,
5074 GLenum *type,
5075 GLchar *name)
5076{
5077 if (bufsize < 0)
5078 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005079 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005080 return false;
5081 }
5082
5083 Program *programObject = GetValidProgram(context, program);
5084
5085 if (!programObject)
5086 {
5087 return false;
5088 }
5089
5090 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5091 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005092 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005093 return false;
5094 }
5095
5096 return true;
5097}
5098
Jamie Madill5b772312018-03-08 20:28:32 -05005099bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005100 GLuint program,
5101 GLsizei maxcount,
5102 GLsizei *count,
5103 GLuint *shaders)
5104{
5105 if (maxcount < 0)
5106 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005107 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005108 return false;
5109 }
5110
5111 Program *programObject = GetValidProgram(context, program);
5112
5113 if (!programObject)
5114 {
5115 return false;
5116 }
5117
5118 return true;
5119}
5120
Jamie Madill5b772312018-03-08 20:28:32 -05005121bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005122{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005123 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5124 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005125 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005126 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005127 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005128 return false;
5129 }
5130
Jamie Madillc1d770e2017-04-13 17:31:24 -04005131 Program *programObject = GetValidProgram(context, program);
5132
5133 if (!programObject)
5134 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005135 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005136 return false;
5137 }
5138
5139 if (!programObject->isLinked())
5140 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005141 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005142 return false;
5143 }
5144
5145 return true;
5146}
5147
Jamie Madill5b772312018-03-08 20:28:32 -05005148bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149{
5150 GLenum nativeType;
5151 unsigned int numParams = 0;
5152 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5153}
5154
Jamie Madill5b772312018-03-08 20:28:32 -05005155bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005156{
5157 return true;
5158}
5159
Jamie Madill5b772312018-03-08 20:28:32 -05005160bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161{
5162 GLenum nativeType;
5163 unsigned int numParams = 0;
5164 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5165}
5166
Jamie Madill5b772312018-03-08 20:28:32 -05005167bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005168{
5169 GLenum nativeType;
5170 unsigned int numParams = 0;
5171 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5172}
5173
Jamie Madill5b772312018-03-08 20:28:32 -05005174bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005175 GLuint program,
5176 GLsizei bufsize,
5177 GLsizei *length,
5178 GLchar *infolog)
5179{
5180 if (bufsize < 0)
5181 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005182 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005183 return false;
5184 }
5185
5186 Program *programObject = GetValidProgram(context, program);
5187 if (!programObject)
5188 {
5189 return false;
5190 }
5191
5192 return true;
5193}
5194
Jamie Madill5b772312018-03-08 20:28:32 -05005195bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005196 GLuint shader,
5197 GLsizei bufsize,
5198 GLsizei *length,
5199 GLchar *infolog)
5200{
5201 if (bufsize < 0)
5202 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005203 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005204 return false;
5205 }
5206
5207 Shader *shaderObject = GetValidShader(context, shader);
5208 if (!shaderObject)
5209 {
5210 return false;
5211 }
5212
5213 return true;
5214}
5215
Jamie Madill5b772312018-03-08 20:28:32 -05005216bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005217 GLenum shadertype,
5218 GLenum precisiontype,
5219 GLint *range,
5220 GLint *precision)
5221{
5222 switch (shadertype)
5223 {
5224 case GL_VERTEX_SHADER:
5225 case GL_FRAGMENT_SHADER:
5226 break;
5227 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005228 context->handleError(InvalidOperation()
5229 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005230 return false;
5231 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005232 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005233 return false;
5234 }
5235
5236 switch (precisiontype)
5237 {
5238 case GL_LOW_FLOAT:
5239 case GL_MEDIUM_FLOAT:
5240 case GL_HIGH_FLOAT:
5241 case GL_LOW_INT:
5242 case GL_MEDIUM_INT:
5243 case GL_HIGH_INT:
5244 break;
5245
5246 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005247 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005248 return false;
5249 }
5250
5251 return true;
5252}
5253
Jamie Madill5b772312018-03-08 20:28:32 -05005254bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005255 GLuint shader,
5256 GLsizei bufsize,
5257 GLsizei *length,
5258 GLchar *source)
5259{
5260 if (bufsize < 0)
5261 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005262 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005263 return false;
5264 }
5265
5266 Shader *shaderObject = GetValidShader(context, shader);
5267 if (!shaderObject)
5268 {
5269 return false;
5270 }
5271
5272 return true;
5273}
5274
Jamie Madill5b772312018-03-08 20:28:32 -05005275bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005276{
5277 if (strstr(name, "gl_") == name)
5278 {
5279 return false;
5280 }
5281
Geoff Langfc32e8b2017-05-31 14:16:59 -04005282 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5283 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005284 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005285 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005286 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005287 return false;
5288 }
5289
Jamie Madillc1d770e2017-04-13 17:31:24 -04005290 Program *programObject = GetValidProgram(context, program);
5291
5292 if (!programObject)
5293 {
5294 return false;
5295 }
5296
5297 if (!programObject->isLinked())
5298 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005299 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005300 return false;
5301 }
5302
5303 return true;
5304}
5305
Jamie Madill5b772312018-03-08 20:28:32 -05005306bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005307{
5308 switch (mode)
5309 {
5310 case GL_FASTEST:
5311 case GL_NICEST:
5312 case GL_DONT_CARE:
5313 break;
5314
5315 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005316 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005317 return false;
5318 }
5319
5320 switch (target)
5321 {
5322 case GL_GENERATE_MIPMAP_HINT:
5323 break;
5324
Geoff Lange7bd2182017-06-16 16:13:13 -04005325 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5326 if (context->getClientVersion() < ES_3_0 &&
5327 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005328 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005329 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005330 return false;
5331 }
5332 break;
5333
5334 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005335 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005336 return false;
5337 }
5338
5339 return true;
5340}
5341
Jamie Madill5b772312018-03-08 20:28:32 -05005342bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005343{
5344 return true;
5345}
5346
Jamie Madill5b772312018-03-08 20:28:32 -05005347bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005348{
5349 return true;
5350}
5351
Jamie Madill5b772312018-03-08 20:28:32 -05005352bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005353{
5354 return true;
5355}
5356
Jamie Madill5b772312018-03-08 20:28:32 -05005357bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005358{
5359 return true;
5360}
5361
Jamie Madill5b772312018-03-08 20:28:32 -05005362bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005363{
5364 return true;
5365}
5366
Jamie Madill5b772312018-03-08 20:28:32 -05005367bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368{
5369 return true;
5370}
5371
Jamie Madill5b772312018-03-08 20:28:32 -05005372bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005373{
5374 if (context->getClientMajorVersion() < 3)
5375 {
5376 switch (pname)
5377 {
5378 case GL_UNPACK_IMAGE_HEIGHT:
5379 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005380 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005381 return false;
5382
5383 case GL_UNPACK_ROW_LENGTH:
5384 case GL_UNPACK_SKIP_ROWS:
5385 case GL_UNPACK_SKIP_PIXELS:
5386 if (!context->getExtensions().unpackSubimage)
5387 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005388 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005389 return false;
5390 }
5391 break;
5392
5393 case GL_PACK_ROW_LENGTH:
5394 case GL_PACK_SKIP_ROWS:
5395 case GL_PACK_SKIP_PIXELS:
5396 if (!context->getExtensions().packSubimage)
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 }
5404
5405 if (param < 0)
5406 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005407 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005408 return false;
5409 }
5410
5411 switch (pname)
5412 {
5413 case GL_UNPACK_ALIGNMENT:
5414 if (param != 1 && param != 2 && param != 4 && param != 8)
5415 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005416 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005417 return false;
5418 }
5419 break;
5420
5421 case GL_PACK_ALIGNMENT:
5422 if (param != 1 && param != 2 && param != 4 && param != 8)
5423 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005424 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005425 return false;
5426 }
5427 break;
5428
5429 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005430 if (!context->getExtensions().packReverseRowOrder)
5431 {
5432 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5433 }
5434 break;
5435
Jamie Madillc1d770e2017-04-13 17:31:24 -04005436 case GL_UNPACK_ROW_LENGTH:
5437 case GL_UNPACK_IMAGE_HEIGHT:
5438 case GL_UNPACK_SKIP_IMAGES:
5439 case GL_UNPACK_SKIP_ROWS:
5440 case GL_UNPACK_SKIP_PIXELS:
5441 case GL_PACK_ROW_LENGTH:
5442 case GL_PACK_SKIP_ROWS:
5443 case GL_PACK_SKIP_PIXELS:
5444 break;
5445
5446 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005447 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005448 return false;
5449 }
5450
5451 return true;
5452}
5453
Jamie Madill5b772312018-03-08 20:28:32 -05005454bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005455{
5456 return true;
5457}
5458
Jamie Madill5b772312018-03-08 20:28:32 -05005459bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005460{
5461 return true;
5462}
5463
Jamie Madill5b772312018-03-08 20:28:32 -05005464bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005465{
5466 return true;
5467}
5468
Jamie Madill5b772312018-03-08 20:28:32 -05005469bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470{
5471 if (width < 0 || height < 0)
5472 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005473 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005474 return false;
5475 }
5476
5477 return true;
5478}
5479
Jamie Madill5b772312018-03-08 20:28:32 -05005480bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005481 GLsizei n,
5482 const GLuint *shaders,
5483 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005484 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485 GLsizei length)
5486{
5487 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5488 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5489 shaderBinaryFormats.end())
5490 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005491 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005492 return false;
5493 }
5494
5495 return true;
5496}
5497
Jamie Madill5b772312018-03-08 20:28:32 -05005498bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005499 GLuint shader,
5500 GLsizei count,
5501 const GLchar *const *string,
5502 const GLint *length)
5503{
5504 if (count < 0)
5505 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005506 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005507 return false;
5508 }
5509
Geoff Langfc32e8b2017-05-31 14:16:59 -04005510 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5511 // shader-related entry points
5512 if (context->getExtensions().webglCompatibility)
5513 {
5514 for (GLsizei i = 0; i < count; i++)
5515 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005516 size_t len =
5517 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005518
5519 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005520 if (!IsValidESSLShaderSourceString(string[i], len,
5521 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005522 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005523 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005524 return false;
5525 }
5526 }
5527 }
5528
Jamie Madillc1d770e2017-04-13 17:31:24 -04005529 Shader *shaderObject = GetValidShader(context, shader);
5530 if (!shaderObject)
5531 {
5532 return false;
5533 }
5534
5535 return true;
5536}
5537
Jamie Madill5b772312018-03-08 20:28:32 -05005538bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005539{
5540 if (!IsValidStencilFunc(func))
5541 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005542 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005543 return false;
5544 }
5545
5546 return true;
5547}
5548
Jamie Madill5b772312018-03-08 20:28:32 -05005549bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005550{
5551 if (!IsValidStencilFace(face))
5552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005553 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005554 return false;
5555 }
5556
5557 if (!IsValidStencilFunc(func))
5558 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005559 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005560 return false;
5561 }
5562
5563 return true;
5564}
5565
Jamie Madill5b772312018-03-08 20:28:32 -05005566bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005567{
5568 return true;
5569}
5570
Jamie Madill5b772312018-03-08 20:28:32 -05005571bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005572{
5573 if (!IsValidStencilFace(face))
5574 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005575 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005576 return false;
5577 }
5578
5579 return true;
5580}
5581
Jamie Madill5b772312018-03-08 20:28:32 -05005582bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005583{
5584 if (!IsValidStencilOp(fail))
5585 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005586 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005587 return false;
5588 }
5589
5590 if (!IsValidStencilOp(zfail))
5591 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005592 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005593 return false;
5594 }
5595
5596 if (!IsValidStencilOp(zpass))
5597 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005598 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005599 return false;
5600 }
5601
5602 return true;
5603}
5604
Jamie Madill5b772312018-03-08 20:28:32 -05005605bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005606 GLenum face,
5607 GLenum fail,
5608 GLenum zfail,
5609 GLenum zpass)
5610{
5611 if (!IsValidStencilFace(face))
5612 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005613 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005614 return false;
5615 }
5616
5617 return ValidateStencilOp(context, fail, zfail, zpass);
5618}
5619
Jamie Madill5b772312018-03-08 20:28:32 -05005620bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005621{
5622 return ValidateUniform(context, GL_FLOAT, location, 1);
5623}
5624
Jamie Madill5b772312018-03-08 20:28:32 -05005625bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005626{
5627 return ValidateUniform(context, GL_FLOAT, location, count);
5628}
5629
Jamie Madill5b772312018-03-08 20:28:32 -05005630bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005631{
5632 return ValidateUniform1iv(context, location, 1, &x);
5633}
5634
Jamie Madill5b772312018-03-08 20:28:32 -05005635bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005636{
5637 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5638}
5639
Jamie Madill5b772312018-03-08 20:28:32 -05005640bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005641{
5642 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5643}
5644
Jamie Madill5b772312018-03-08 20:28:32 -05005645bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005646{
5647 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5648}
5649
Jamie Madill5b772312018-03-08 20:28:32 -05005650bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005651{
5652 return ValidateUniform(context, GL_INT_VEC2, location, count);
5653}
5654
Jamie Madill5b772312018-03-08 20:28:32 -05005655bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005656{
5657 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5658}
5659
Jamie Madill5b772312018-03-08 20:28:32 -05005660bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005661{
5662 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5663}
5664
Jamie Madill5b772312018-03-08 20:28:32 -05005665bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005666{
5667 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5668}
5669
Jamie Madill5b772312018-03-08 20:28:32 -05005670bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005671{
5672 return ValidateUniform(context, GL_INT_VEC3, location, count);
5673}
5674
Jamie Madill5b772312018-03-08 20:28:32 -05005675bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005676{
5677 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5678}
5679
Jamie Madill5b772312018-03-08 20:28:32 -05005680bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005681{
5682 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5683}
5684
Jamie Madill5b772312018-03-08 20:28:32 -05005685bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005686{
5687 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5688}
5689
Jamie Madill5b772312018-03-08 20:28:32 -05005690bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005691{
5692 return ValidateUniform(context, GL_INT_VEC4, location, count);
5693}
5694
Jamie Madill5b772312018-03-08 20:28:32 -05005695bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005696 GLint location,
5697 GLsizei count,
5698 GLboolean transpose,
5699 const GLfloat *value)
5700{
5701 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5702}
5703
Jamie Madill5b772312018-03-08 20:28:32 -05005704bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005705 GLint location,
5706 GLsizei count,
5707 GLboolean transpose,
5708 const GLfloat *value)
5709{
5710 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5711}
5712
Jamie Madill5b772312018-03-08 20:28:32 -05005713bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005714 GLint location,
5715 GLsizei count,
5716 GLboolean transpose,
5717 const GLfloat *value)
5718{
5719 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5720}
5721
Jamie Madill5b772312018-03-08 20:28:32 -05005722bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005723{
5724 Program *programObject = GetValidProgram(context, program);
5725
5726 if (!programObject)
5727 {
5728 return false;
5729 }
5730
5731 return true;
5732}
5733
Jamie Madill5b772312018-03-08 20:28:32 -05005734bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005735{
5736 return ValidateVertexAttribIndex(context, index);
5737}
5738
Jamie Madill5b772312018-03-08 20:28:32 -05005739bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005740{
5741 return ValidateVertexAttribIndex(context, index);
5742}
5743
Jamie Madill5b772312018-03-08 20:28:32 -05005744bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005745{
5746 return ValidateVertexAttribIndex(context, index);
5747}
5748
Jamie Madill5b772312018-03-08 20:28:32 -05005749bool ValidateVertexAttrib2fv(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 ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005755{
5756 return ValidateVertexAttribIndex(context, index);
5757}
5758
Jamie Madill5b772312018-03-08 20:28:32 -05005759bool ValidateVertexAttrib3fv(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 ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005765 GLuint index,
5766 GLfloat x,
5767 GLfloat y,
5768 GLfloat z,
5769 GLfloat w)
5770{
5771 return ValidateVertexAttribIndex(context, index);
5772}
5773
Jamie Madill5b772312018-03-08 20:28:32 -05005774bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005775{
5776 return ValidateVertexAttribIndex(context, index);
5777}
5778
Jamie Madill5b772312018-03-08 20:28:32 -05005779bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005780{
5781 if (width < 0 || height < 0)
5782 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005783 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005784 return false;
5785 }
5786
5787 return true;
5788}
5789
Jamie Madill493f9572018-05-24 19:52:15 -04005790bool ValidateDrawArrays(Context *context, PrimitiveMode mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005791{
5792 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5793}
5794
Jamie Madill5b772312018-03-08 20:28:32 -05005795bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005796 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005797 GLsizei count,
5798 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005799 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005800{
5801 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5802}
5803
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005804bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005805 GLenum target,
5806 GLenum attachment,
5807 GLenum pname,
5808 GLint *params)
5809{
5810 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5811 nullptr);
5812}
5813
Jamie Madill5b772312018-03-08 20:28:32 -05005814bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005815{
5816 return ValidateGetProgramivBase(context, program, pname, nullptr);
5817}
5818
Jamie Madill5b772312018-03-08 20:28:32 -05005819bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005820 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005821 GLint level,
5822 GLenum internalformat,
5823 GLint x,
5824 GLint y,
5825 GLsizei width,
5826 GLsizei height,
5827 GLint border)
5828{
5829 if (context->getClientMajorVersion() < 3)
5830 {
5831 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5832 0, x, y, width, height, border);
5833 }
5834
5835 ASSERT(context->getClientMajorVersion() == 3);
5836 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5837 0, x, y, width, height, border);
5838}
5839
5840bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005841 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005842 GLint level,
5843 GLint xoffset,
5844 GLint yoffset,
5845 GLint x,
5846 GLint y,
5847 GLsizei width,
5848 GLsizei height)
5849{
5850 if (context->getClientMajorVersion() < 3)
5851 {
5852 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5853 yoffset, x, y, width, height, 0);
5854 }
5855
5856 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5857 yoffset, 0, x, y, width, height, 0);
5858}
5859
5860bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5861{
5862 return ValidateGenOrDelete(context, n);
5863}
5864
5865bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5866{
5867 return ValidateGenOrDelete(context, n);
5868}
5869
5870bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5871{
5872 return ValidateGenOrDelete(context, n);
5873}
5874
5875bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5876{
5877 return ValidateGenOrDelete(context, n);
5878}
5879
5880bool ValidateDisable(Context *context, GLenum cap)
5881{
5882 if (!ValidCap(context, cap, false))
5883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005884 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005885 return false;
5886 }
5887
5888 return true;
5889}
5890
5891bool ValidateEnable(Context *context, GLenum cap)
5892{
5893 if (!ValidCap(context, cap, false))
5894 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005895 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005896 return false;
5897 }
5898
5899 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5900 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5901 {
5902 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005903 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005904
5905 // We also output an error message to the debugger window if tracing is active, so that
5906 // developers can see the error message.
5907 ERR() << errorMessage;
5908 return false;
5909 }
5910
5911 return true;
5912}
5913
5914bool ValidateFramebufferRenderbuffer(Context *context,
5915 GLenum target,
5916 GLenum attachment,
5917 GLenum renderbuffertarget,
5918 GLuint renderbuffer)
5919{
Geoff Lange8afa902017-09-27 15:00:43 -04005920 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005921 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005922 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5923 return false;
5924 }
5925
5926 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5927 {
5928 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005929 return false;
5930 }
5931
5932 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5933 renderbuffertarget, renderbuffer);
5934}
5935
5936bool ValidateFramebufferTexture2D(Context *context,
5937 GLenum target,
5938 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005939 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005940 GLuint texture,
5941 GLint level)
5942{
5943 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5944 // extension
5945 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5946 level != 0)
5947 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005948 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005949 return false;
5950 }
5951
5952 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5953 {
5954 return false;
5955 }
5956
5957 if (texture != 0)
5958 {
5959 gl::Texture *tex = context->getTexture(texture);
5960 ASSERT(tex);
5961
5962 const gl::Caps &caps = context->getCaps();
5963
5964 switch (textarget)
5965 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005966 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005967 {
5968 if (level > gl::log2(caps.max2DTextureSize))
5969 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005970 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005971 return false;
5972 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005973 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005974 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005975 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005976 return false;
5977 }
5978 }
5979 break;
5980
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005981 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005982 {
5983 if (level != 0)
5984 {
5985 context->handleError(InvalidValue());
5986 return false;
5987 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005988 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005989 {
5990 context->handleError(InvalidOperation()
5991 << "Textarget must match the texture target type.");
5992 return false;
5993 }
5994 }
5995 break;
5996
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005997 case TextureTarget::CubeMapNegativeX:
5998 case TextureTarget::CubeMapNegativeY:
5999 case TextureTarget::CubeMapNegativeZ:
6000 case TextureTarget::CubeMapPositiveX:
6001 case TextureTarget::CubeMapPositiveY:
6002 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006003 {
6004 if (level > gl::log2(caps.maxCubeMapTextureSize))
6005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006006 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006007 return false;
6008 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006009 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006011 context->handleError(InvalidOperation()
6012 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 return false;
6014 }
6015 }
6016 break;
6017
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006018 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006019 {
6020 if (context->getClientVersion() < ES_3_1)
6021 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006022 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006023 return false;
6024 }
6025
6026 if (level != 0)
6027 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006028 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006029 return false;
6030 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006031 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006032 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006033 context->handleError(InvalidOperation()
6034 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006035 return false;
6036 }
6037 }
6038 break;
6039
6040 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006041 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 return false;
6043 }
6044
6045 const Format &format = tex->getFormat(textarget, level);
6046 if (format.info->compressed)
6047 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006048 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 return false;
6050 }
6051 }
6052
6053 return true;
6054}
6055
6056bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6057{
6058 return ValidateGenOrDelete(context, n);
6059}
6060
6061bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6062{
6063 return ValidateGenOrDelete(context, n);
6064}
6065
6066bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6067{
6068 return ValidateGenOrDelete(context, n);
6069}
6070
6071bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6072{
6073 return ValidateGenOrDelete(context, n);
6074}
6075
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006076bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006077{
6078 if (!ValidTextureTarget(context, target))
6079 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006080 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006081 return false;
6082 }
6083
6084 Texture *texture = context->getTargetTexture(target);
6085
6086 if (texture == nullptr)
6087 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006088 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006089 return false;
6090 }
6091
6092 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6093
6094 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6095 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6096 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6097 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006098 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006099 return false;
6100 }
6101
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006102 TextureTarget baseTarget = (target == TextureType::CubeMap)
6103 ? TextureTarget::CubeMapPositiveX
6104 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006105 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6106 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6107 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006108 {
6109 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6110 return false;
6111 }
6112
Geoff Lang536eca12017-09-13 11:23:35 -04006113 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6114 bool formatUnsized = !format.sized;
6115 bool formatColorRenderableAndFilterable =
6116 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006117 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006118 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006119 {
Geoff Lang536eca12017-09-13 11:23:35 -04006120 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006121 return false;
6122 }
6123
Geoff Lang536eca12017-09-13 11:23:35 -04006124 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6125 // generation
6126 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6127 {
6128 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6129 return false;
6130 }
6131
6132 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
Geoff Lange24032a2018-03-28 15:41:46 -04006133 // not. Differentiate the ES3 format from the extension format by checking if the format is
6134 // sized, GL_EXT_sRGB does not add any sized formats.
6135 bool supportsSRGBMipmapGeneration = context->getExtensions().webglCompatibility;
6136 if (!supportsSRGBMipmapGeneration && !format.sized && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006137 {
Geoff Lang536eca12017-09-13 11:23:35 -04006138 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006139 return false;
6140 }
6141
6142 // Non-power of 2 ES2 check
6143 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6144 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6145 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6146 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006147 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6148 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006149 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006150 return false;
6151 }
6152
6153 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006154 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006156 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006157 return false;
6158 }
6159
6160 return true;
6161}
6162
Jamie Madill5b772312018-03-08 20:28:32 -05006163bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006164 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006165 GLenum pname,
6166 GLint *params)
6167{
6168 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6169}
6170
6171bool ValidateGetRenderbufferParameteriv(Context *context,
6172 GLenum target,
6173 GLenum pname,
6174 GLint *params)
6175{
6176 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6177}
6178
6179bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6180{
6181 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6182}
6183
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006184bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006185{
6186 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6187}
6188
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006189bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006190{
6191 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6192}
6193
6194bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6195{
6196 return ValidateGetUniformBase(context, program, location);
6197}
6198
6199bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6200{
6201 return ValidateGetUniformBase(context, program, location);
6202}
6203
6204bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6205{
6206 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6207}
6208
6209bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6210{
6211 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6212}
6213
6214bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6215{
6216 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6217}
6218
6219bool ValidateIsEnabled(Context *context, GLenum cap)
6220{
6221 if (!ValidCap(context, cap, true))
6222 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006223 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006224 return false;
6225 }
6226
6227 return true;
6228}
6229
6230bool ValidateLinkProgram(Context *context, GLuint program)
6231{
6232 if (context->hasActiveTransformFeedback(program))
6233 {
6234 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006235 context->handleError(InvalidOperation() << "Cannot link program while program is "
6236 "associated with an active transform "
6237 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006238 return false;
6239 }
6240
6241 Program *programObject = GetValidProgram(context, program);
6242 if (!programObject)
6243 {
6244 return false;
6245 }
6246
6247 return true;
6248}
6249
Jamie Madill4928b7c2017-06-20 12:57:39 -04006250bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006251 GLint x,
6252 GLint y,
6253 GLsizei width,
6254 GLsizei height,
6255 GLenum format,
6256 GLenum type,
6257 void *pixels)
6258{
6259 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6260 nullptr, pixels);
6261}
6262
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006263bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006264{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006265 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006266}
6267
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006268bool ValidateTexParameterfv(Context *context,
6269 TextureType target,
6270 GLenum pname,
6271 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006272{
6273 return ValidateTexParameterBase(context, target, pname, -1, params);
6274}
6275
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006276bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006277{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006278 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006279}
6280
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006281bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006282{
6283 return ValidateTexParameterBase(context, target, pname, -1, params);
6284}
6285
6286bool ValidateUseProgram(Context *context, GLuint program)
6287{
6288 if (program != 0)
6289 {
6290 Program *programObject = context->getProgram(program);
6291 if (!programObject)
6292 {
6293 // ES 3.1.0 section 7.3 page 72
6294 if (context->getShader(program))
6295 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006296 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006297 return false;
6298 }
6299 else
6300 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006301 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006302 return false;
6303 }
6304 }
6305 if (!programObject->isLinked())
6306 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006307 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006308 return false;
6309 }
6310 }
6311 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6312 {
6313 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006314 context
6315 ->handleError(InvalidOperation()
6316 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006317 return false;
6318 }
6319
6320 return true;
6321}
6322
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006323bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6324{
6325 if (!context->getExtensions().fence)
6326 {
6327 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6328 return false;
6329 }
6330
6331 if (n < 0)
6332 {
6333 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6334 return false;
6335 }
6336
6337 return true;
6338}
6339
6340bool ValidateFinishFenceNV(Context *context, GLuint fence)
6341{
6342 if (!context->getExtensions().fence)
6343 {
6344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6345 return false;
6346 }
6347
6348 FenceNV *fenceObject = context->getFenceNV(fence);
6349
6350 if (fenceObject == nullptr)
6351 {
6352 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6353 return false;
6354 }
6355
6356 if (!fenceObject->isSet())
6357 {
6358 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6359 return false;
6360 }
6361
6362 return true;
6363}
6364
6365bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6366{
6367 if (!context->getExtensions().fence)
6368 {
6369 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6370 return false;
6371 }
6372
6373 if (n < 0)
6374 {
6375 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6376 return false;
6377 }
6378
6379 return true;
6380}
6381
6382bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6383{
6384 if (!context->getExtensions().fence)
6385 {
6386 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6387 return false;
6388 }
6389
6390 FenceNV *fenceObject = context->getFenceNV(fence);
6391
6392 if (fenceObject == nullptr)
6393 {
6394 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6395 return false;
6396 }
6397
6398 if (!fenceObject->isSet())
6399 {
6400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6401 return false;
6402 }
6403
6404 switch (pname)
6405 {
6406 case GL_FENCE_STATUS_NV:
6407 case GL_FENCE_CONDITION_NV:
6408 break;
6409
6410 default:
6411 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6412 return false;
6413 }
6414
6415 return true;
6416}
6417
6418bool ValidateGetGraphicsResetStatusEXT(Context *context)
6419{
6420 if (!context->getExtensions().robustness)
6421 {
6422 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6423 return false;
6424 }
6425
6426 return true;
6427}
6428
6429bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6430 GLuint shader,
6431 GLsizei bufsize,
6432 GLsizei *length,
6433 GLchar *source)
6434{
6435 if (!context->getExtensions().translatedShaderSource)
6436 {
6437 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6438 return false;
6439 }
6440
6441 if (bufsize < 0)
6442 {
6443 context->handleError(InvalidValue());
6444 return false;
6445 }
6446
6447 Shader *shaderObject = context->getShader(shader);
6448
6449 if (!shaderObject)
6450 {
6451 context->handleError(InvalidOperation());
6452 return false;
6453 }
6454
6455 return true;
6456}
6457
6458bool ValidateIsFenceNV(Context *context, GLuint fence)
6459{
6460 if (!context->getExtensions().fence)
6461 {
6462 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6463 return false;
6464 }
6465
6466 return true;
6467}
6468
Jamie Madill007530e2017-12-28 14:27:04 -05006469bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6470{
6471 if (!context->getExtensions().fence)
6472 {
6473 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6474 return false;
6475 }
6476
6477 if (condition != GL_ALL_COMPLETED_NV)
6478 {
6479 context->handleError(InvalidEnum());
6480 return false;
6481 }
6482
6483 FenceNV *fenceObject = context->getFenceNV(fence);
6484
6485 if (fenceObject == nullptr)
6486 {
6487 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6488 return false;
6489 }
6490
6491 return true;
6492}
6493
6494bool ValidateTestFenceNV(Context *context, GLuint fence)
6495{
6496 if (!context->getExtensions().fence)
6497 {
6498 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6499 return false;
6500 }
6501
6502 FenceNV *fenceObject = context->getFenceNV(fence);
6503
6504 if (fenceObject == nullptr)
6505 {
6506 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6507 return false;
6508 }
6509
6510 if (fenceObject->isSet() != GL_TRUE)
6511 {
6512 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6513 return false;
6514 }
6515
6516 return true;
6517}
6518
6519bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006520 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006521 GLsizei levels,
6522 GLenum internalformat,
6523 GLsizei width,
6524 GLsizei height)
6525{
6526 if (!context->getExtensions().textureStorage)
6527 {
6528 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6529 return false;
6530 }
6531
6532 if (context->getClientMajorVersion() < 3)
6533 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006534 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006535 height);
6536 }
6537
6538 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006539 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006540 1);
6541}
6542
6543bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6544{
6545 if (!context->getExtensions().instancedArrays)
6546 {
6547 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6548 return false;
6549 }
6550
6551 if (index >= MAX_VERTEX_ATTRIBS)
6552 {
6553 context->handleError(InvalidValue());
6554 return false;
6555 }
6556
6557 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6558 {
6559 if (index == 0 && divisor != 0)
6560 {
6561 const char *errorMessage =
6562 "The current context doesn't support setting a non-zero divisor on the "
6563 "attribute with index zero. "
6564 "Please reorder the attributes in your vertex shader so that attribute zero "
6565 "can have a zero divisor.";
6566 context->handleError(InvalidOperation() << errorMessage);
6567
6568 // We also output an error message to the debugger window if tracing is active, so
6569 // that developers can see the error message.
6570 ERR() << errorMessage;
6571 return false;
6572 }
6573 }
6574
6575 return true;
6576}
6577
6578bool ValidateTexImage3DOES(Context *context,
6579 GLenum target,
6580 GLint level,
6581 GLenum internalformat,
6582 GLsizei width,
6583 GLsizei height,
6584 GLsizei depth,
6585 GLint border,
6586 GLenum format,
6587 GLenum type,
6588 const void *pixels)
6589{
6590 UNIMPLEMENTED(); // FIXME
6591 return false;
6592}
6593
6594bool ValidatePopGroupMarkerEXT(Context *context)
6595{
6596 if (!context->getExtensions().debugMarker)
6597 {
6598 // The debug marker calls should not set error state
6599 // However, it seems reasonable to set an error state if the extension is not enabled
6600 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6601 return false;
6602 }
6603
6604 return true;
6605}
6606
Jamie Madillfa920eb2018-01-04 11:45:50 -05006607bool ValidateTexStorage1DEXT(Context *context,
6608 GLenum target,
6609 GLsizei levels,
6610 GLenum internalformat,
6611 GLsizei width)
6612{
6613 UNIMPLEMENTED();
6614 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6615 return false;
6616}
6617
6618bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006619 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006620 GLsizei levels,
6621 GLenum internalformat,
6622 GLsizei width,
6623 GLsizei height,
6624 GLsizei depth)
6625{
6626 if (!context->getExtensions().textureStorage)
6627 {
6628 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6629 return false;
6630 }
6631
6632 if (context->getClientMajorVersion() < 3)
6633 {
6634 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6635 return false;
6636 }
6637
6638 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6639 depth);
6640}
6641
jchen1082af6202018-06-22 10:59:52 +08006642bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6643{
6644 if (!context->getExtensions().parallelShaderCompile)
6645 {
6646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6647 return false;
6648 }
6649 return true;
6650}
6651
Jamie Madillc29968b2016-01-20 11:17:23 -05006652} // namespace gl