blob: fb72f6c0dd75c06f15c014b067189318641ae887 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070078 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030079 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madill5b772312018-03-08 20:28:32 -0500458bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700795 // GLES1 emulation: GLES1-specific caps
796 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700797 case GL_VERTEX_ARRAY:
798 case GL_NORMAL_ARRAY:
799 case GL_COLOR_ARRAY:
800 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700801 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700802 case GL_LIGHTING:
803 case GL_LIGHT0:
804 case GL_LIGHT1:
805 case GL_LIGHT2:
806 case GL_LIGHT3:
807 case GL_LIGHT4:
808 case GL_LIGHT5:
809 case GL_LIGHT6:
810 case GL_LIGHT7:
811 case GL_NORMALIZE:
812 case GL_RESCALE_NORMAL:
813 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700814 case GL_CLIP_PLANE0:
815 case GL_CLIP_PLANE1:
816 case GL_CLIP_PLANE2:
817 case GL_CLIP_PLANE3:
818 case GL_CLIP_PLANE4:
819 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700820 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700821 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700822 case GL_LINE_SMOOTH:
823 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700824 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700825 case GL_POINT_SIZE_ARRAY_OES:
826 return context->getClientVersion() < Version(2, 0) &&
827 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700828 case GL_TEXTURE_CUBE_MAP:
829 return context->getClientVersion() < Version(2, 0) &&
830 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700831 case GL_POINT_SPRITE_OES:
832 return context->getClientVersion() < Version(2, 0) &&
833 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400834 default:
835 return false;
836 }
837}
838
Geoff Langfc32e8b2017-05-31 14:16:59 -0400839// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
840// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400841bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400842{
843 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400844 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
845 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400846 {
847 return true;
848 }
849
850 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
851 if (c >= 9 && c <= 13)
852 {
853 return true;
854 }
855
856 return false;
857}
858
Geoff Langcab92ee2017-07-19 17:32:07 -0400859bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400860{
Geoff Langa71a98e2017-06-19 15:15:00 -0400861 for (size_t i = 0; i < len; i++)
862 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400863 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400864 {
865 return false;
866 }
867 }
868
869 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400870}
871
Geoff Langcab92ee2017-07-19 17:32:07 -0400872bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
873{
874 enum class ParseState
875 {
876 // Have not seen an ASCII non-whitespace character yet on
877 // this line. Possible that we might see a preprocessor
878 // directive.
879 BEGINING_OF_LINE,
880
881 // Have seen at least one ASCII non-whitespace character
882 // on this line.
883 MIDDLE_OF_LINE,
884
885 // Handling a preprocessor directive. Passes through all
886 // characters up to the end of the line. Disables comment
887 // processing.
888 IN_PREPROCESSOR_DIRECTIVE,
889
890 // Handling a single-line comment. The comment text is
891 // replaced with a single space.
892 IN_SINGLE_LINE_COMMENT,
893
894 // Handling a multi-line comment. Newlines are passed
895 // through to preserve line numbers.
896 IN_MULTI_LINE_COMMENT
897 };
898
899 ParseState state = ParseState::BEGINING_OF_LINE;
900 size_t pos = 0;
901
902 while (pos < len)
903 {
904 char c = str[pos];
905 char next = pos + 1 < len ? str[pos + 1] : 0;
906
907 // Check for newlines
908 if (c == '\n' || c == '\r')
909 {
910 if (state != ParseState::IN_MULTI_LINE_COMMENT)
911 {
912 state = ParseState::BEGINING_OF_LINE;
913 }
914
915 pos++;
916 continue;
917 }
918
919 switch (state)
920 {
921 case ParseState::BEGINING_OF_LINE:
922 if (c == ' ')
923 {
924 // Maintain the BEGINING_OF_LINE state until a non-space is seen
925 pos++;
926 }
927 else if (c == '#')
928 {
929 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
930 pos++;
931 }
932 else
933 {
934 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
935 state = ParseState::MIDDLE_OF_LINE;
936 }
937 break;
938
939 case ParseState::MIDDLE_OF_LINE:
940 if (c == '/' && next == '/')
941 {
942 state = ParseState::IN_SINGLE_LINE_COMMENT;
943 pos++;
944 }
945 else if (c == '/' && next == '*')
946 {
947 state = ParseState::IN_MULTI_LINE_COMMENT;
948 pos++;
949 }
950 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
951 {
952 // Skip line continuation characters
953 }
954 else if (!IsValidESSLCharacter(c))
955 {
956 return false;
957 }
958 pos++;
959 break;
960
961 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700962 // Line-continuation characters may not be permitted.
963 // Otherwise, just pass it through. Do not parse comments in this state.
964 if (!lineContinuationAllowed && c == '\\')
965 {
966 return false;
967 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400968 pos++;
969 break;
970
971 case ParseState::IN_SINGLE_LINE_COMMENT:
972 // Line-continuation characters are processed before comment processing.
973 // Advance string if a new line character is immediately behind
974 // line-continuation character.
975 if (c == '\\' && (next == '\n' || next == '\r'))
976 {
977 pos++;
978 }
979 pos++;
980 break;
981
982 case ParseState::IN_MULTI_LINE_COMMENT:
983 if (c == '*' && next == '/')
984 {
985 state = ParseState::MIDDLE_OF_LINE;
986 pos++;
987 }
988 pos++;
989 break;
990 }
991 }
992
993 return true;
994}
995
Jamie Madill5b772312018-03-08 20:28:32 -0500996bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700997{
998 ASSERT(context->isWebGL());
999
1000 // WebGL 1.0 [Section 6.16] GLSL Constructs
1001 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1002 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1003 {
1004 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1005 return false;
1006 }
1007
1008 return true;
1009}
1010
Jamie Madill5b772312018-03-08 20:28:32 -05001011bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001012{
1013 ASSERT(context->isWebGL());
1014
1015 if (context->isWebGL1() && length > 256)
1016 {
1017 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1018 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1019 // locations.
1020 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1021
1022 return false;
1023 }
1024 else if (length > 1024)
1025 {
1026 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1027 // uniform and attribute locations.
1028 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1029 return false;
1030 }
1031
1032 return true;
1033}
1034
Jamie Madill007530e2017-12-28 14:27:04 -05001035bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1036{
1037 if (!context->getExtensions().pathRendering)
1038 {
1039 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1040 return false;
1041 }
1042
1043 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1044 {
1045 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1046 return false;
1047 }
1048 return true;
1049}
Jamie Madillc29968b2016-01-20 11:17:23 -05001050} // anonymous namespace
1051
Geoff Langff5b2d52016-09-07 11:32:23 -04001052bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001053 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001054 GLint level,
1055 GLenum internalformat,
1056 bool isCompressed,
1057 bool isSubImage,
1058 GLint xoffset,
1059 GLint yoffset,
1060 GLsizei width,
1061 GLsizei height,
1062 GLint border,
1063 GLenum format,
1064 GLenum type,
1065 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001066 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001067{
Jamie Madill6f38f822014-06-06 17:12:20 -04001068 if (!ValidTexture2DDestinationTarget(context, target))
1069 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001070 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001071 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001072 }
1073
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001074 TextureType texType = TextureTargetToType(target);
1075 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001076 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001077 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001078 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001079 }
1080
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001081 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001082 {
1083 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1084 return false;
1085 }
1086
1087 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001088 std::numeric_limits<GLsizei>::max() - yoffset < height)
1089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001090 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001091 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001092 }
1093
Geoff Lang6e898aa2017-06-02 11:17:26 -04001094 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1095 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1096 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1097 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1098 // case.
1099 bool nonEqualFormatsAllowed =
1100 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1101 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1102
1103 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001104 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001105 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001106 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001107 }
1108
Geoff Langaae65a42014-05-26 12:43:44 -04001109 const gl::Caps &caps = context->getCaps();
1110
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001111 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001112 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001113 case TextureType::_2D:
1114 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1115 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1116 {
1117 context->handleError(InvalidValue());
1118 return false;
1119 }
1120 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001121
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001122 case TextureType::Rectangle:
1123 ASSERT(level == 0);
1124 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1125 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1126 {
1127 context->handleError(InvalidValue());
1128 return false;
1129 }
1130 if (isCompressed)
1131 {
1132 context->handleError(InvalidEnum()
1133 << "Rectangle texture cannot have a compressed format.");
1134 return false;
1135 }
1136 break;
1137
1138 case TextureType::CubeMap:
1139 if (!isSubImage && width != height)
1140 {
1141 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1142 return false;
1143 }
1144
1145 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1146 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1147 {
1148 context->handleError(InvalidValue());
1149 return false;
1150 }
1151 break;
1152
1153 default:
1154 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001155 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001156 }
1157
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001158 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001159 if (!texture)
1160 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001161 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001162 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001163 }
1164
Geoff Langa9be0dc2014-12-17 12:34:40 -05001165 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001166 {
Geoff Langca271392017-04-05 12:30:00 -04001167 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1168 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001169 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001170 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001171 return false;
1172 }
1173
Geoff Langa9be0dc2014-12-17 12:34:40 -05001174 if (format != GL_NONE)
1175 {
Geoff Langca271392017-04-05 12:30:00 -04001176 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1177 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001178 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001179 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001180 return false;
1181 }
1182 }
1183
1184 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1185 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1186 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001187 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001188 return false;
1189 }
Geoff Langfb052642017-10-24 13:42:09 -04001190
1191 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001192 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001193 {
1194 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1195 return false;
1196 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001197 }
1198 else
1199 {
Geoff Lang69cce582015-09-17 13:20:36 -04001200 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001201 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001202 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001203 return false;
1204 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001205 }
1206
1207 // Verify zero border
1208 if (border != 0)
1209 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001210 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001211 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001212 }
1213
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001214 if (isCompressed)
1215 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001216 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001217 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1218 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001219
1220 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1221
1222 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001223 {
Geoff Lange88e4542018-05-03 15:05:57 -04001224 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1225 return false;
1226 }
1227
1228 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1229 context->getExtensions()))
1230 {
1231 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1232 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001233 }
Geoff Lang966c9402017-04-18 12:38:27 -04001234
1235 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001236 {
Geoff Lange88e4542018-05-03 15:05:57 -04001237 // From the OES_compressed_ETC1_RGB8_texture spec:
1238 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1239 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1240 // ETC1_RGB8_OES.
1241 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1242 {
1243 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1244 return false;
1245 }
1246
Geoff Lang966c9402017-04-18 12:38:27 -04001247 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1248 height, texture->getWidth(target, level),
1249 texture->getHeight(target, level)))
1250 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001251 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001252 return false;
1253 }
1254
1255 if (format != actualInternalFormat)
1256 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001257 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001258 return false;
1259 }
1260 }
1261 else
1262 {
1263 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1264 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001265 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001266 return false;
1267 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001268 }
1269 }
1270 else
1271 {
1272 // validate <type> by itself (used as secondary key below)
1273 switch (type)
1274 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001275 case GL_UNSIGNED_BYTE:
1276 case GL_UNSIGNED_SHORT_5_6_5:
1277 case GL_UNSIGNED_SHORT_4_4_4_4:
1278 case GL_UNSIGNED_SHORT_5_5_5_1:
1279 case GL_UNSIGNED_SHORT:
1280 case GL_UNSIGNED_INT:
1281 case GL_UNSIGNED_INT_24_8_OES:
1282 case GL_HALF_FLOAT_OES:
1283 case GL_FLOAT:
1284 break;
1285 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001286 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001287 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001288 }
1289
1290 // validate <format> + <type> combinations
1291 // - invalid <format> -> sets INVALID_ENUM
1292 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1293 switch (format)
1294 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001295 case GL_ALPHA:
1296 case GL_LUMINANCE:
1297 case GL_LUMINANCE_ALPHA:
1298 switch (type)
1299 {
1300 case GL_UNSIGNED_BYTE:
1301 case GL_FLOAT:
1302 case GL_HALF_FLOAT_OES:
1303 break;
1304 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001306 return false;
1307 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001308 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001309 case GL_RED:
1310 case GL_RG:
1311 if (!context->getExtensions().textureRG)
1312 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001313 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001314 return false;
1315 }
1316 switch (type)
1317 {
1318 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001319 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001320 case GL_FLOAT:
1321 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001322 if (!context->getExtensions().textureFloat)
1323 {
1324 context->handleError(InvalidEnum());
1325 return false;
1326 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001327 break;
1328 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001329 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001330 return false;
1331 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001332 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001333 case GL_RGB:
1334 switch (type)
1335 {
1336 case GL_UNSIGNED_BYTE:
1337 case GL_UNSIGNED_SHORT_5_6_5:
1338 case GL_FLOAT:
1339 case GL_HALF_FLOAT_OES:
1340 break;
1341 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001342 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001343 return false;
1344 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001345 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001346 case GL_RGBA:
1347 switch (type)
1348 {
1349 case GL_UNSIGNED_BYTE:
1350 case GL_UNSIGNED_SHORT_4_4_4_4:
1351 case GL_UNSIGNED_SHORT_5_5_5_1:
1352 case GL_FLOAT:
1353 case GL_HALF_FLOAT_OES:
1354 break;
1355 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001356 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001357 return false;
1358 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001359 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001360 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001361 if (!context->getExtensions().textureFormatBGRA8888)
1362 {
1363 context->handleError(InvalidEnum());
1364 return false;
1365 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001366 switch (type)
1367 {
1368 case GL_UNSIGNED_BYTE:
1369 break;
1370 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001371 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001372 return false;
1373 }
1374 break;
1375 case GL_SRGB_EXT:
1376 case GL_SRGB_ALPHA_EXT:
1377 if (!context->getExtensions().sRGB)
1378 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001379 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001380 return false;
1381 }
1382 switch (type)
1383 {
1384 case GL_UNSIGNED_BYTE:
1385 break;
1386 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001387 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001388 return false;
1389 }
1390 break;
1391 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1392 // handled below
1393 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1394 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1395 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1396 break;
1397 case GL_DEPTH_COMPONENT:
1398 switch (type)
1399 {
1400 case GL_UNSIGNED_SHORT:
1401 case GL_UNSIGNED_INT:
1402 break;
1403 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001404 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001405 return false;
1406 }
1407 break;
1408 case GL_DEPTH_STENCIL_OES:
1409 switch (type)
1410 {
1411 case GL_UNSIGNED_INT_24_8_OES:
1412 break;
1413 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001414 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001415 return false;
1416 }
1417 break;
1418 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001419 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001420 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001421 }
1422
1423 switch (format)
1424 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001425 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1426 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1427 if (context->getExtensions().textureCompressionDXT1)
1428 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001429 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001430 return false;
1431 }
1432 else
1433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001434 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001435 return false;
1436 }
1437 break;
1438 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1439 if (context->getExtensions().textureCompressionDXT3)
1440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001441 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001442 return false;
1443 }
1444 else
1445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001446 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001447 return false;
1448 }
1449 break;
1450 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1451 if (context->getExtensions().textureCompressionDXT5)
1452 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001453 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001454 return false;
1455 }
1456 else
1457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001458 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001459 return false;
1460 }
1461 break;
1462 case GL_ETC1_RGB8_OES:
1463 if (context->getExtensions().compressedETC1RGB8Texture)
1464 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001465 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001466 return false;
1467 }
1468 else
1469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001470 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001471 return false;
1472 }
1473 break;
1474 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001475 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1476 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1477 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1478 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001479 if (context->getExtensions().lossyETCDecode)
1480 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001481 context->handleError(InvalidOperation()
1482 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001483 return false;
1484 }
1485 else
1486 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001487 context->handleError(InvalidEnum()
1488 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001489 return false;
1490 }
1491 break;
1492 case GL_DEPTH_COMPONENT:
1493 case GL_DEPTH_STENCIL_OES:
1494 if (!context->getExtensions().depthTextures)
1495 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001496 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 return false;
1498 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001499 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001500 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001502 return false;
1503 }
1504 // OES_depth_texture supports loading depth data and multiple levels,
1505 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001506 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001507 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1509 return false;
1510 }
1511 if (level != 0)
1512 {
1513 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001514 return false;
1515 }
1516 break;
1517 default:
1518 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001519 }
1520
Geoff Lang6e898aa2017-06-02 11:17:26 -04001521 if (!isSubImage)
1522 {
1523 switch (internalformat)
1524 {
1525 case GL_RGBA32F:
1526 if (!context->getExtensions().colorBufferFloatRGBA)
1527 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001528 context->handleError(InvalidValue()
1529 << "Sized GL_RGBA32F internal format requires "
1530 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001531 return false;
1532 }
1533 if (type != GL_FLOAT)
1534 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001535 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001536 return false;
1537 }
1538 if (format != GL_RGBA)
1539 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001540 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001541 return false;
1542 }
1543 break;
1544
1545 case GL_RGB32F:
1546 if (!context->getExtensions().colorBufferFloatRGB)
1547 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001548 context->handleError(InvalidValue()
1549 << "Sized GL_RGB32F internal format requires "
1550 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001551 return false;
1552 }
1553 if (type != GL_FLOAT)
1554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001555 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001556 return false;
1557 }
1558 if (format != GL_RGB)
1559 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001560 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001561 return false;
1562 }
1563 break;
1564
1565 default:
1566 break;
1567 }
1568 }
1569
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001570 if (type == GL_FLOAT)
1571 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001572 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001573 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001574 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001575 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001576 }
1577 }
1578 else if (type == GL_HALF_FLOAT_OES)
1579 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001580 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001581 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001582 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001583 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001584 }
1585 }
1586 }
1587
Geoff Langdbcced82017-06-06 15:55:54 -04001588 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001589 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001590 imageSize))
1591 {
1592 return false;
1593 }
1594
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001595 return true;
1596}
1597
He Yunchaoced53ae2016-11-29 15:00:51 +08001598bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001599 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001600 GLsizei levels,
1601 GLenum internalformat,
1602 GLsizei width,
1603 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001604{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001605 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1606 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001607 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001608 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001609 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001610 }
1611
1612 if (width < 1 || height < 1 || levels < 1)
1613 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001614 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001615 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001616 }
1617
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001618 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001619 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001620 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001621 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001622 }
1623
1624 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1625 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001626 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001627 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001628 }
1629
Geoff Langca271392017-04-05 12:30:00 -04001630 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001631 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001632 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001633 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001634 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001635 }
1636
Geoff Langaae65a42014-05-26 12:43:44 -04001637 const gl::Caps &caps = context->getCaps();
1638
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001639 switch (target)
1640 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001641 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001642 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1643 static_cast<GLuint>(height) > caps.max2DTextureSize)
1644 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001645 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001646 return false;
1647 }
1648 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001649 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001650 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1651 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1652 {
1653 context->handleError(InvalidValue());
1654 return false;
1655 }
1656 if (formatInfo.compressed)
1657 {
1658 context->handleError(InvalidEnum()
1659 << "Rectangle texture cannot have a compressed format.");
1660 return false;
1661 }
1662 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001663 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001664 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1665 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1666 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001667 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001668 return false;
1669 }
1670 break;
1671 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001672 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001673 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001674 }
1675
Geoff Langc0b9ef42014-07-02 10:02:37 -04001676 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001677 {
1678 if (!gl::isPow2(width) || !gl::isPow2(height))
1679 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001680 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001681 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001682 }
1683 }
1684
1685 switch (internalformat)
1686 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001687 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1688 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1689 if (!context->getExtensions().textureCompressionDXT1)
1690 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001691 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001692 return false;
1693 }
1694 break;
1695 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1696 if (!context->getExtensions().textureCompressionDXT3)
1697 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001698 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001699 return false;
1700 }
1701 break;
1702 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1703 if (!context->getExtensions().textureCompressionDXT5)
1704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001705 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001706 return false;
1707 }
1708 break;
1709 case GL_ETC1_RGB8_OES:
1710 if (!context->getExtensions().compressedETC1RGB8Texture)
1711 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001712 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001713 return false;
1714 }
1715 break;
1716 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001717 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1718 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1719 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1720 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001721 if (!context->getExtensions().lossyETCDecode)
1722 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001723 context->handleError(InvalidEnum()
1724 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001725 return false;
1726 }
1727 break;
1728 case GL_RGBA32F_EXT:
1729 case GL_RGB32F_EXT:
1730 case GL_ALPHA32F_EXT:
1731 case GL_LUMINANCE32F_EXT:
1732 case GL_LUMINANCE_ALPHA32F_EXT:
1733 if (!context->getExtensions().textureFloat)
1734 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001735 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001736 return false;
1737 }
1738 break;
1739 case GL_RGBA16F_EXT:
1740 case GL_RGB16F_EXT:
1741 case GL_ALPHA16F_EXT:
1742 case GL_LUMINANCE16F_EXT:
1743 case GL_LUMINANCE_ALPHA16F_EXT:
1744 if (!context->getExtensions().textureHalfFloat)
1745 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001746 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001747 return false;
1748 }
1749 break;
1750 case GL_R8_EXT:
1751 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001752 if (!context->getExtensions().textureRG)
1753 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001754 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001755 return false;
1756 }
1757 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001758 case GL_R16F_EXT:
1759 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001760 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1761 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001762 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001763 return false;
1764 }
1765 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001766 case GL_R32F_EXT:
1767 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001768 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001770 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001771 return false;
1772 }
1773 break;
1774 case GL_DEPTH_COMPONENT16:
1775 case GL_DEPTH_COMPONENT32_OES:
1776 case GL_DEPTH24_STENCIL8_OES:
1777 if (!context->getExtensions().depthTextures)
1778 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001779 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001780 return false;
1781 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001782 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001784 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001785 return false;
1786 }
1787 // ANGLE_depth_texture only supports 1-level textures
1788 if (levels != 1)
1789 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001790 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001791 return false;
1792 }
1793 break;
1794 default:
1795 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001796 }
1797
Geoff Lang691e58c2014-12-19 17:03:25 -05001798 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001799 if (!texture || texture->id() == 0)
1800 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001801 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001802 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001803 }
1804
Geoff Lang69cce582015-09-17 13:20:36 -04001805 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001806 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001807 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001808 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001809 }
1810
1811 return true;
1812}
1813
He Yunchaoced53ae2016-11-29 15:00:51 +08001814bool ValidateDiscardFramebufferEXT(Context *context,
1815 GLenum target,
1816 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001817 const GLenum *attachments)
1818{
Jamie Madillc29968b2016-01-20 11:17:23 -05001819 if (!context->getExtensions().discardFramebuffer)
1820 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001821 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001822 return false;
1823 }
1824
Austin Kinross08332632015-05-05 13:35:47 -07001825 bool defaultFramebuffer = false;
1826
1827 switch (target)
1828 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001829 case GL_FRAMEBUFFER:
1830 defaultFramebuffer =
1831 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1832 break;
1833 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001834 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001835 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001836 }
1837
He Yunchaoced53ae2016-11-29 15:00:51 +08001838 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1839 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001840}
1841
Austin Kinrossbc781f32015-10-26 09:27:38 -07001842bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1843{
1844 if (!context->getExtensions().vertexArrayObject)
1845 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001846 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001847 return false;
1848 }
1849
1850 return ValidateBindVertexArrayBase(context, array);
1851}
1852
Jamie Madilld7576732017-08-26 18:49:50 -04001853bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001854{
1855 if (!context->getExtensions().vertexArrayObject)
1856 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001857 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001858 return false;
1859 }
1860
Olli Etuaho41997e72016-03-10 13:38:39 +02001861 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001862}
1863
Jamie Madilld7576732017-08-26 18:49:50 -04001864bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001865{
1866 if (!context->getExtensions().vertexArrayObject)
1867 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001868 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001869 return false;
1870 }
1871
Olli Etuaho41997e72016-03-10 13:38:39 +02001872 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001873}
1874
Jamie Madilld7576732017-08-26 18:49:50 -04001875bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001876{
1877 if (!context->getExtensions().vertexArrayObject)
1878 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001879 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001880 return false;
1881 }
1882
1883 return true;
1884}
Geoff Langc5629752015-12-07 16:29:04 -05001885
1886bool ValidateProgramBinaryOES(Context *context,
1887 GLuint program,
1888 GLenum binaryFormat,
1889 const void *binary,
1890 GLint length)
1891{
1892 if (!context->getExtensions().getProgramBinary)
1893 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001894 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001895 return false;
1896 }
1897
1898 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1899}
1900
1901bool ValidateGetProgramBinaryOES(Context *context,
1902 GLuint program,
1903 GLsizei bufSize,
1904 GLsizei *length,
1905 GLenum *binaryFormat,
1906 void *binary)
1907{
1908 if (!context->getExtensions().getProgramBinary)
1909 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001910 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001911 return false;
1912 }
1913
1914 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1915}
Geoff Lange102fee2015-12-10 11:23:30 -05001916
Geoff Lang70d0f492015-12-10 17:45:46 -05001917static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1918{
1919 switch (source)
1920 {
1921 case GL_DEBUG_SOURCE_API:
1922 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1923 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1924 case GL_DEBUG_SOURCE_OTHER:
1925 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1926 return !mustBeThirdPartyOrApplication;
1927
1928 case GL_DEBUG_SOURCE_THIRD_PARTY:
1929 case GL_DEBUG_SOURCE_APPLICATION:
1930 return true;
1931
1932 default:
1933 return false;
1934 }
1935}
1936
1937static bool ValidDebugType(GLenum type)
1938{
1939 switch (type)
1940 {
1941 case GL_DEBUG_TYPE_ERROR:
1942 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1943 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1944 case GL_DEBUG_TYPE_PERFORMANCE:
1945 case GL_DEBUG_TYPE_PORTABILITY:
1946 case GL_DEBUG_TYPE_OTHER:
1947 case GL_DEBUG_TYPE_MARKER:
1948 case GL_DEBUG_TYPE_PUSH_GROUP:
1949 case GL_DEBUG_TYPE_POP_GROUP:
1950 return true;
1951
1952 default:
1953 return false;
1954 }
1955}
1956
1957static bool ValidDebugSeverity(GLenum severity)
1958{
1959 switch (severity)
1960 {
1961 case GL_DEBUG_SEVERITY_HIGH:
1962 case GL_DEBUG_SEVERITY_MEDIUM:
1963 case GL_DEBUG_SEVERITY_LOW:
1964 case GL_DEBUG_SEVERITY_NOTIFICATION:
1965 return true;
1966
1967 default:
1968 return false;
1969 }
1970}
1971
Geoff Lange102fee2015-12-10 11:23:30 -05001972bool ValidateDebugMessageControlKHR(Context *context,
1973 GLenum source,
1974 GLenum type,
1975 GLenum severity,
1976 GLsizei count,
1977 const GLuint *ids,
1978 GLboolean enabled)
1979{
1980 if (!context->getExtensions().debug)
1981 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001982 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001983 return false;
1984 }
1985
Geoff Lang70d0f492015-12-10 17:45:46 -05001986 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1987 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001988 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001989 return false;
1990 }
1991
1992 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1993 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001994 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001995 return false;
1996 }
1997
1998 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1999 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002000 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002001 return false;
2002 }
2003
2004 if (count > 0)
2005 {
2006 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002008 context->handleError(
2009 InvalidOperation()
2010 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002011 return false;
2012 }
2013
2014 if (severity != GL_DONT_CARE)
2015 {
Jamie Madill437fa652016-05-03 15:13:24 -04002016 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002017 InvalidOperation()
2018 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002019 return false;
2020 }
2021 }
2022
Geoff Lange102fee2015-12-10 11:23:30 -05002023 return true;
2024}
2025
2026bool ValidateDebugMessageInsertKHR(Context *context,
2027 GLenum source,
2028 GLenum type,
2029 GLuint id,
2030 GLenum severity,
2031 GLsizei length,
2032 const GLchar *buf)
2033{
2034 if (!context->getExtensions().debug)
2035 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002036 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002037 return false;
2038 }
2039
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002040 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002041 {
2042 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2043 // not generate an error.
2044 return false;
2045 }
2046
2047 if (!ValidDebugSeverity(severity))
2048 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002049 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002050 return false;
2051 }
2052
2053 if (!ValidDebugType(type))
2054 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002055 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002056 return false;
2057 }
2058
2059 if (!ValidDebugSource(source, true))
2060 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002061 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002062 return false;
2063 }
2064
2065 size_t messageLength = (length < 0) ? strlen(buf) : length;
2066 if (messageLength > context->getExtensions().maxDebugMessageLength)
2067 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002068 context->handleError(InvalidValue()
2069 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002070 return false;
2071 }
2072
Geoff Lange102fee2015-12-10 11:23:30 -05002073 return true;
2074}
2075
2076bool ValidateDebugMessageCallbackKHR(Context *context,
2077 GLDEBUGPROCKHR callback,
2078 const void *userParam)
2079{
2080 if (!context->getExtensions().debug)
2081 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002082 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002083 return false;
2084 }
2085
Geoff Lange102fee2015-12-10 11:23:30 -05002086 return true;
2087}
2088
2089bool ValidateGetDebugMessageLogKHR(Context *context,
2090 GLuint count,
2091 GLsizei bufSize,
2092 GLenum *sources,
2093 GLenum *types,
2094 GLuint *ids,
2095 GLenum *severities,
2096 GLsizei *lengths,
2097 GLchar *messageLog)
2098{
2099 if (!context->getExtensions().debug)
2100 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002101 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002102 return false;
2103 }
2104
Geoff Lang70d0f492015-12-10 17:45:46 -05002105 if (bufSize < 0 && messageLog != nullptr)
2106 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002107 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002108 return false;
2109 }
2110
Geoff Lange102fee2015-12-10 11:23:30 -05002111 return true;
2112}
2113
2114bool ValidatePushDebugGroupKHR(Context *context,
2115 GLenum source,
2116 GLuint id,
2117 GLsizei length,
2118 const GLchar *message)
2119{
2120 if (!context->getExtensions().debug)
2121 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002122 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002123 return false;
2124 }
2125
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 if (!ValidDebugSource(source, true))
2127 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002128 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002129 return false;
2130 }
2131
2132 size_t messageLength = (length < 0) ? strlen(message) : length;
2133 if (messageLength > context->getExtensions().maxDebugMessageLength)
2134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002135 context->handleError(InvalidValue()
2136 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002137 return false;
2138 }
2139
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002140 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002141 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002143 context
2144 ->handleError(StackOverflow()
2145 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002146 return false;
2147 }
2148
Geoff Lange102fee2015-12-10 11:23:30 -05002149 return true;
2150}
2151
2152bool ValidatePopDebugGroupKHR(Context *context)
2153{
2154 if (!context->getExtensions().debug)
2155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002156 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002157 return false;
2158 }
2159
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002160 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002161 if (currentStackSize <= 1)
2162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002163 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002164 return false;
2165 }
2166
2167 return true;
2168}
2169
2170static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2171{
2172 switch (identifier)
2173 {
2174 case GL_BUFFER:
2175 if (context->getBuffer(name) == nullptr)
2176 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002177 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002178 return false;
2179 }
2180 return true;
2181
2182 case GL_SHADER:
2183 if (context->getShader(name) == nullptr)
2184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002185 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002186 return false;
2187 }
2188 return true;
2189
2190 case GL_PROGRAM:
2191 if (context->getProgram(name) == nullptr)
2192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002193 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002194 return false;
2195 }
2196 return true;
2197
2198 case GL_VERTEX_ARRAY:
2199 if (context->getVertexArray(name) == nullptr)
2200 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002201 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002202 return false;
2203 }
2204 return true;
2205
2206 case GL_QUERY:
2207 if (context->getQuery(name) == nullptr)
2208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002209 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002210 return false;
2211 }
2212 return true;
2213
2214 case GL_TRANSFORM_FEEDBACK:
2215 if (context->getTransformFeedback(name) == nullptr)
2216 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002217 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002218 return false;
2219 }
2220 return true;
2221
2222 case GL_SAMPLER:
2223 if (context->getSampler(name) == nullptr)
2224 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002225 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002226 return false;
2227 }
2228 return true;
2229
2230 case GL_TEXTURE:
2231 if (context->getTexture(name) == nullptr)
2232 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002233 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002234 return false;
2235 }
2236 return true;
2237
2238 case GL_RENDERBUFFER:
2239 if (context->getRenderbuffer(name) == nullptr)
2240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002241 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002242 return false;
2243 }
2244 return true;
2245
2246 case GL_FRAMEBUFFER:
2247 if (context->getFramebuffer(name) == nullptr)
2248 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002249 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002250 return false;
2251 }
2252 return true;
2253
2254 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002255 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002256 return false;
2257 }
Geoff Lange102fee2015-12-10 11:23:30 -05002258}
2259
Martin Radev9d901792016-07-15 15:58:58 +03002260static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2261{
2262 size_t labelLength = 0;
2263
2264 if (length < 0)
2265 {
2266 if (label != nullptr)
2267 {
2268 labelLength = strlen(label);
2269 }
2270 }
2271 else
2272 {
2273 labelLength = static_cast<size_t>(length);
2274 }
2275
2276 if (labelLength > context->getExtensions().maxLabelLength)
2277 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002278 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002279 return false;
2280 }
2281
2282 return true;
2283}
2284
Geoff Lange102fee2015-12-10 11:23:30 -05002285bool ValidateObjectLabelKHR(Context *context,
2286 GLenum identifier,
2287 GLuint name,
2288 GLsizei length,
2289 const GLchar *label)
2290{
2291 if (!context->getExtensions().debug)
2292 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002293 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002294 return false;
2295 }
2296
Geoff Lang70d0f492015-12-10 17:45:46 -05002297 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2298 {
2299 return false;
2300 }
2301
Martin Radev9d901792016-07-15 15:58:58 +03002302 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002303 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002304 return false;
2305 }
2306
Geoff Lange102fee2015-12-10 11:23:30 -05002307 return true;
2308}
2309
2310bool ValidateGetObjectLabelKHR(Context *context,
2311 GLenum identifier,
2312 GLuint name,
2313 GLsizei bufSize,
2314 GLsizei *length,
2315 GLchar *label)
2316{
2317 if (!context->getExtensions().debug)
2318 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002319 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002320 return false;
2321 }
2322
Geoff Lang70d0f492015-12-10 17:45:46 -05002323 if (bufSize < 0)
2324 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002325 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002326 return false;
2327 }
2328
2329 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2330 {
2331 return false;
2332 }
2333
Martin Radev9d901792016-07-15 15:58:58 +03002334 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002335}
2336
2337static bool ValidateObjectPtrName(Context *context, const void *ptr)
2338{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002339 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002340 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002341 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002342 return false;
2343 }
2344
Geoff Lange102fee2015-12-10 11:23:30 -05002345 return true;
2346}
2347
2348bool ValidateObjectPtrLabelKHR(Context *context,
2349 const void *ptr,
2350 GLsizei length,
2351 const GLchar *label)
2352{
2353 if (!context->getExtensions().debug)
2354 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002355 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002356 return false;
2357 }
2358
Geoff Lang70d0f492015-12-10 17:45:46 -05002359 if (!ValidateObjectPtrName(context, ptr))
2360 {
2361 return false;
2362 }
2363
Martin Radev9d901792016-07-15 15:58:58 +03002364 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002365 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002366 return false;
2367 }
2368
Geoff Lange102fee2015-12-10 11:23:30 -05002369 return true;
2370}
2371
2372bool ValidateGetObjectPtrLabelKHR(Context *context,
2373 const void *ptr,
2374 GLsizei bufSize,
2375 GLsizei *length,
2376 GLchar *label)
2377{
2378 if (!context->getExtensions().debug)
2379 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002380 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002381 return false;
2382 }
2383
Geoff Lang70d0f492015-12-10 17:45:46 -05002384 if (bufSize < 0)
2385 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002386 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002387 return false;
2388 }
2389
2390 if (!ValidateObjectPtrName(context, ptr))
2391 {
2392 return false;
2393 }
2394
Martin Radev9d901792016-07-15 15:58:58 +03002395 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002396}
2397
2398bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2399{
2400 if (!context->getExtensions().debug)
2401 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002402 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002403 return false;
2404 }
2405
Geoff Lang70d0f492015-12-10 17:45:46 -05002406 // TODO: represent this in Context::getQueryParameterInfo.
2407 switch (pname)
2408 {
2409 case GL_DEBUG_CALLBACK_FUNCTION:
2410 case GL_DEBUG_CALLBACK_USER_PARAM:
2411 break;
2412
2413 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002414 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002415 return false;
2416 }
2417
Geoff Lange102fee2015-12-10 11:23:30 -05002418 return true;
2419}
Jamie Madillc29968b2016-01-20 11:17:23 -05002420
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002421bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2422 GLenum pname,
2423 GLsizei bufSize,
2424 GLsizei *length,
2425 void **params)
2426{
2427 UNIMPLEMENTED();
2428 return false;
2429}
2430
Jamie Madillc29968b2016-01-20 11:17:23 -05002431bool ValidateBlitFramebufferANGLE(Context *context,
2432 GLint srcX0,
2433 GLint srcY0,
2434 GLint srcX1,
2435 GLint srcY1,
2436 GLint dstX0,
2437 GLint dstY0,
2438 GLint dstX1,
2439 GLint dstY1,
2440 GLbitfield mask,
2441 GLenum filter)
2442{
2443 if (!context->getExtensions().framebufferBlit)
2444 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002445 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002446 return false;
2447 }
2448
2449 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2450 {
2451 // TODO(jmadill): Determine if this should be available on other implementations.
Olli Etuahof0e3c192018-08-15 13:37:21 +03002452 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002453 return false;
2454 }
2455
2456 if (filter == GL_LINEAR)
2457 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002458 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002459 return false;
2460 }
2461
Jamie Madill51f40ec2016-06-15 14:06:00 -04002462 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2463 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002464
2465 if (mask & GL_COLOR_BUFFER_BIT)
2466 {
2467 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2468 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2469
2470 if (readColorAttachment && drawColorAttachment)
2471 {
2472 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002473 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002474 readColorAttachment->type() != GL_RENDERBUFFER &&
2475 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2476 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002477 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2478 BlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002479 return false;
2480 }
2481
Geoff Langa15472a2015-08-11 11:48:03 -04002482 for (size_t drawbufferIdx = 0;
2483 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002484 {
Geoff Langa15472a2015-08-11 11:48:03 -04002485 const FramebufferAttachment *attachment =
2486 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2487 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002488 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002489 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002490 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 attachment->type() != GL_RENDERBUFFER &&
2492 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2493 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002494 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2495 BlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002496 return false;
2497 }
2498
2499 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002500 if (!Format::EquivalentForBlit(attachment->getFormat(),
2501 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002502 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002503 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2504 BlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002505 return false;
2506 }
2507 }
2508 }
2509
Jamie Madill427064d2018-04-13 16:20:34 -04002510 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002511 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002512 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2513 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2514 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002515 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2516 BlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002517 return false;
2518 }
2519 }
2520 }
2521
2522 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2523 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2524 for (size_t i = 0; i < 2; i++)
2525 {
2526 if (mask & masks[i])
2527 {
2528 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002529 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002530 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002531 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002532
2533 if (readBuffer && drawBuffer)
2534 {
2535 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2536 dstX0, dstY0, dstX1, dstY1))
2537 {
2538 // only whole-buffer copies are permitted
Olli Etuahof0e3c192018-08-15 13:37:21 +03002539 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2540 BlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002541 return false;
2542 }
2543
2544 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2545 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002546 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2547 BlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002548 return false;
2549 }
2550 }
2551 }
2552 }
2553
2554 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2555 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002556}
Jamie Madillc29968b2016-01-20 11:17:23 -05002557
Jamie Madill5b772312018-03-08 20:28:32 -05002558bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002559{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002560 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002561 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002562
Jamie Madill427064d2018-04-13 16:20:34 -04002563 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002564 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002565 return false;
2566 }
2567
2568 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2569 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002570 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002571 return false;
2572 }
2573
Olli Etuaho94c91a92018-07-19 15:10:24 +03002574 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002575 {
2576 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2577 GL_SIGNED_NORMALIZED};
2578
Corentin Wallez59c41592017-07-11 13:19:54 -04002579 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002580 drawBufferIdx++)
2581 {
2582 if (!ValidateWebGLFramebufferAttachmentClearType(
2583 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2584 {
2585 return false;
2586 }
2587 }
2588 }
2589
Olli Etuaho94c91a92018-07-19 15:10:24 +03002590 if (extensions.multiview && extensions.disjointTimerQuery)
2591 {
2592 const State &state = context->getGLState();
2593 Framebuffer *framebuffer = state.getDrawFramebuffer();
2594 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2595 {
2596 context->handleError(InvalidOperation() << "There is an active query for target "
2597 "GL_TIME_ELAPSED_EXT when the number of "
2598 "views in the active draw framebuffer is "
2599 "greater than 1.");
2600 return false;
2601 }
2602 }
2603
Jamie Madillc29968b2016-01-20 11:17:23 -05002604 return true;
2605}
2606
Jamie Madill5b772312018-03-08 20:28:32 -05002607bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002608{
2609 if (!context->getExtensions().drawBuffers)
2610 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002611 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002612 return false;
2613 }
2614
2615 return ValidateDrawBuffersBase(context, n, bufs);
2616}
2617
Jamie Madill73a84962016-02-12 09:27:23 -05002618bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002619 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002620 GLint level,
2621 GLint internalformat,
2622 GLsizei width,
2623 GLsizei height,
2624 GLint border,
2625 GLenum format,
2626 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002627 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002628{
Martin Radev1be913c2016-07-11 17:59:16 +03002629 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002630 {
2631 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002632 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002633 }
2634
Martin Radev1be913c2016-07-11 17:59:16 +03002635 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002636 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002637 0, 0, width, height, 1, border, format, type, -1,
2638 pixels);
2639}
2640
Brandon Jones416aaf92018-04-10 08:10:16 -07002641bool ValidateTexImage2DRobustANGLE(Context *context,
2642 TextureTarget target,
2643 GLint level,
2644 GLint internalformat,
2645 GLsizei width,
2646 GLsizei height,
2647 GLint border,
2648 GLenum format,
2649 GLenum type,
2650 GLsizei bufSize,
2651 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002652{
2653 if (!ValidateRobustEntryPoint(context, bufSize))
2654 {
2655 return false;
2656 }
2657
2658 if (context->getClientMajorVersion() < 3)
2659 {
2660 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2661 0, 0, width, height, border, format, type, bufSize,
2662 pixels);
2663 }
2664
2665 ASSERT(context->getClientMajorVersion() >= 3);
2666 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2667 0, 0, width, height, 1, border, format, type, bufSize,
2668 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002669}
2670
2671bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002672 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002673 GLint level,
2674 GLint xoffset,
2675 GLint yoffset,
2676 GLsizei width,
2677 GLsizei height,
2678 GLenum format,
2679 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002680 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002681{
2682
Martin Radev1be913c2016-07-11 17:59:16 +03002683 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002684 {
2685 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002686 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002687 }
2688
Martin Radev1be913c2016-07-11 17:59:16 +03002689 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002690 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002691 yoffset, 0, width, height, 1, 0, format, type, -1,
2692 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002693}
2694
Geoff Langc52f6f12016-10-14 10:18:00 -04002695bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002696 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002697 GLint level,
2698 GLint xoffset,
2699 GLint yoffset,
2700 GLsizei width,
2701 GLsizei height,
2702 GLenum format,
2703 GLenum type,
2704 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002705 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002706{
2707 if (!ValidateRobustEntryPoint(context, bufSize))
2708 {
2709 return false;
2710 }
2711
2712 if (context->getClientMajorVersion() < 3)
2713 {
2714 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2715 yoffset, width, height, 0, format, type, bufSize,
2716 pixels);
2717 }
2718
2719 ASSERT(context->getClientMajorVersion() >= 3);
2720 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2721 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2722 pixels);
2723}
2724
Jamie Madill73a84962016-02-12 09:27:23 -05002725bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002726 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002727 GLint level,
2728 GLenum internalformat,
2729 GLsizei width,
2730 GLsizei height,
2731 GLint border,
2732 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002733 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002734{
Martin Radev1be913c2016-07-11 17:59:16 +03002735 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002736 {
2737 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002738 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002739 {
2740 return false;
2741 }
2742 }
2743 else
2744 {
Martin Radev1be913c2016-07-11 17:59:16 +03002745 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002746 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002747 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002748 data))
2749 {
2750 return false;
2751 }
2752 }
2753
Geoff Langca271392017-04-05 12:30:00 -04002754 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002755
2756 GLuint blockSize = 0;
2757 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002758 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002759 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002760 return false;
2761 }
2762
Jamie Madillca2ff382018-07-11 09:01:17 -04002763 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002764 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002765 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002766 return false;
2767 }
2768
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002769 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002770 {
2771 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2772 return false;
2773 }
2774
Jamie Madill73a84962016-02-12 09:27:23 -05002775 return true;
2776}
2777
Corentin Wallezb2931602017-04-11 15:58:57 -04002778bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002779 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002780 GLint level,
2781 GLenum internalformat,
2782 GLsizei width,
2783 GLsizei height,
2784 GLint border,
2785 GLsizei imageSize,
2786 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002787 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002788{
2789 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2790 {
2791 return false;
2792 }
2793
2794 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2795 border, imageSize, data);
2796}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002797
Corentin Wallezb2931602017-04-11 15:58:57 -04002798bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002799 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002800 GLint level,
2801 GLint xoffset,
2802 GLint yoffset,
2803 GLsizei width,
2804 GLsizei height,
2805 GLenum format,
2806 GLsizei imageSize,
2807 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002808 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002809{
2810 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2811 {
2812 return false;
2813 }
2814
2815 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2816 format, imageSize, data);
2817}
2818
Jamie Madill73a84962016-02-12 09:27:23 -05002819bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002820 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002821 GLint level,
2822 GLint xoffset,
2823 GLint yoffset,
2824 GLsizei width,
2825 GLsizei height,
2826 GLenum format,
2827 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002828 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002829{
Martin Radev1be913c2016-07-11 17:59:16 +03002830 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002831 {
2832 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002833 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002834 {
2835 return false;
2836 }
2837 }
2838 else
2839 {
Martin Radev1be913c2016-07-11 17:59:16 +03002840 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002841 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002842 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002843 data))
2844 {
2845 return false;
2846 }
2847 }
2848
Geoff Langca271392017-04-05 12:30:00 -04002849 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002850 GLuint blockSize = 0;
2851 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002852 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002853 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002854 return false;
2855 }
2856
Jamie Madillca2ff382018-07-11 09:01:17 -04002857 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002858 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002859 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002860 return false;
2861 }
2862
2863 return true;
2864}
2865
Corentin Wallez336129f2017-10-17 15:55:40 -04002866bool ValidateGetBufferPointervOES(Context *context,
2867 BufferBinding target,
2868 GLenum pname,
2869 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002870{
Geoff Lang496c02d2016-10-20 11:38:11 -07002871 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002872}
2873
Corentin Wallez336129f2017-10-17 15:55:40 -04002874bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002875{
2876 if (!context->getExtensions().mapBuffer)
2877 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002878 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002879 return false;
2880 }
2881
Corentin Walleze4477002017-12-01 14:39:58 -05002882 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002884 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002885 return false;
2886 }
2887
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002888 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002889
2890 if (buffer == nullptr)
2891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002892 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002893 return false;
2894 }
2895
2896 if (access != GL_WRITE_ONLY_OES)
2897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002898 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002899 return false;
2900 }
2901
2902 if (buffer->isMapped())
2903 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002904 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002905 return false;
2906 }
2907
Geoff Lang79f71042017-08-14 16:43:43 -04002908 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002909}
2910
Corentin Wallez336129f2017-10-17 15:55:40 -04002911bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002912{
2913 if (!context->getExtensions().mapBuffer)
2914 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002915 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002916 return false;
2917 }
2918
2919 return ValidateUnmapBufferBase(context, target);
2920}
2921
2922bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002923 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002924 GLintptr offset,
2925 GLsizeiptr length,
2926 GLbitfield access)
2927{
2928 if (!context->getExtensions().mapBufferRange)
2929 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002930 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002931 return false;
2932 }
2933
2934 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2935}
2936
Corentin Wallez336129f2017-10-17 15:55:40 -04002937bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002938{
2939 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2940 ASSERT(buffer != nullptr);
2941
2942 // Check if this buffer is currently being used as a transform feedback output buffer
2943 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2944 if (transformFeedback != nullptr && transformFeedback->isActive())
2945 {
2946 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2947 {
2948 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2949 if (transformFeedbackBuffer.get() == buffer)
2950 {
2951 context->handleError(InvalidOperation()
2952 << "Buffer is currently bound for transform feedback.");
2953 return false;
2954 }
2955 }
2956 }
2957
James Darpiniane8a93c62018-01-04 18:02:24 -08002958 if (context->getExtensions().webglCompatibility &&
2959 buffer->isBoundForTransformFeedbackAndOtherUse())
2960 {
2961 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2962 return false;
2963 }
2964
Geoff Lang79f71042017-08-14 16:43:43 -04002965 return true;
2966}
2967
Olli Etuaho4f667482016-03-30 15:56:35 +03002968bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002969 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002970 GLintptr offset,
2971 GLsizeiptr length)
2972{
2973 if (!context->getExtensions().mapBufferRange)
2974 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002975 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002976 return false;
2977 }
2978
2979 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2980}
2981
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002982bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002983{
2984 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002985 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002986 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002987 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002988 return false;
2989 }
2990
Geoff Langf41a7152016-09-19 15:11:17 -04002991 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2992 !context->isTextureGenerated(texture))
2993 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002994 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002995 return false;
2996 }
2997
Ian Ewell54f87462016-03-10 13:47:21 -05002998 switch (target)
2999 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003000 case TextureType::_2D:
3001 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05003002 break;
3003
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003004 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003005 if (!context->getExtensions().textureRectangle)
3006 {
3007 context->handleError(InvalidEnum()
3008 << "Context does not support GL_ANGLE_texture_rectangle");
3009 return false;
3010 }
3011 break;
3012
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003013 case TextureType::_3D:
3014 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03003015 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003016 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003017 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003018 return false;
3019 }
3020 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003021
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003022 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003023 if (context->getClientVersion() < Version(3, 1))
3024 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003025 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003026 return false;
3027 }
Geoff Lang3b573612016-10-31 14:08:10 -04003028 break;
3029
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003030 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003031 if (!context->getExtensions().eglImageExternal &&
3032 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003033 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003034 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003035 return false;
3036 }
3037 break;
3038 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003039 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003040 return false;
3041 }
3042
3043 return true;
3044}
3045
Geoff Langd8605522016-04-13 10:19:12 -04003046bool ValidateBindUniformLocationCHROMIUM(Context *context,
3047 GLuint program,
3048 GLint location,
3049 const GLchar *name)
3050{
3051 if (!context->getExtensions().bindUniformLocation)
3052 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003053 context->handleError(InvalidOperation()
3054 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003055 return false;
3056 }
3057
3058 Program *programObject = GetValidProgram(context, program);
3059 if (!programObject)
3060 {
3061 return false;
3062 }
3063
3064 if (location < 0)
3065 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003066 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003067 return false;
3068 }
3069
3070 const Caps &caps = context->getCaps();
3071 if (static_cast<size_t>(location) >=
3072 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3073 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003074 context->handleError(InvalidValue() << "Location must be less than "
3075 "(MAX_VERTEX_UNIFORM_VECTORS + "
3076 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003077 return false;
3078 }
3079
Geoff Langfc32e8b2017-05-31 14:16:59 -04003080 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3081 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003082 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003083 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003084 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003085 return false;
3086 }
3087
Geoff Langd8605522016-04-13 10:19:12 -04003088 if (strncmp(name, "gl_", 3) == 0)
3089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003090 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003091 return false;
3092 }
3093
3094 return true;
3095}
3096
Jamie Madille2e406c2016-06-02 13:04:10 -04003097bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003098{
3099 if (!context->getExtensions().framebufferMixedSamples)
3100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003101 context->handleError(InvalidOperation()
3102 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003103 return false;
3104 }
3105 switch (components)
3106 {
3107 case GL_RGB:
3108 case GL_RGBA:
3109 case GL_ALPHA:
3110 case GL_NONE:
3111 break;
3112 default:
3113 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003114 InvalidEnum()
3115 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003116 return false;
3117 }
3118
3119 return true;
3120}
3121
Sami Väisänene45e53b2016-05-25 10:36:04 +03003122// CHROMIUM_path_rendering
3123
Jamie Madill007530e2017-12-28 14:27:04 -05003124bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003125{
Jamie Madill007530e2017-12-28 14:27:04 -05003126 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003127 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003128 return false;
3129 }
Jamie Madill007530e2017-12-28 14:27:04 -05003130
Sami Väisänene45e53b2016-05-25 10:36:04 +03003131 if (matrix == nullptr)
3132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003133 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003134 return false;
3135 }
Jamie Madill007530e2017-12-28 14:27:04 -05003136
Sami Väisänene45e53b2016-05-25 10:36:04 +03003137 return true;
3138}
3139
Jamie Madill007530e2017-12-28 14:27:04 -05003140bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003141{
Jamie Madill007530e2017-12-28 14:27:04 -05003142 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003143}
3144
Jamie Madill007530e2017-12-28 14:27:04 -05003145bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003146{
3147 if (!context->getExtensions().pathRendering)
3148 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003149 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003150 return false;
3151 }
3152
3153 // range = 0 is undefined in NV_path_rendering.
3154 // we add stricter semantic check here and require a non zero positive range.
3155 if (range <= 0)
3156 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003157 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003158 return false;
3159 }
3160
3161 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3162 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003163 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003164 return false;
3165 }
3166
3167 return true;
3168}
3169
Jamie Madill007530e2017-12-28 14:27:04 -05003170bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003171{
3172 if (!context->getExtensions().pathRendering)
3173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003174 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003175 return false;
3176 }
3177
3178 // range = 0 is undefined in NV_path_rendering.
3179 // we add stricter semantic check here and require a non zero positive range.
3180 if (range <= 0)
3181 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003182 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003183 return false;
3184 }
3185
3186 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3187 checkedRange += range;
3188
3189 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3190 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003191 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003192 return false;
3193 }
3194 return true;
3195}
3196
Jamie Madill007530e2017-12-28 14:27:04 -05003197bool ValidatePathCommandsCHROMIUM(Context *context,
3198 GLuint path,
3199 GLsizei numCommands,
3200 const GLubyte *commands,
3201 GLsizei numCoords,
3202 GLenum coordType,
3203 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003204{
3205 if (!context->getExtensions().pathRendering)
3206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003207 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003208 return false;
3209 }
Brandon Jones59770802018-04-02 13:18:42 -07003210 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003211 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003212 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003213 return false;
3214 }
3215
3216 if (numCommands < 0)
3217 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003218 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003219 return false;
3220 }
3221 else if (numCommands > 0)
3222 {
3223 if (!commands)
3224 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003225 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003226 return false;
3227 }
3228 }
3229
3230 if (numCoords < 0)
3231 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003232 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003233 return false;
3234 }
3235 else if (numCoords > 0)
3236 {
3237 if (!coords)
3238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003239 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003240 return false;
3241 }
3242 }
3243
3244 std::uint32_t coordTypeSize = 0;
3245 switch (coordType)
3246 {
3247 case GL_BYTE:
3248 coordTypeSize = sizeof(GLbyte);
3249 break;
3250
3251 case GL_UNSIGNED_BYTE:
3252 coordTypeSize = sizeof(GLubyte);
3253 break;
3254
3255 case GL_SHORT:
3256 coordTypeSize = sizeof(GLshort);
3257 break;
3258
3259 case GL_UNSIGNED_SHORT:
3260 coordTypeSize = sizeof(GLushort);
3261 break;
3262
3263 case GL_FLOAT:
3264 coordTypeSize = sizeof(GLfloat);
3265 break;
3266
3267 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003268 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003269 return false;
3270 }
3271
3272 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3273 checkedSize += (coordTypeSize * numCoords);
3274 if (!checkedSize.IsValid())
3275 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003276 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003277 return false;
3278 }
3279
3280 // early return skips command data validation when it doesn't exist.
3281 if (!commands)
3282 return true;
3283
3284 GLsizei expectedNumCoords = 0;
3285 for (GLsizei i = 0; i < numCommands; ++i)
3286 {
3287 switch (commands[i])
3288 {
3289 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3290 break;
3291 case GL_MOVE_TO_CHROMIUM:
3292 case GL_LINE_TO_CHROMIUM:
3293 expectedNumCoords += 2;
3294 break;
3295 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3296 expectedNumCoords += 4;
3297 break;
3298 case GL_CUBIC_CURVE_TO_CHROMIUM:
3299 expectedNumCoords += 6;
3300 break;
3301 case GL_CONIC_CURVE_TO_CHROMIUM:
3302 expectedNumCoords += 5;
3303 break;
3304 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003305 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003306 return false;
3307 }
3308 }
3309 if (expectedNumCoords != numCoords)
3310 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003311 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003312 return false;
3313 }
3314
3315 return true;
3316}
3317
Jamie Madill007530e2017-12-28 14:27:04 -05003318bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003319{
3320 if (!context->getExtensions().pathRendering)
3321 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003322 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003323 return false;
3324 }
Brandon Jones59770802018-04-02 13:18:42 -07003325 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003326 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003327 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003328 return false;
3329 }
3330
3331 switch (pname)
3332 {
3333 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3334 if (value < 0.0f)
3335 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003336 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003337 return false;
3338 }
3339 break;
3340 case GL_PATH_END_CAPS_CHROMIUM:
3341 switch (static_cast<GLenum>(value))
3342 {
3343 case GL_FLAT_CHROMIUM:
3344 case GL_SQUARE_CHROMIUM:
3345 case GL_ROUND_CHROMIUM:
3346 break;
3347 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003348 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003349 return false;
3350 }
3351 break;
3352 case GL_PATH_JOIN_STYLE_CHROMIUM:
3353 switch (static_cast<GLenum>(value))
3354 {
3355 case GL_MITER_REVERT_CHROMIUM:
3356 case GL_BEVEL_CHROMIUM:
3357 case GL_ROUND_CHROMIUM:
3358 break;
3359 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003360 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003361 return false;
3362 }
Nico Weber41b072b2018-02-09 10:01:32 -05003363 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003364 case GL_PATH_MITER_LIMIT_CHROMIUM:
3365 if (value < 0.0f)
3366 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003367 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003368 return false;
3369 }
3370 break;
3371
3372 case GL_PATH_STROKE_BOUND_CHROMIUM:
3373 // no errors, only clamping.
3374 break;
3375
3376 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003377 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003378 return false;
3379 }
3380 return true;
3381}
3382
Jamie Madill007530e2017-12-28 14:27:04 -05003383bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3384{
3385 // TODO(jmadill): Use proper clamping cast.
3386 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3387}
3388
3389bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003390{
3391 if (!context->getExtensions().pathRendering)
3392 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003393 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003394 return false;
3395 }
3396
Brandon Jones59770802018-04-02 13:18:42 -07003397 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003398 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003400 return false;
3401 }
3402 if (!value)
3403 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003404 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003405 return false;
3406 }
3407
3408 switch (pname)
3409 {
3410 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3411 case GL_PATH_END_CAPS_CHROMIUM:
3412 case GL_PATH_JOIN_STYLE_CHROMIUM:
3413 case GL_PATH_MITER_LIMIT_CHROMIUM:
3414 case GL_PATH_STROKE_BOUND_CHROMIUM:
3415 break;
3416
3417 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003418 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003419 return false;
3420 }
3421
3422 return true;
3423}
3424
Jamie Madill007530e2017-12-28 14:27:04 -05003425bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3426{
3427 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3428 reinterpret_cast<GLfloat *>(value));
3429}
3430
3431bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003432{
3433 if (!context->getExtensions().pathRendering)
3434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003435 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003436 return false;
3437 }
3438
3439 switch (func)
3440 {
3441 case GL_NEVER:
3442 case GL_ALWAYS:
3443 case GL_LESS:
3444 case GL_LEQUAL:
3445 case GL_EQUAL:
3446 case GL_GEQUAL:
3447 case GL_GREATER:
3448 case GL_NOTEQUAL:
3449 break;
3450 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003451 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003452 return false;
3453 }
3454
3455 return true;
3456}
3457
3458// Note that the spec specifies that for the path drawing commands
3459// if the path object is not an existing path object the command
3460// does nothing and no error is generated.
3461// However if the path object exists but has not been specified any
3462// commands then an error is generated.
3463
Jamie Madill007530e2017-12-28 14:27:04 -05003464bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003465{
3466 if (!context->getExtensions().pathRendering)
3467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003468 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003469 return false;
3470 }
Brandon Jones59770802018-04-02 13:18:42 -07003471 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003472 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003473 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474 return false;
3475 }
3476
3477 switch (fillMode)
3478 {
3479 case GL_COUNT_UP_CHROMIUM:
3480 case GL_COUNT_DOWN_CHROMIUM:
3481 break;
3482 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003483 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003484 return false;
3485 }
3486
3487 if (!isPow2(mask + 1))
3488 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003489 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003490 return false;
3491 }
3492
3493 return true;
3494}
3495
Jamie Madill007530e2017-12-28 14:27:04 -05003496bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003497{
3498 if (!context->getExtensions().pathRendering)
3499 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003500 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003501 return false;
3502 }
Brandon Jones59770802018-04-02 13:18:42 -07003503 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003504 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003505 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003506 return false;
3507 }
3508
3509 return true;
3510}
3511
Brandon Jonesd1049182018-03-28 10:02:20 -07003512bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3513{
3514 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3515}
3516
3517bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3518{
3519 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3520}
3521
Jamie Madill007530e2017-12-28 14:27:04 -05003522bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003523{
3524 if (!context->getExtensions().pathRendering)
3525 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003526 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003527 return false;
3528 }
Brandon Jones59770802018-04-02 13:18:42 -07003529 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003530 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003532 return false;
3533 }
3534
3535 switch (coverMode)
3536 {
3537 case GL_CONVEX_HULL_CHROMIUM:
3538 case GL_BOUNDING_BOX_CHROMIUM:
3539 break;
3540 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003541 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542 return false;
3543 }
3544 return true;
3545}
3546
Jamie Madill007530e2017-12-28 14:27:04 -05003547bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3548 GLuint path,
3549 GLenum fillMode,
3550 GLuint mask,
3551 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003552{
Jamie Madill007530e2017-12-28 14:27:04 -05003553 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3554 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003555}
3556
Jamie Madill007530e2017-12-28 14:27:04 -05003557bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3558 GLuint path,
3559 GLint reference,
3560 GLuint mask,
3561 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003562{
Jamie Madill007530e2017-12-28 14:27:04 -05003563 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3564 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003565}
3566
Brandon Jonesd1049182018-03-28 10:02:20 -07003567bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003568{
3569 if (!context->getExtensions().pathRendering)
3570 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003571 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003572 return false;
3573 }
3574 return true;
3575}
3576
Jamie Madill007530e2017-12-28 14:27:04 -05003577bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3578 GLsizei numPaths,
3579 GLenum pathNameType,
3580 const void *paths,
3581 GLuint pathBase,
3582 GLenum coverMode,
3583 GLenum transformType,
3584 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003585{
3586 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3587 transformType, transformValues))
3588 return false;
3589
3590 switch (coverMode)
3591 {
3592 case GL_CONVEX_HULL_CHROMIUM:
3593 case GL_BOUNDING_BOX_CHROMIUM:
3594 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3595 break;
3596 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003597 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003598 return false;
3599 }
3600
3601 return true;
3602}
3603
Jamie Madill007530e2017-12-28 14:27:04 -05003604bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3605 GLsizei numPaths,
3606 GLenum pathNameType,
3607 const void *paths,
3608 GLuint pathBase,
3609 GLenum coverMode,
3610 GLenum transformType,
3611 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003612{
3613 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3614 transformType, transformValues))
3615 return false;
3616
3617 switch (coverMode)
3618 {
3619 case GL_CONVEX_HULL_CHROMIUM:
3620 case GL_BOUNDING_BOX_CHROMIUM:
3621 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3622 break;
3623 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003624 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003625 return false;
3626 }
3627
3628 return true;
3629}
3630
Jamie Madill007530e2017-12-28 14:27:04 -05003631bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3632 GLsizei numPaths,
3633 GLenum pathNameType,
3634 const void *paths,
3635 GLuint pathBase,
3636 GLenum fillMode,
3637 GLuint mask,
3638 GLenum transformType,
3639 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003640{
3641
3642 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3643 transformType, transformValues))
3644 return false;
3645
3646 switch (fillMode)
3647 {
3648 case GL_COUNT_UP_CHROMIUM:
3649 case GL_COUNT_DOWN_CHROMIUM:
3650 break;
3651 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003652 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003653 return false;
3654 }
3655 if (!isPow2(mask + 1))
3656 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003657 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003658 return false;
3659 }
3660 return true;
3661}
3662
Jamie Madill007530e2017-12-28 14:27:04 -05003663bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3664 GLsizei numPaths,
3665 GLenum pathNameType,
3666 const void *paths,
3667 GLuint pathBase,
3668 GLint reference,
3669 GLuint mask,
3670 GLenum transformType,
3671 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003672{
3673 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3674 transformType, transformValues))
3675 return false;
3676
3677 // no more validation here.
3678
3679 return true;
3680}
3681
Jamie Madill007530e2017-12-28 14:27:04 -05003682bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3683 GLsizei numPaths,
3684 GLenum pathNameType,
3685 const void *paths,
3686 GLuint pathBase,
3687 GLenum fillMode,
3688 GLuint mask,
3689 GLenum coverMode,
3690 GLenum transformType,
3691 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003692{
3693 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3694 transformType, transformValues))
3695 return false;
3696
3697 switch (coverMode)
3698 {
3699 case GL_CONVEX_HULL_CHROMIUM:
3700 case GL_BOUNDING_BOX_CHROMIUM:
3701 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3702 break;
3703 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003704 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003705 return false;
3706 }
3707
3708 switch (fillMode)
3709 {
3710 case GL_COUNT_UP_CHROMIUM:
3711 case GL_COUNT_DOWN_CHROMIUM:
3712 break;
3713 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003714 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003715 return false;
3716 }
3717 if (!isPow2(mask + 1))
3718 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003719 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003720 return false;
3721 }
3722
3723 return true;
3724}
3725
Jamie Madill007530e2017-12-28 14:27:04 -05003726bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3727 GLsizei numPaths,
3728 GLenum pathNameType,
3729 const void *paths,
3730 GLuint pathBase,
3731 GLint reference,
3732 GLuint mask,
3733 GLenum coverMode,
3734 GLenum transformType,
3735 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003736{
3737 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3738 transformType, transformValues))
3739 return false;
3740
3741 switch (coverMode)
3742 {
3743 case GL_CONVEX_HULL_CHROMIUM:
3744 case GL_BOUNDING_BOX_CHROMIUM:
3745 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3746 break;
3747 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003748 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003749 return false;
3750 }
3751
3752 return true;
3753}
3754
Jamie Madill007530e2017-12-28 14:27:04 -05003755bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3756 GLuint program,
3757 GLint location,
3758 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003759{
3760 if (!context->getExtensions().pathRendering)
3761 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003762 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003763 return false;
3764 }
3765
3766 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3767 if (location >= MaxLocation)
3768 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003769 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003770 return false;
3771 }
3772
3773 const auto *programObject = context->getProgram(program);
3774 if (!programObject)
3775 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003776 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003777 return false;
3778 }
3779
3780 if (!name)
3781 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003782 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003783 return false;
3784 }
3785
3786 if (angle::BeginsWith(name, "gl_"))
3787 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003788 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003789 return false;
3790 }
3791
3792 return true;
3793}
3794
Jamie Madill007530e2017-12-28 14:27:04 -05003795bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3796 GLuint program,
3797 GLint location,
3798 GLenum genMode,
3799 GLint components,
3800 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003801{
3802 if (!context->getExtensions().pathRendering)
3803 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003804 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003805 return false;
3806 }
3807
3808 const auto *programObject = context->getProgram(program);
3809 if (!programObject || programObject->isFlaggedForDeletion())
3810 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003811 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003812 return false;
3813 }
3814
3815 if (!programObject->isLinked())
3816 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003817 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003818 return false;
3819 }
3820
3821 switch (genMode)
3822 {
3823 case GL_NONE:
3824 if (components != 0)
3825 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003826 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003827 return false;
3828 }
3829 break;
3830
3831 case GL_OBJECT_LINEAR_CHROMIUM:
3832 case GL_EYE_LINEAR_CHROMIUM:
3833 case GL_CONSTANT_CHROMIUM:
3834 if (components < 1 || components > 4)
3835 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003836 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003837 return false;
3838 }
3839 if (!coeffs)
3840 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003841 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003842 return false;
3843 }
3844 break;
3845
3846 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003847 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003848 return false;
3849 }
3850
3851 // If the location is -1 then the command is silently ignored
3852 // and no further validation is needed.
3853 if (location == -1)
3854 return true;
3855
jchen103fd614d2018-08-13 12:21:58 +08003856 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003857
3858 if (!binding.valid)
3859 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003860 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003861 return false;
3862 }
3863
3864 if (binding.type != GL_NONE)
3865 {
3866 GLint expectedComponents = 0;
3867 switch (binding.type)
3868 {
3869 case GL_FLOAT:
3870 expectedComponents = 1;
3871 break;
3872 case GL_FLOAT_VEC2:
3873 expectedComponents = 2;
3874 break;
3875 case GL_FLOAT_VEC3:
3876 expectedComponents = 3;
3877 break;
3878 case GL_FLOAT_VEC4:
3879 expectedComponents = 4;
3880 break;
3881 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003882 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003883 InvalidOperation()
3884 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003885 return false;
3886 }
3887 if (expectedComponents != components && genMode != GL_NONE)
3888 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003889 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003890 return false;
3891 }
3892 }
3893 return true;
3894}
3895
Geoff Lang97073d12016-04-20 10:42:34 -07003896bool ValidateCopyTextureCHROMIUM(Context *context,
3897 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003898 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003899 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003900 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003901 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003902 GLint internalFormat,
3903 GLenum destType,
3904 GLboolean unpackFlipY,
3905 GLboolean unpackPremultiplyAlpha,
3906 GLboolean unpackUnmultiplyAlpha)
3907{
3908 if (!context->getExtensions().copyTexture)
3909 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003910 context->handleError(InvalidOperation()
3911 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003912 return false;
3913 }
3914
Geoff Lang4f0e0032017-05-01 16:04:35 -04003915 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003916 if (source == nullptr)
3917 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003918 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003919 return false;
3920 }
3921
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003922 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003923 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003924 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003925 return false;
3926 }
3927
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003928 TextureType sourceType = source->getType();
3929 ASSERT(sourceType != TextureType::CubeMap);
3930 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003931
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003932 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003933 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003934 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003935 return false;
3936 }
3937
Geoff Lang4f0e0032017-05-01 16:04:35 -04003938 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3939 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3940 if (sourceWidth == 0 || sourceHeight == 0)
3941 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003942 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003943 return false;
3944 }
3945
3946 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3947 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003948 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003949 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003950 return false;
3951 }
3952
Geoff Lang63458a32017-10-30 15:16:53 -04003953 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3954 {
3955 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3956 return false;
3957 }
3958
Geoff Lang4f0e0032017-05-01 16:04:35 -04003959 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003960 if (dest == nullptr)
3961 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003962 context->handleError(InvalidValue()
3963 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003964 return false;
3965 }
3966
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003967 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003968 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003969 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003970 return false;
3971 }
3972
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003973 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003974 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003975 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003976 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003977 return false;
3978 }
3979
Geoff Lang97073d12016-04-20 10:42:34 -07003980 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3981 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003982 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003983 return false;
3984 }
3985
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003986 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003987 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003988 context->handleError(
3989 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003990 return false;
3991 }
3992
Geoff Lang97073d12016-04-20 10:42:34 -07003993 if (dest->getImmutableFormat())
3994 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003995 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003996 return false;
3997 }
3998
3999 return true;
4000}
4001
4002bool ValidateCopySubTextureCHROMIUM(Context *context,
4003 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004004 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004005 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004006 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004007 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004008 GLint xoffset,
4009 GLint yoffset,
4010 GLint x,
4011 GLint y,
4012 GLsizei width,
4013 GLsizei height,
4014 GLboolean unpackFlipY,
4015 GLboolean unpackPremultiplyAlpha,
4016 GLboolean unpackUnmultiplyAlpha)
4017{
4018 if (!context->getExtensions().copyTexture)
4019 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004020 context->handleError(InvalidOperation()
4021 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004022 return false;
4023 }
4024
Geoff Lang4f0e0032017-05-01 16:04:35 -04004025 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004026 if (source == nullptr)
4027 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004028 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004029 return false;
4030 }
4031
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004032 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004033 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004034 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004035 return false;
4036 }
4037
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004038 TextureType sourceType = source->getType();
4039 ASSERT(sourceType != TextureType::CubeMap);
4040 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004041
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004042 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004043 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004044 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004045 return false;
4046 }
4047
4048 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4049 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004050 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004051 context->handleError(InvalidValue()
4052 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004053 return false;
4054 }
4055
4056 if (x < 0 || y < 0)
4057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004058 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004059 return false;
4060 }
4061
4062 if (width < 0 || height < 0)
4063 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004064 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004065 return false;
4066 }
4067
Geoff Lang4f0e0032017-05-01 16:04:35 -04004068 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4069 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004070 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004071 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004072 return false;
4073 }
4074
Geoff Lang4f0e0032017-05-01 16:04:35 -04004075 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4076 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004077 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004078 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004079 return false;
4080 }
4081
Geoff Lang63458a32017-10-30 15:16:53 -04004082 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4083 {
4084 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4085 return false;
4086 }
4087
Geoff Lang4f0e0032017-05-01 16:04:35 -04004088 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004089 if (dest == nullptr)
4090 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004091 context->handleError(InvalidValue()
4092 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004093 return false;
4094 }
4095
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004096 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004097 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004098 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004099 return false;
4100 }
4101
Brandon Jones28783792018-03-05 09:37:32 -08004102 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4103 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004104 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004105 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004106 return false;
4107 }
4108
Geoff Lang4f0e0032017-05-01 16:04:35 -04004109 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4110 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004111 context
4112 ->handleError(InvalidOperation()
4113 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004114 return false;
4115 }
4116
4117 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4118 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004119 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004120 context->handleError(InvalidOperation()
4121 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004122 return false;
4123 }
4124
4125 if (xoffset < 0 || yoffset < 0)
4126 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004127 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004128 return false;
4129 }
4130
Geoff Lang4f0e0032017-05-01 16:04:35 -04004131 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4132 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004133 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004134 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004135 return false;
4136 }
4137
4138 return true;
4139}
4140
Geoff Lang47110bf2016-04-20 11:13:22 -07004141bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4142{
4143 if (!context->getExtensions().copyCompressedTexture)
4144 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004145 context->handleError(InvalidOperation()
4146 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004147 return false;
4148 }
4149
4150 const gl::Texture *source = context->getTexture(sourceId);
4151 if (source == nullptr)
4152 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004153 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004154 return false;
4155 }
4156
Corentin Wallez99d492c2018-02-27 15:17:10 -05004157 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004158 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004159 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004160 return false;
4161 }
4162
Corentin Wallez99d492c2018-02-27 15:17:10 -05004163 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4164 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004165 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004166 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004167 return false;
4168 }
4169
Corentin Wallez99d492c2018-02-27 15:17:10 -05004170 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004171 if (!sourceFormat.info->compressed)
4172 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004173 context->handleError(InvalidOperation()
4174 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004175 return false;
4176 }
4177
4178 const gl::Texture *dest = context->getTexture(destId);
4179 if (dest == nullptr)
4180 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004181 context->handleError(InvalidValue()
4182 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004183 return false;
4184 }
4185
Corentin Wallez99d492c2018-02-27 15:17:10 -05004186 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004187 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004188 context->handleError(InvalidValue()
4189 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004190 return false;
4191 }
4192
4193 if (dest->getImmutableFormat())
4194 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004195 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004196 return false;
4197 }
4198
4199 return true;
4200}
4201
Jiawei Shao385b3e02018-03-21 09:43:28 +08004202bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004203{
4204 switch (type)
4205 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004206 case ShaderType::Vertex:
4207 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004208 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004209
Jiawei Shao385b3e02018-03-21 09:43:28 +08004210 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004211 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004212 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004213 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004214 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004215 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004216 break;
4217
Jiawei Shao385b3e02018-03-21 09:43:28 +08004218 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004219 if (!context->getExtensions().geometryShader)
4220 {
4221 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4222 return false;
4223 }
4224 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004225 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004226 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004227 return false;
4228 }
Jamie Madill29639852016-09-02 15:00:09 -04004229
4230 return true;
4231}
4232
Jamie Madill5b772312018-03-08 20:28:32 -05004233bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004234 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004235 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004236 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004237 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004238{
4239 if (size < 0)
4240 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004241 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004242 return false;
4243 }
4244
4245 switch (usage)
4246 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004247 case BufferUsage::StreamDraw:
4248 case BufferUsage::StaticDraw:
4249 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004250 break;
4251
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004252 case BufferUsage::StreamRead:
4253 case BufferUsage::StaticRead:
4254 case BufferUsage::DynamicRead:
4255 case BufferUsage::StreamCopy:
4256 case BufferUsage::StaticCopy:
4257 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004258 if (context->getClientMajorVersion() < 3)
4259 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004260 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004261 return false;
4262 }
4263 break;
4264
4265 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004266 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004267 return false;
4268 }
4269
Corentin Walleze4477002017-12-01 14:39:58 -05004270 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004271 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004272 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004273 return false;
4274 }
4275
4276 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4277
4278 if (!buffer)
4279 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004280 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004281 return false;
4282 }
4283
James Darpiniane8a93c62018-01-04 18:02:24 -08004284 if (context->getExtensions().webglCompatibility &&
4285 buffer->isBoundForTransformFeedbackAndOtherUse())
4286 {
4287 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4288 return false;
4289 }
4290
Jamie Madill29639852016-09-02 15:00:09 -04004291 return true;
4292}
4293
Jamie Madill5b772312018-03-08 20:28:32 -05004294bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004295 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004296 GLintptr offset,
4297 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004298 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004299{
Brandon Jones6cad5662017-06-14 13:25:13 -07004300 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004301 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004302 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4303 return false;
4304 }
4305
4306 if (offset < 0)
4307 {
4308 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004309 return false;
4310 }
4311
Corentin Walleze4477002017-12-01 14:39:58 -05004312 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004313 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004314 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004315 return false;
4316 }
4317
4318 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4319
4320 if (!buffer)
4321 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004322 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004323 return false;
4324 }
4325
4326 if (buffer->isMapped())
4327 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004328 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004329 return false;
4330 }
4331
James Darpiniane8a93c62018-01-04 18:02:24 -08004332 if (context->getExtensions().webglCompatibility &&
4333 buffer->isBoundForTransformFeedbackAndOtherUse())
4334 {
4335 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4336 return false;
4337 }
4338
Jamie Madill29639852016-09-02 15:00:09 -04004339 // Check for possible overflow of size + offset
4340 angle::CheckedNumeric<size_t> checkedSize(size);
4341 checkedSize += offset;
4342 if (!checkedSize.IsValid())
4343 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004344 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004345 return false;
4346 }
4347
4348 if (size + offset > buffer->getSize())
4349 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004350 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004351 return false;
4352 }
4353
Martin Radev4c4c8e72016-08-04 12:25:34 +03004354 return true;
4355}
4356
Geoff Lang111a99e2017-10-17 10:58:41 -04004357bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004358{
Geoff Langc339c4e2016-11-29 10:37:36 -05004359 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004360 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004361 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004362 return false;
4363 }
4364
Geoff Lang111a99e2017-10-17 10:58:41 -04004365 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004366 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004367 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004368 return false;
4369 }
4370
4371 return true;
4372}
4373
Jamie Madill5b772312018-03-08 20:28:32 -05004374bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004375{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004376 if (context->getClientMajorVersion() < 2)
4377 {
4378 return ValidateMultitextureUnit(context, texture);
4379 }
4380
Jamie Madillef300b12016-10-07 15:12:09 -04004381 if (texture < GL_TEXTURE0 ||
4382 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4383 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004384 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004385 return false;
4386 }
4387
4388 return true;
4389}
4390
Jamie Madill5b772312018-03-08 20:28:32 -05004391bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004392{
4393 Program *programObject = GetValidProgram(context, program);
4394 if (!programObject)
4395 {
4396 return false;
4397 }
4398
4399 Shader *shaderObject = GetValidShader(context, shader);
4400 if (!shaderObject)
4401 {
4402 return false;
4403 }
4404
Jiawei Shao385b3e02018-03-21 09:43:28 +08004405 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004406 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004407 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4408 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004409 }
4410
4411 return true;
4412}
4413
Jamie Madill5b772312018-03-08 20:28:32 -05004414bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004415{
4416 if (index >= MAX_VERTEX_ATTRIBS)
4417 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004418 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004419 return false;
4420 }
4421
4422 if (strncmp(name, "gl_", 3) == 0)
4423 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004424 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004425 return false;
4426 }
4427
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004428 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004429 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004430 const size_t length = strlen(name);
4431
4432 if (!IsValidESSLString(name, length))
4433 {
4434 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4435 // for shader-related entry points
4436 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4437 return false;
4438 }
4439
4440 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4441 {
4442 return false;
4443 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004444 }
4445
Jamie Madill01a80ee2016-11-07 12:06:18 -05004446 return GetValidProgram(context, program) != nullptr;
4447}
4448
Jamie Madill5b772312018-03-08 20:28:32 -05004449bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004450{
Corentin Walleze4477002017-12-01 14:39:58 -05004451 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004452 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004453 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004454 return false;
4455 }
4456
4457 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4458 !context->isBufferGenerated(buffer))
4459 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004460 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004461 return false;
4462 }
4463
4464 return true;
4465}
4466
Jamie Madill5b772312018-03-08 20:28:32 -05004467bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004468{
Geoff Lange8afa902017-09-27 15:00:43 -04004469 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004470 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004471 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004472 return false;
4473 }
4474
4475 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4476 !context->isFramebufferGenerated(framebuffer))
4477 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004478 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004479 return false;
4480 }
4481
4482 return true;
4483}
4484
Jamie Madill5b772312018-03-08 20:28:32 -05004485bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004486{
4487 if (target != GL_RENDERBUFFER)
4488 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004489 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004490 return false;
4491 }
4492
4493 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4494 !context->isRenderbufferGenerated(renderbuffer))
4495 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004496 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004497 return false;
4498 }
4499
4500 return true;
4501}
4502
Jamie Madill5b772312018-03-08 20:28:32 -05004503static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004504{
4505 switch (mode)
4506 {
4507 case GL_FUNC_ADD:
4508 case GL_FUNC_SUBTRACT:
4509 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004510 return true;
4511
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004512 case GL_MIN:
4513 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004514 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004515
4516 default:
4517 return false;
4518 }
4519}
4520
Jamie Madill5b772312018-03-08 20:28:32 -05004521bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004522{
4523 return true;
4524}
4525
Jamie Madill5b772312018-03-08 20:28:32 -05004526bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004527{
Geoff Lang50cac572017-09-26 17:37:43 -04004528 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004529 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004530 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004531 return false;
4532 }
4533
4534 return true;
4535}
4536
Jamie Madill5b772312018-03-08 20:28:32 -05004537bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004538{
Geoff Lang50cac572017-09-26 17:37:43 -04004539 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004540 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004541 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004542 return false;
4543 }
4544
Geoff Lang50cac572017-09-26 17:37:43 -04004545 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004546 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004547 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004548 return false;
4549 }
4550
4551 return true;
4552}
4553
Jamie Madill5b772312018-03-08 20:28:32 -05004554bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004555{
4556 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4557}
4558
4559static bool ValidSrcBlendFunc(GLenum srcBlend)
4560{
4561 switch (srcBlend)
4562 {
4563 case GL_ZERO:
4564 case GL_ONE:
4565 case GL_SRC_COLOR:
4566 case GL_ONE_MINUS_SRC_COLOR:
4567 case GL_DST_COLOR:
4568 case GL_ONE_MINUS_DST_COLOR:
4569 case GL_SRC_ALPHA:
4570 case GL_ONE_MINUS_SRC_ALPHA:
4571 case GL_DST_ALPHA:
4572 case GL_ONE_MINUS_DST_ALPHA:
4573 case GL_CONSTANT_COLOR:
4574 case GL_ONE_MINUS_CONSTANT_COLOR:
4575 case GL_CONSTANT_ALPHA:
4576 case GL_ONE_MINUS_CONSTANT_ALPHA:
4577 case GL_SRC_ALPHA_SATURATE:
4578 return true;
4579
4580 default:
4581 return false;
4582 }
4583}
4584
4585static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4586{
4587 switch (dstBlend)
4588 {
4589 case GL_ZERO:
4590 case GL_ONE:
4591 case GL_SRC_COLOR:
4592 case GL_ONE_MINUS_SRC_COLOR:
4593 case GL_DST_COLOR:
4594 case GL_ONE_MINUS_DST_COLOR:
4595 case GL_SRC_ALPHA:
4596 case GL_ONE_MINUS_SRC_ALPHA:
4597 case GL_DST_ALPHA:
4598 case GL_ONE_MINUS_DST_ALPHA:
4599 case GL_CONSTANT_COLOR:
4600 case GL_ONE_MINUS_CONSTANT_COLOR:
4601 case GL_CONSTANT_ALPHA:
4602 case GL_ONE_MINUS_CONSTANT_ALPHA:
4603 return true;
4604
4605 case GL_SRC_ALPHA_SATURATE:
4606 return (contextMajorVersion >= 3);
4607
4608 default:
4609 return false;
4610 }
4611}
4612
Jamie Madill5b772312018-03-08 20:28:32 -05004613bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004614 GLenum srcRGB,
4615 GLenum dstRGB,
4616 GLenum srcAlpha,
4617 GLenum dstAlpha)
4618{
4619 if (!ValidSrcBlendFunc(srcRGB))
4620 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004621 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004622 return false;
4623 }
4624
4625 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4626 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004627 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004628 return false;
4629 }
4630
4631 if (!ValidSrcBlendFunc(srcAlpha))
4632 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004633 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004634 return false;
4635 }
4636
4637 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4638 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004639 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004640 return false;
4641 }
4642
Frank Henigman146e8a12017-03-02 23:22:37 -05004643 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4644 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004645 {
4646 bool constantColorUsed =
4647 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4648 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4649
4650 bool constantAlphaUsed =
4651 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4652 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4653
4654 if (constantColorUsed && constantAlphaUsed)
4655 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004656 const char *msg;
4657 if (context->getExtensions().webglCompatibility)
4658 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004659 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004660 }
4661 else
4662 {
4663 msg =
4664 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4665 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4666 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004667 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004668 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004669 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004670 return false;
4671 }
4672 }
4673
4674 return true;
4675}
4676
Geoff Langc339c4e2016-11-29 10:37:36 -05004677bool ValidateGetString(Context *context, GLenum name)
4678{
4679 switch (name)
4680 {
4681 case GL_VENDOR:
4682 case GL_RENDERER:
4683 case GL_VERSION:
4684 case GL_SHADING_LANGUAGE_VERSION:
4685 case GL_EXTENSIONS:
4686 break;
4687
4688 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4689 if (!context->getExtensions().requestExtension)
4690 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004691 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004692 return false;
4693 }
4694 break;
4695
4696 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004697 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004698 return false;
4699 }
4700
4701 return true;
4702}
4703
Jamie Madill5b772312018-03-08 20:28:32 -05004704bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004705{
4706 if (width <= 0.0f || isNaN(width))
4707 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004708 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004709 return false;
4710 }
4711
4712 return true;
4713}
4714
Jamie Madill5b772312018-03-08 20:28:32 -05004715bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004716 GLuint index,
4717 GLint size,
4718 GLenum type,
4719 GLboolean normalized,
4720 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004721 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004722{
Shao80957d92017-02-20 21:25:59 +08004723 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004724 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004725 return false;
4726 }
4727
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004728 if (stride < 0)
4729 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004730 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004731 return false;
4732 }
4733
Shao80957d92017-02-20 21:25:59 +08004734 const Caps &caps = context->getCaps();
4735 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004736 {
Shao80957d92017-02-20 21:25:59 +08004737 if (stride > caps.maxVertexAttribStride)
4738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004739 context->handleError(InvalidValue()
4740 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004741 return false;
4742 }
4743
4744 if (index >= caps.maxVertexAttribBindings)
4745 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004746 context->handleError(InvalidValue()
4747 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004748 return false;
4749 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004750 }
4751
4752 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4753 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4754 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4755 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004756 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4757 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004758 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4759 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004760 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004761 context
4762 ->handleError(InvalidOperation()
4763 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004764 return false;
4765 }
4766
4767 if (context->getExtensions().webglCompatibility)
4768 {
4769 // WebGL 1.0 [Section 6.14] Fixed point support
4770 // The WebGL API does not support the GL_FIXED data type.
4771 if (type == GL_FIXED)
4772 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004773 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004774 return false;
4775 }
4776
Geoff Lang2d62ab72017-03-23 16:54:40 -04004777 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004778 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004779 return false;
4780 }
4781 }
4782
4783 return true;
4784}
4785
Jamie Madill5b772312018-03-08 20:28:32 -05004786bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004787{
4788 if (context->getExtensions().webglCompatibility && zNear > zFar)
4789 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004790 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004791 return false;
4792 }
4793
4794 return true;
4795}
4796
Jamie Madill5b772312018-03-08 20:28:32 -05004797bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004798 GLenum target,
4799 GLenum internalformat,
4800 GLsizei width,
4801 GLsizei height)
4802{
4803 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4804 height);
4805}
4806
Jamie Madill5b772312018-03-08 20:28:32 -05004807bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004808 GLenum target,
4809 GLsizei samples,
4810 GLenum internalformat,
4811 GLsizei width,
4812 GLsizei height)
4813{
4814 if (!context->getExtensions().framebufferMultisample)
4815 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004816 context->handleError(InvalidOperation()
4817 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004818 return false;
4819 }
4820
4821 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4822 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4823 // generated.
4824 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4825 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004826 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004827 return false;
4828 }
4829
4830 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4831 // the specified storage. This is different than ES 3.0 in which a sample number higher
4832 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4833 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4834 if (context->getClientMajorVersion() >= 3)
4835 {
4836 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4837 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4838 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004839 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004840 return false;
4841 }
4842 }
4843
4844 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4845 width, height);
4846}
4847
Jamie Madill5b772312018-03-08 20:28:32 -05004848bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004849{
Geoff Lange8afa902017-09-27 15:00:43 -04004850 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004851 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004852 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004853 return false;
4854 }
4855
4856 return true;
4857}
4858
Jamie Madill5b772312018-03-08 20:28:32 -05004859bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004860{
4861 return true;
4862}
4863
Jamie Madill5b772312018-03-08 20:28:32 -05004864bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004865{
4866 return true;
4867}
4868
Jamie Madill5b772312018-03-08 20:28:32 -05004869bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004870{
4871 return true;
4872}
4873
Jamie Madill5b772312018-03-08 20:28:32 -05004874bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004875 GLboolean red,
4876 GLboolean green,
4877 GLboolean blue,
4878 GLboolean alpha)
4879{
4880 return true;
4881}
4882
Jamie Madill5b772312018-03-08 20:28:32 -05004883bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004884{
4885 return true;
4886}
4887
Jamie Madill5b772312018-03-08 20:28:32 -05004888bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004889{
4890 return true;
4891}
4892
Jamie Madill5b772312018-03-08 20:28:32 -05004893bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894{
4895 switch (mode)
4896 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004897 case CullFaceMode::Front:
4898 case CullFaceMode::Back:
4899 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004900 break;
4901
4902 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004903 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004904 return false;
4905 }
4906
4907 return true;
4908}
4909
Jamie Madill5b772312018-03-08 20:28:32 -05004910bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004911{
4912 if (program == 0)
4913 {
4914 return false;
4915 }
4916
4917 if (!context->getProgram(program))
4918 {
4919 if (context->getShader(program))
4920 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004921 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004922 return false;
4923 }
4924 else
4925 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004926 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004927 return false;
4928 }
4929 }
4930
4931 return true;
4932}
4933
Jamie Madill5b772312018-03-08 20:28:32 -05004934bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004935{
4936 if (shader == 0)
4937 {
4938 return false;
4939 }
4940
4941 if (!context->getShader(shader))
4942 {
4943 if (context->getProgram(shader))
4944 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004945 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004946 return false;
4947 }
4948 else
4949 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004950 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004951 return false;
4952 }
4953 }
4954
4955 return true;
4956}
4957
Jamie Madill5b772312018-03-08 20:28:32 -05004958bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004959{
4960 switch (func)
4961 {
4962 case GL_NEVER:
4963 case GL_ALWAYS:
4964 case GL_LESS:
4965 case GL_LEQUAL:
4966 case GL_EQUAL:
4967 case GL_GREATER:
4968 case GL_GEQUAL:
4969 case GL_NOTEQUAL:
4970 break;
4971
4972 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004973 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004974 return false;
4975 }
4976
4977 return true;
4978}
4979
Jamie Madill5b772312018-03-08 20:28:32 -05004980bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004981{
4982 return true;
4983}
4984
Jamie Madill5b772312018-03-08 20:28:32 -05004985bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004986{
4987 Program *programObject = GetValidProgram(context, program);
4988 if (!programObject)
4989 {
4990 return false;
4991 }
4992
4993 Shader *shaderObject = GetValidShader(context, shader);
4994 if (!shaderObject)
4995 {
4996 return false;
4997 }
4998
Jiawei Shao385b3e02018-03-21 09:43:28 +08004999 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005000 if (attachedShader != shaderObject)
5001 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005002 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005003 return false;
5004 }
5005
5006 return true;
5007}
5008
Jamie Madill5b772312018-03-08 20:28:32 -05005009bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005010{
5011 if (index >= MAX_VERTEX_ATTRIBS)
5012 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005013 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005014 return false;
5015 }
5016
5017 return true;
5018}
5019
Jamie Madill5b772312018-03-08 20:28:32 -05005020bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005021{
5022 if (index >= MAX_VERTEX_ATTRIBS)
5023 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005024 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005025 return false;
5026 }
5027
5028 return true;
5029}
5030
Jamie Madill5b772312018-03-08 20:28:32 -05005031bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005032{
5033 return true;
5034}
5035
Jamie Madill5b772312018-03-08 20:28:32 -05005036bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005037{
5038 return true;
5039}
5040
Jamie Madill5b772312018-03-08 20:28:32 -05005041bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005042{
5043 switch (mode)
5044 {
5045 case GL_CW:
5046 case GL_CCW:
5047 break;
5048 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005049 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005050 return false;
5051 }
5052
5053 return true;
5054}
5055
Jamie Madill5b772312018-03-08 20:28:32 -05005056bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005057 GLuint program,
5058 GLuint index,
5059 GLsizei bufsize,
5060 GLsizei *length,
5061 GLint *size,
5062 GLenum *type,
5063 GLchar *name)
5064{
5065 if (bufsize < 0)
5066 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005067 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005068 return false;
5069 }
5070
5071 Program *programObject = GetValidProgram(context, program);
5072
5073 if (!programObject)
5074 {
5075 return false;
5076 }
5077
5078 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5079 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005080 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005081 return false;
5082 }
5083
5084 return true;
5085}
5086
Jamie Madill5b772312018-03-08 20:28:32 -05005087bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005088 GLuint program,
5089 GLuint index,
5090 GLsizei bufsize,
5091 GLsizei *length,
5092 GLint *size,
5093 GLenum *type,
5094 GLchar *name)
5095{
5096 if (bufsize < 0)
5097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005098 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005099 return false;
5100 }
5101
5102 Program *programObject = GetValidProgram(context, program);
5103
5104 if (!programObject)
5105 {
5106 return false;
5107 }
5108
5109 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5110 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005111 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005112 return false;
5113 }
5114
5115 return true;
5116}
5117
Jamie Madill5b772312018-03-08 20:28:32 -05005118bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005119 GLuint program,
5120 GLsizei maxcount,
5121 GLsizei *count,
5122 GLuint *shaders)
5123{
5124 if (maxcount < 0)
5125 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005126 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005127 return false;
5128 }
5129
5130 Program *programObject = GetValidProgram(context, program);
5131
5132 if (!programObject)
5133 {
5134 return false;
5135 }
5136
5137 return true;
5138}
5139
Jamie Madill5b772312018-03-08 20:28:32 -05005140bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005141{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005142 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5143 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005144 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005145 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005146 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005147 return false;
5148 }
5149
Jamie Madillc1d770e2017-04-13 17:31:24 -04005150 Program *programObject = GetValidProgram(context, program);
5151
5152 if (!programObject)
5153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005155 return false;
5156 }
5157
5158 if (!programObject->isLinked())
5159 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005160 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161 return false;
5162 }
5163
5164 return true;
5165}
5166
Jamie Madill5b772312018-03-08 20:28:32 -05005167bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *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 ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005175{
5176 return true;
5177}
5178
Jamie Madill5b772312018-03-08 20:28:32 -05005179bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005180{
5181 GLenum nativeType;
5182 unsigned int numParams = 0;
5183 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5184}
5185
Jamie Madill5b772312018-03-08 20:28:32 -05005186bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005187{
5188 GLenum nativeType;
5189 unsigned int numParams = 0;
5190 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5191}
5192
Jamie Madill5b772312018-03-08 20:28:32 -05005193bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005194 GLuint program,
5195 GLsizei bufsize,
5196 GLsizei *length,
5197 GLchar *infolog)
5198{
5199 if (bufsize < 0)
5200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005201 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005202 return false;
5203 }
5204
5205 Program *programObject = GetValidProgram(context, program);
5206 if (!programObject)
5207 {
5208 return false;
5209 }
5210
5211 return true;
5212}
5213
Jamie Madill5b772312018-03-08 20:28:32 -05005214bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005215 GLuint shader,
5216 GLsizei bufsize,
5217 GLsizei *length,
5218 GLchar *infolog)
5219{
5220 if (bufsize < 0)
5221 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005222 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005223 return false;
5224 }
5225
5226 Shader *shaderObject = GetValidShader(context, shader);
5227 if (!shaderObject)
5228 {
5229 return false;
5230 }
5231
5232 return true;
5233}
5234
Jamie Madill5b772312018-03-08 20:28:32 -05005235bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005236 GLenum shadertype,
5237 GLenum precisiontype,
5238 GLint *range,
5239 GLint *precision)
5240{
5241 switch (shadertype)
5242 {
5243 case GL_VERTEX_SHADER:
5244 case GL_FRAGMENT_SHADER:
5245 break;
5246 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005247 context->handleError(InvalidOperation()
5248 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005249 return false;
5250 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005251 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005252 return false;
5253 }
5254
5255 switch (precisiontype)
5256 {
5257 case GL_LOW_FLOAT:
5258 case GL_MEDIUM_FLOAT:
5259 case GL_HIGH_FLOAT:
5260 case GL_LOW_INT:
5261 case GL_MEDIUM_INT:
5262 case GL_HIGH_INT:
5263 break;
5264
5265 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005266 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005267 return false;
5268 }
5269
5270 return true;
5271}
5272
Jamie Madill5b772312018-03-08 20:28:32 -05005273bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005274 GLuint shader,
5275 GLsizei bufsize,
5276 GLsizei *length,
5277 GLchar *source)
5278{
5279 if (bufsize < 0)
5280 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005281 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005282 return false;
5283 }
5284
5285 Shader *shaderObject = GetValidShader(context, shader);
5286 if (!shaderObject)
5287 {
5288 return false;
5289 }
5290
5291 return true;
5292}
5293
Jamie Madill5b772312018-03-08 20:28:32 -05005294bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005295{
5296 if (strstr(name, "gl_") == name)
5297 {
5298 return false;
5299 }
5300
Geoff Langfc32e8b2017-05-31 14:16:59 -04005301 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5302 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005303 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005304 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005305 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005306 return false;
5307 }
5308
Jamie Madillc1d770e2017-04-13 17:31:24 -04005309 Program *programObject = GetValidProgram(context, program);
5310
5311 if (!programObject)
5312 {
5313 return false;
5314 }
5315
5316 if (!programObject->isLinked())
5317 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005318 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005319 return false;
5320 }
5321
5322 return true;
5323}
5324
Jamie Madill5b772312018-03-08 20:28:32 -05005325bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005326{
5327 switch (mode)
5328 {
5329 case GL_FASTEST:
5330 case GL_NICEST:
5331 case GL_DONT_CARE:
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 switch (target)
5340 {
5341 case GL_GENERATE_MIPMAP_HINT:
5342 break;
5343
Geoff Lange7bd2182017-06-16 16:13:13 -04005344 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5345 if (context->getClientVersion() < ES_3_0 &&
5346 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005348 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005349 return false;
5350 }
5351 break;
5352
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005353 case GL_PERSPECTIVE_CORRECTION_HINT:
5354 case GL_POINT_SMOOTH_HINT:
5355 case GL_LINE_SMOOTH_HINT:
5356 case GL_FOG_HINT:
5357 if (context->getClientMajorVersion() >= 2)
5358 {
5359 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5360 return false;
5361 }
5362 break;
5363
Jamie Madillc1d770e2017-04-13 17:31:24 -04005364 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005365 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005366 return false;
5367 }
5368
5369 return true;
5370}
5371
Jamie Madill5b772312018-03-08 20:28:32 -05005372bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005373{
5374 return true;
5375}
5376
Jamie Madill5b772312018-03-08 20:28:32 -05005377bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378{
5379 return true;
5380}
5381
Jamie Madill5b772312018-03-08 20:28:32 -05005382bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005383{
5384 return true;
5385}
5386
Jamie Madill5b772312018-03-08 20:28:32 -05005387bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005388{
5389 return true;
5390}
5391
Jamie Madill5b772312018-03-08 20:28:32 -05005392bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005393{
5394 return true;
5395}
5396
Jamie Madill5b772312018-03-08 20:28:32 -05005397bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005398{
5399 return true;
5400}
5401
Jamie Madill5b772312018-03-08 20:28:32 -05005402bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005403{
5404 if (context->getClientMajorVersion() < 3)
5405 {
5406 switch (pname)
5407 {
5408 case GL_UNPACK_IMAGE_HEIGHT:
5409 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005410 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005411 return false;
5412
5413 case GL_UNPACK_ROW_LENGTH:
5414 case GL_UNPACK_SKIP_ROWS:
5415 case GL_UNPACK_SKIP_PIXELS:
5416 if (!context->getExtensions().unpackSubimage)
5417 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005418 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005419 return false;
5420 }
5421 break;
5422
5423 case GL_PACK_ROW_LENGTH:
5424 case GL_PACK_SKIP_ROWS:
5425 case GL_PACK_SKIP_PIXELS:
5426 if (!context->getExtensions().packSubimage)
5427 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005428 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005429 return false;
5430 }
5431 break;
5432 }
5433 }
5434
5435 if (param < 0)
5436 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005437 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005438 return false;
5439 }
5440
5441 switch (pname)
5442 {
5443 case GL_UNPACK_ALIGNMENT:
5444 if (param != 1 && param != 2 && param != 4 && param != 8)
5445 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005446 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005447 return false;
5448 }
5449 break;
5450
5451 case GL_PACK_ALIGNMENT:
5452 if (param != 1 && param != 2 && param != 4 && param != 8)
5453 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005454 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005455 return false;
5456 }
5457 break;
5458
5459 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005460 if (!context->getExtensions().packReverseRowOrder)
5461 {
5462 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5463 }
5464 break;
5465
Jamie Madillc1d770e2017-04-13 17:31:24 -04005466 case GL_UNPACK_ROW_LENGTH:
5467 case GL_UNPACK_IMAGE_HEIGHT:
5468 case GL_UNPACK_SKIP_IMAGES:
5469 case GL_UNPACK_SKIP_ROWS:
5470 case GL_UNPACK_SKIP_PIXELS:
5471 case GL_PACK_ROW_LENGTH:
5472 case GL_PACK_SKIP_ROWS:
5473 case GL_PACK_SKIP_PIXELS:
5474 break;
5475
5476 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005477 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005478 return false;
5479 }
5480
5481 return true;
5482}
5483
Jamie Madill5b772312018-03-08 20:28:32 -05005484bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485{
5486 return true;
5487}
5488
Jamie Madill5b772312018-03-08 20:28:32 -05005489bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005490{
5491 return true;
5492}
5493
Jamie Madill5b772312018-03-08 20:28:32 -05005494bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005495{
5496 return true;
5497}
5498
Jamie Madill5b772312018-03-08 20:28:32 -05005499bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005500{
5501 if (width < 0 || height < 0)
5502 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005503 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005504 return false;
5505 }
5506
5507 return true;
5508}
5509
Jamie Madill5b772312018-03-08 20:28:32 -05005510bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005511 GLsizei n,
5512 const GLuint *shaders,
5513 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005514 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005515 GLsizei length)
5516{
5517 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5518 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5519 shaderBinaryFormats.end())
5520 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005521 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005522 return false;
5523 }
5524
5525 return true;
5526}
5527
Jamie Madill5b772312018-03-08 20:28:32 -05005528bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005529 GLuint shader,
5530 GLsizei count,
5531 const GLchar *const *string,
5532 const GLint *length)
5533{
5534 if (count < 0)
5535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005536 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005537 return false;
5538 }
5539
Geoff Langfc32e8b2017-05-31 14:16:59 -04005540 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5541 // shader-related entry points
5542 if (context->getExtensions().webglCompatibility)
5543 {
5544 for (GLsizei i = 0; i < count; i++)
5545 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005546 size_t len =
5547 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005548
5549 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005550 if (!IsValidESSLShaderSourceString(string[i], len,
5551 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005553 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005554 return false;
5555 }
5556 }
5557 }
5558
Jamie Madillc1d770e2017-04-13 17:31:24 -04005559 Shader *shaderObject = GetValidShader(context, shader);
5560 if (!shaderObject)
5561 {
5562 return false;
5563 }
5564
5565 return true;
5566}
5567
Jamie Madill5b772312018-03-08 20:28:32 -05005568bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005569{
5570 if (!IsValidStencilFunc(func))
5571 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005572 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005573 return false;
5574 }
5575
5576 return true;
5577}
5578
Jamie Madill5b772312018-03-08 20:28:32 -05005579bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580{
5581 if (!IsValidStencilFace(face))
5582 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005583 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005584 return false;
5585 }
5586
5587 if (!IsValidStencilFunc(func))
5588 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005589 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005590 return false;
5591 }
5592
5593 return true;
5594}
5595
Jamie Madill5b772312018-03-08 20:28:32 -05005596bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005597{
5598 return true;
5599}
5600
Jamie Madill5b772312018-03-08 20:28:32 -05005601bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602{
5603 if (!IsValidStencilFace(face))
5604 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005605 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005606 return false;
5607 }
5608
5609 return true;
5610}
5611
Jamie Madill5b772312018-03-08 20:28:32 -05005612bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005613{
5614 if (!IsValidStencilOp(fail))
5615 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005616 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005617 return false;
5618 }
5619
5620 if (!IsValidStencilOp(zfail))
5621 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005622 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005623 return false;
5624 }
5625
5626 if (!IsValidStencilOp(zpass))
5627 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005628 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629 return false;
5630 }
5631
5632 return true;
5633}
5634
Jamie Madill5b772312018-03-08 20:28:32 -05005635bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005636 GLenum face,
5637 GLenum fail,
5638 GLenum zfail,
5639 GLenum zpass)
5640{
5641 if (!IsValidStencilFace(face))
5642 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005643 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005644 return false;
5645 }
5646
5647 return ValidateStencilOp(context, fail, zfail, zpass);
5648}
5649
Jamie Madill5b772312018-03-08 20:28:32 -05005650bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005651{
5652 return ValidateUniform(context, GL_FLOAT, location, 1);
5653}
5654
Jamie Madill5b772312018-03-08 20:28:32 -05005655bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005656{
5657 return ValidateUniform(context, GL_FLOAT, location, count);
5658}
5659
Jamie Madill5b772312018-03-08 20:28:32 -05005660bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005661{
5662 return ValidateUniform1iv(context, location, 1, &x);
5663}
5664
Jamie Madill5b772312018-03-08 20:28:32 -05005665bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005666{
5667 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5668}
5669
Jamie Madill5b772312018-03-08 20:28:32 -05005670bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005671{
5672 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5673}
5674
Jamie Madill5b772312018-03-08 20:28:32 -05005675bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005676{
5677 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5678}
5679
Jamie Madill5b772312018-03-08 20:28:32 -05005680bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005681{
5682 return ValidateUniform(context, GL_INT_VEC2, location, count);
5683}
5684
Jamie Madill5b772312018-03-08 20:28:32 -05005685bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005686{
5687 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5688}
5689
Jamie Madill5b772312018-03-08 20:28:32 -05005690bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005691{
5692 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5693}
5694
Jamie Madill5b772312018-03-08 20:28:32 -05005695bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005696{
5697 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5698}
5699
Jamie Madill5b772312018-03-08 20:28:32 -05005700bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005701{
5702 return ValidateUniform(context, GL_INT_VEC3, location, count);
5703}
5704
Jamie Madill5b772312018-03-08 20:28:32 -05005705bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005706{
5707 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5708}
5709
Jamie Madill5b772312018-03-08 20:28:32 -05005710bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005711{
5712 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5713}
5714
Jamie Madill5b772312018-03-08 20:28:32 -05005715bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005716{
5717 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5718}
5719
Jamie Madill5b772312018-03-08 20:28:32 -05005720bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005721{
5722 return ValidateUniform(context, GL_INT_VEC4, location, count);
5723}
5724
Jamie Madill5b772312018-03-08 20:28:32 -05005725bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005726 GLint location,
5727 GLsizei count,
5728 GLboolean transpose,
5729 const GLfloat *value)
5730{
5731 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5732}
5733
Jamie Madill5b772312018-03-08 20:28:32 -05005734bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005735 GLint location,
5736 GLsizei count,
5737 GLboolean transpose,
5738 const GLfloat *value)
5739{
5740 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5741}
5742
Jamie Madill5b772312018-03-08 20:28:32 -05005743bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005744 GLint location,
5745 GLsizei count,
5746 GLboolean transpose,
5747 const GLfloat *value)
5748{
5749 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5750}
5751
Jamie Madill5b772312018-03-08 20:28:32 -05005752bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005753{
5754 Program *programObject = GetValidProgram(context, program);
5755
5756 if (!programObject)
5757 {
5758 return false;
5759 }
5760
5761 return true;
5762}
5763
Jamie Madill5b772312018-03-08 20:28:32 -05005764bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005765{
5766 return ValidateVertexAttribIndex(context, index);
5767}
5768
Jamie Madill5b772312018-03-08 20:28:32 -05005769bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005770{
5771 return ValidateVertexAttribIndex(context, index);
5772}
5773
Jamie Madill5b772312018-03-08 20:28:32 -05005774bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005775{
5776 return ValidateVertexAttribIndex(context, index);
5777}
5778
Jamie Madill5b772312018-03-08 20:28:32 -05005779bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005780{
5781 return ValidateVertexAttribIndex(context, index);
5782}
5783
Jamie Madill5b772312018-03-08 20:28:32 -05005784bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005785{
5786 return ValidateVertexAttribIndex(context, index);
5787}
5788
Jamie Madill5b772312018-03-08 20:28:32 -05005789bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005790{
5791 return ValidateVertexAttribIndex(context, index);
5792}
5793
Jamie Madill5b772312018-03-08 20:28:32 -05005794bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005795 GLuint index,
5796 GLfloat x,
5797 GLfloat y,
5798 GLfloat z,
5799 GLfloat w)
5800{
5801 return ValidateVertexAttribIndex(context, index);
5802}
5803
Jamie Madill5b772312018-03-08 20:28:32 -05005804bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005805{
5806 return ValidateVertexAttribIndex(context, index);
5807}
5808
Jamie Madill5b772312018-03-08 20:28:32 -05005809bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005810{
5811 if (width < 0 || height < 0)
5812 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005813 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005814 return false;
5815 }
5816
5817 return true;
5818}
5819
Jamie Madill493f9572018-05-24 19:52:15 -04005820bool ValidateDrawArrays(Context *context, PrimitiveMode mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005821{
5822 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5823}
5824
Jamie Madill5b772312018-03-08 20:28:32 -05005825bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005826 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005827 GLsizei count,
5828 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005829 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005830{
5831 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5832}
5833
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005834bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005835 GLenum target,
5836 GLenum attachment,
5837 GLenum pname,
5838 GLint *params)
5839{
5840 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5841 nullptr);
5842}
5843
Jamie Madill5b772312018-03-08 20:28:32 -05005844bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005845{
5846 return ValidateGetProgramivBase(context, program, pname, nullptr);
5847}
5848
Jamie Madill5b772312018-03-08 20:28:32 -05005849bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005850 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005851 GLint level,
5852 GLenum internalformat,
5853 GLint x,
5854 GLint y,
5855 GLsizei width,
5856 GLsizei height,
5857 GLint border)
5858{
5859 if (context->getClientMajorVersion() < 3)
5860 {
5861 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5862 0, x, y, width, height, border);
5863 }
5864
5865 ASSERT(context->getClientMajorVersion() == 3);
5866 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5867 0, x, y, width, height, border);
5868}
5869
5870bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005871 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005872 GLint level,
5873 GLint xoffset,
5874 GLint yoffset,
5875 GLint x,
5876 GLint y,
5877 GLsizei width,
5878 GLsizei height)
5879{
5880 if (context->getClientMajorVersion() < 3)
5881 {
5882 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5883 yoffset, x, y, width, height, 0);
5884 }
5885
5886 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5887 yoffset, 0, x, y, width, height, 0);
5888}
5889
5890bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5891{
5892 return ValidateGenOrDelete(context, n);
5893}
5894
5895bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5896{
5897 return ValidateGenOrDelete(context, n);
5898}
5899
5900bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5901{
5902 return ValidateGenOrDelete(context, n);
5903}
5904
5905bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5906{
5907 return ValidateGenOrDelete(context, n);
5908}
5909
5910bool ValidateDisable(Context *context, GLenum cap)
5911{
5912 if (!ValidCap(context, cap, false))
5913 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005914 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005915 return false;
5916 }
5917
5918 return true;
5919}
5920
5921bool ValidateEnable(Context *context, GLenum cap)
5922{
5923 if (!ValidCap(context, cap, false))
5924 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005925 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005926 return false;
5927 }
5928
5929 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5930 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5931 {
5932 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005933 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005934
5935 // We also output an error message to the debugger window if tracing is active, so that
5936 // developers can see the error message.
5937 ERR() << errorMessage;
5938 return false;
5939 }
5940
5941 return true;
5942}
5943
5944bool ValidateFramebufferRenderbuffer(Context *context,
5945 GLenum target,
5946 GLenum attachment,
5947 GLenum renderbuffertarget,
5948 GLuint renderbuffer)
5949{
Geoff Lange8afa902017-09-27 15:00:43 -04005950 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005951 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005952 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5953 return false;
5954 }
5955
5956 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5957 {
5958 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005959 return false;
5960 }
5961
5962 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5963 renderbuffertarget, renderbuffer);
5964}
5965
5966bool ValidateFramebufferTexture2D(Context *context,
5967 GLenum target,
5968 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005969 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005970 GLuint texture,
5971 GLint level)
5972{
5973 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5974 // extension
5975 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5976 level != 0)
5977 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005978 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005979 return false;
5980 }
5981
5982 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5983 {
5984 return false;
5985 }
5986
5987 if (texture != 0)
5988 {
5989 gl::Texture *tex = context->getTexture(texture);
5990 ASSERT(tex);
5991
5992 const gl::Caps &caps = context->getCaps();
5993
5994 switch (textarget)
5995 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005996 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005997 {
5998 if (level > gl::log2(caps.max2DTextureSize))
5999 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006000 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006001 return false;
6002 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006003 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006004 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006005 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 return false;
6007 }
6008 }
6009 break;
6010
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006011 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006012 {
6013 if (level != 0)
6014 {
6015 context->handleError(InvalidValue());
6016 return false;
6017 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006018 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006019 {
6020 context->handleError(InvalidOperation()
6021 << "Textarget must match the texture target type.");
6022 return false;
6023 }
6024 }
6025 break;
6026
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006027 case TextureTarget::CubeMapNegativeX:
6028 case TextureTarget::CubeMapNegativeY:
6029 case TextureTarget::CubeMapNegativeZ:
6030 case TextureTarget::CubeMapPositiveX:
6031 case TextureTarget::CubeMapPositiveY:
6032 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006033 {
6034 if (level > gl::log2(caps.maxCubeMapTextureSize))
6035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006036 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 return false;
6038 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006039 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006040 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006041 context->handleError(InvalidOperation()
6042 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006043 return false;
6044 }
6045 }
6046 break;
6047
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006048 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 {
6050 if (context->getClientVersion() < ES_3_1)
6051 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006052 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006053 return false;
6054 }
6055
6056 if (level != 0)
6057 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006058 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006059 return false;
6060 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006061 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006062 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006063 context->handleError(InvalidOperation()
6064 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006065 return false;
6066 }
6067 }
6068 break;
6069
6070 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006071 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006072 return false;
6073 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006074 }
6075
6076 return true;
6077}
6078
6079bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6080{
6081 return ValidateGenOrDelete(context, n);
6082}
6083
6084bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6085{
6086 return ValidateGenOrDelete(context, n);
6087}
6088
6089bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6090{
6091 return ValidateGenOrDelete(context, n);
6092}
6093
6094bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6095{
6096 return ValidateGenOrDelete(context, n);
6097}
6098
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006099bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006100{
6101 if (!ValidTextureTarget(context, target))
6102 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006103 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006104 return false;
6105 }
6106
6107 Texture *texture = context->getTargetTexture(target);
6108
6109 if (texture == nullptr)
6110 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006111 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006112 return false;
6113 }
6114
6115 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6116
6117 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6118 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6119 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6120 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006121 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006122 return false;
6123 }
6124
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006125 TextureTarget baseTarget = (target == TextureType::CubeMap)
6126 ? TextureTarget::CubeMapPositiveX
6127 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006128 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6129 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6130 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006131 {
6132 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6133 return false;
6134 }
6135
Geoff Lang536eca12017-09-13 11:23:35 -04006136 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6137 bool formatUnsized = !format.sized;
6138 bool formatColorRenderableAndFilterable =
6139 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006140 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006141 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006142 {
Geoff Lang536eca12017-09-13 11:23:35 -04006143 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006144 return false;
6145 }
6146
Geoff Lang536eca12017-09-13 11:23:35 -04006147 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6148 // generation
6149 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6150 {
6151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6152 return false;
6153 }
6154
Jiange2c00842018-07-13 16:50:49 +08006155 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6156 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6157 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006158 {
Geoff Lang536eca12017-09-13 11:23:35 -04006159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006160 return false;
6161 }
6162
6163 // Non-power of 2 ES2 check
6164 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6165 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6166 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6167 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006168 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6169 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006170 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006171 return false;
6172 }
6173
6174 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006175 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006176 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006177 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006178 return false;
6179 }
6180
6181 return true;
6182}
6183
Jamie Madill5b772312018-03-08 20:28:32 -05006184bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006185 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006186 GLenum pname,
6187 GLint *params)
6188{
6189 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6190}
6191
6192bool ValidateGetRenderbufferParameteriv(Context *context,
6193 GLenum target,
6194 GLenum pname,
6195 GLint *params)
6196{
6197 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6198}
6199
6200bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6201{
6202 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6203}
6204
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006205bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006206{
6207 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6208}
6209
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006210bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006211{
6212 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6213}
6214
6215bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6216{
6217 return ValidateGetUniformBase(context, program, location);
6218}
6219
6220bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6221{
6222 return ValidateGetUniformBase(context, program, location);
6223}
6224
6225bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6226{
6227 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6228}
6229
6230bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6231{
6232 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6233}
6234
6235bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6236{
6237 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6238}
6239
6240bool ValidateIsEnabled(Context *context, GLenum cap)
6241{
6242 if (!ValidCap(context, cap, true))
6243 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006244 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006245 return false;
6246 }
6247
6248 return true;
6249}
6250
6251bool ValidateLinkProgram(Context *context, GLuint program)
6252{
6253 if (context->hasActiveTransformFeedback(program))
6254 {
6255 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006256 context->handleError(InvalidOperation() << "Cannot link program while program is "
6257 "associated with an active transform "
6258 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006259 return false;
6260 }
6261
6262 Program *programObject = GetValidProgram(context, program);
6263 if (!programObject)
6264 {
6265 return false;
6266 }
6267
6268 return true;
6269}
6270
Jamie Madill4928b7c2017-06-20 12:57:39 -04006271bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006272 GLint x,
6273 GLint y,
6274 GLsizei width,
6275 GLsizei height,
6276 GLenum format,
6277 GLenum type,
6278 void *pixels)
6279{
6280 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6281 nullptr, pixels);
6282}
6283
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006284bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006285{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006286 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006287}
6288
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006289bool ValidateTexParameterfv(Context *context,
6290 TextureType target,
6291 GLenum pname,
6292 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006293{
6294 return ValidateTexParameterBase(context, target, pname, -1, params);
6295}
6296
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006297bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006298{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006299 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006300}
6301
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006302bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006303{
6304 return ValidateTexParameterBase(context, target, pname, -1, params);
6305}
6306
6307bool ValidateUseProgram(Context *context, GLuint program)
6308{
6309 if (program != 0)
6310 {
6311 Program *programObject = context->getProgram(program);
6312 if (!programObject)
6313 {
6314 // ES 3.1.0 section 7.3 page 72
6315 if (context->getShader(program))
6316 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006317 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006318 return false;
6319 }
6320 else
6321 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006322 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006323 return false;
6324 }
6325 }
6326 if (!programObject->isLinked())
6327 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006328 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006329 return false;
6330 }
6331 }
6332 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6333 {
6334 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006335 context
6336 ->handleError(InvalidOperation()
6337 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006338 return false;
6339 }
6340
6341 return true;
6342}
6343
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006344bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6345{
6346 if (!context->getExtensions().fence)
6347 {
6348 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6349 return false;
6350 }
6351
6352 if (n < 0)
6353 {
6354 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6355 return false;
6356 }
6357
6358 return true;
6359}
6360
6361bool ValidateFinishFenceNV(Context *context, GLuint fence)
6362{
6363 if (!context->getExtensions().fence)
6364 {
6365 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6366 return false;
6367 }
6368
6369 FenceNV *fenceObject = context->getFenceNV(fence);
6370
6371 if (fenceObject == nullptr)
6372 {
6373 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6374 return false;
6375 }
6376
6377 if (!fenceObject->isSet())
6378 {
6379 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6380 return false;
6381 }
6382
6383 return true;
6384}
6385
6386bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6387{
6388 if (!context->getExtensions().fence)
6389 {
6390 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6391 return false;
6392 }
6393
6394 if (n < 0)
6395 {
6396 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6397 return false;
6398 }
6399
6400 return true;
6401}
6402
6403bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6404{
6405 if (!context->getExtensions().fence)
6406 {
6407 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6408 return false;
6409 }
6410
6411 FenceNV *fenceObject = context->getFenceNV(fence);
6412
6413 if (fenceObject == nullptr)
6414 {
6415 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6416 return false;
6417 }
6418
6419 if (!fenceObject->isSet())
6420 {
6421 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6422 return false;
6423 }
6424
6425 switch (pname)
6426 {
6427 case GL_FENCE_STATUS_NV:
6428 case GL_FENCE_CONDITION_NV:
6429 break;
6430
6431 default:
6432 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6433 return false;
6434 }
6435
6436 return true;
6437}
6438
6439bool ValidateGetGraphicsResetStatusEXT(Context *context)
6440{
6441 if (!context->getExtensions().robustness)
6442 {
6443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6444 return false;
6445 }
6446
6447 return true;
6448}
6449
6450bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6451 GLuint shader,
6452 GLsizei bufsize,
6453 GLsizei *length,
6454 GLchar *source)
6455{
6456 if (!context->getExtensions().translatedShaderSource)
6457 {
6458 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6459 return false;
6460 }
6461
6462 if (bufsize < 0)
6463 {
6464 context->handleError(InvalidValue());
6465 return false;
6466 }
6467
6468 Shader *shaderObject = context->getShader(shader);
6469
6470 if (!shaderObject)
6471 {
6472 context->handleError(InvalidOperation());
6473 return false;
6474 }
6475
6476 return true;
6477}
6478
6479bool ValidateIsFenceNV(Context *context, GLuint fence)
6480{
6481 if (!context->getExtensions().fence)
6482 {
6483 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6484 return false;
6485 }
6486
6487 return true;
6488}
6489
Jamie Madill007530e2017-12-28 14:27:04 -05006490bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6491{
6492 if (!context->getExtensions().fence)
6493 {
6494 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6495 return false;
6496 }
6497
6498 if (condition != GL_ALL_COMPLETED_NV)
6499 {
6500 context->handleError(InvalidEnum());
6501 return false;
6502 }
6503
6504 FenceNV *fenceObject = context->getFenceNV(fence);
6505
6506 if (fenceObject == nullptr)
6507 {
6508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6509 return false;
6510 }
6511
6512 return true;
6513}
6514
6515bool ValidateTestFenceNV(Context *context, GLuint fence)
6516{
6517 if (!context->getExtensions().fence)
6518 {
6519 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6520 return false;
6521 }
6522
6523 FenceNV *fenceObject = context->getFenceNV(fence);
6524
6525 if (fenceObject == nullptr)
6526 {
6527 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6528 return false;
6529 }
6530
6531 if (fenceObject->isSet() != GL_TRUE)
6532 {
6533 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6534 return false;
6535 }
6536
6537 return true;
6538}
6539
6540bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006541 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006542 GLsizei levels,
6543 GLenum internalformat,
6544 GLsizei width,
6545 GLsizei height)
6546{
6547 if (!context->getExtensions().textureStorage)
6548 {
6549 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6550 return false;
6551 }
6552
6553 if (context->getClientMajorVersion() < 3)
6554 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006555 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006556 height);
6557 }
6558
6559 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006560 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006561 1);
6562}
6563
6564bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6565{
6566 if (!context->getExtensions().instancedArrays)
6567 {
6568 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6569 return false;
6570 }
6571
6572 if (index >= MAX_VERTEX_ATTRIBS)
6573 {
6574 context->handleError(InvalidValue());
6575 return false;
6576 }
6577
6578 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6579 {
6580 if (index == 0 && divisor != 0)
6581 {
6582 const char *errorMessage =
6583 "The current context doesn't support setting a non-zero divisor on the "
6584 "attribute with index zero. "
6585 "Please reorder the attributes in your vertex shader so that attribute zero "
6586 "can have a zero divisor.";
6587 context->handleError(InvalidOperation() << errorMessage);
6588
6589 // We also output an error message to the debugger window if tracing is active, so
6590 // that developers can see the error message.
6591 ERR() << errorMessage;
6592 return false;
6593 }
6594 }
6595
6596 return true;
6597}
6598
6599bool ValidateTexImage3DOES(Context *context,
6600 GLenum target,
6601 GLint level,
6602 GLenum internalformat,
6603 GLsizei width,
6604 GLsizei height,
6605 GLsizei depth,
6606 GLint border,
6607 GLenum format,
6608 GLenum type,
6609 const void *pixels)
6610{
6611 UNIMPLEMENTED(); // FIXME
6612 return false;
6613}
6614
6615bool ValidatePopGroupMarkerEXT(Context *context)
6616{
6617 if (!context->getExtensions().debugMarker)
6618 {
6619 // The debug marker calls should not set error state
6620 // However, it seems reasonable to set an error state if the extension is not enabled
6621 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6622 return false;
6623 }
6624
6625 return true;
6626}
6627
Jamie Madillfa920eb2018-01-04 11:45:50 -05006628bool ValidateTexStorage1DEXT(Context *context,
6629 GLenum target,
6630 GLsizei levels,
6631 GLenum internalformat,
6632 GLsizei width)
6633{
6634 UNIMPLEMENTED();
6635 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6636 return false;
6637}
6638
6639bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006640 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006641 GLsizei levels,
6642 GLenum internalformat,
6643 GLsizei width,
6644 GLsizei height,
6645 GLsizei depth)
6646{
6647 if (!context->getExtensions().textureStorage)
6648 {
6649 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6650 return false;
6651 }
6652
6653 if (context->getClientMajorVersion() < 3)
6654 {
6655 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6656 return false;
6657 }
6658
6659 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6660 depth);
6661}
6662
jchen1082af6202018-06-22 10:59:52 +08006663bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6664{
6665 if (!context->getExtensions().parallelShaderCompile)
6666 {
6667 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6668 return false;
6669 }
6670 return true;
6671}
6672
Jamie Madillc29968b2016-01-20 11:17:23 -05006673} // namespace gl