blob: 0e138f6b1fce5c8e88a6825066058ce3e866c792 [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}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001050
1051bool ValidBlendFunc(const Context *context, GLenum val)
1052{
1053 const gl::Extensions &ext = context->getExtensions();
1054
1055 // these are always valid for src and dst.
1056 switch (val)
1057 {
1058 case GL_ZERO:
1059 case GL_ONE:
1060 case GL_SRC_COLOR:
1061 case GL_ONE_MINUS_SRC_COLOR:
1062 case GL_DST_COLOR:
1063 case GL_ONE_MINUS_DST_COLOR:
1064 case GL_SRC_ALPHA:
1065 case GL_ONE_MINUS_SRC_ALPHA:
1066 case GL_DST_ALPHA:
1067 case GL_ONE_MINUS_DST_ALPHA:
1068 case GL_CONSTANT_COLOR:
1069 case GL_ONE_MINUS_CONSTANT_COLOR:
1070 case GL_CONSTANT_ALPHA:
1071 case GL_ONE_MINUS_CONSTANT_ALPHA:
1072 return true;
1073
1074 // EXT_blend_func_extended.
1075 case GL_SRC1_COLOR_EXT:
1076 case GL_SRC1_ALPHA_EXT:
1077 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1078 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1079 case GL_SRC_ALPHA_SATURATE_EXT:
1080 return ext.blendFuncExtended;
1081
1082 default:
1083 return false;
1084 }
1085}
1086
1087bool ValidSrcBlendFunc(const Context *context, GLenum val)
1088{
1089 if (ValidBlendFunc(context, val))
1090 return true;
1091
1092 if (val == GL_SRC_ALPHA_SATURATE)
1093 return true;
1094
1095 return false;
1096}
1097
1098bool ValidDstBlendFunc(const Context *context, GLenum val)
1099{
1100 if (ValidBlendFunc(context, val))
1101 return true;
1102
1103 if (val == GL_SRC_ALPHA_SATURATE)
1104 {
1105 if (context->getClientMajorVersion() >= 3)
1106 return true;
1107 }
1108
1109 return false;
1110}
1111
Jamie Madillc29968b2016-01-20 11:17:23 -05001112} // anonymous namespace
1113
Geoff Langff5b2d52016-09-07 11:32:23 -04001114bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001115 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001116 GLint level,
1117 GLenum internalformat,
1118 bool isCompressed,
1119 bool isSubImage,
1120 GLint xoffset,
1121 GLint yoffset,
1122 GLsizei width,
1123 GLsizei height,
1124 GLint border,
1125 GLenum format,
1126 GLenum type,
1127 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001128 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001129{
Jamie Madill6f38f822014-06-06 17:12:20 -04001130 if (!ValidTexture2DDestinationTarget(context, target))
1131 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001132 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001133 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001134 }
1135
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001136 TextureType texType = TextureTargetToType(target);
1137 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001139 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001140 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001141 }
1142
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001143 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001144 {
1145 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1146 return false;
1147 }
1148
1149 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001150 std::numeric_limits<GLsizei>::max() - yoffset < height)
1151 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001152 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001153 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001154 }
1155
Geoff Lang6e898aa2017-06-02 11:17:26 -04001156 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1157 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1158 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1159 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1160 // case.
1161 bool nonEqualFormatsAllowed =
1162 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1163 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1164
1165 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001166 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001167 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001168 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001169 }
1170
Geoff Langaae65a42014-05-26 12:43:44 -04001171 const gl::Caps &caps = context->getCaps();
1172
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001173 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001174 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001175 case TextureType::_2D:
1176 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1177 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1178 {
1179 context->handleError(InvalidValue());
1180 return false;
1181 }
1182 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001183
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001184 case TextureType::Rectangle:
1185 ASSERT(level == 0);
1186 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1187 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1188 {
1189 context->handleError(InvalidValue());
1190 return false;
1191 }
1192 if (isCompressed)
1193 {
1194 context->handleError(InvalidEnum()
1195 << "Rectangle texture cannot have a compressed format.");
1196 return false;
1197 }
1198 break;
1199
1200 case TextureType::CubeMap:
1201 if (!isSubImage && width != height)
1202 {
1203 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1204 return false;
1205 }
1206
1207 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1208 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1209 {
1210 context->handleError(InvalidValue());
1211 return false;
1212 }
1213 break;
1214
1215 default:
1216 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001217 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001218 }
1219
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001220 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001221 if (!texture)
1222 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001223 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001224 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001225 }
1226
Geoff Langa9be0dc2014-12-17 12:34:40 -05001227 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001228 {
Geoff Langca271392017-04-05 12:30:00 -04001229 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1230 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001231 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001232 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001233 return false;
1234 }
1235
Geoff Langa9be0dc2014-12-17 12:34:40 -05001236 if (format != GL_NONE)
1237 {
Geoff Langca271392017-04-05 12:30:00 -04001238 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1239 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001240 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001241 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001242 return false;
1243 }
1244 }
1245
1246 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1247 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1248 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001249 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001250 return false;
1251 }
Geoff Langfb052642017-10-24 13:42:09 -04001252
1253 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001254 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001255 {
1256 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1257 return false;
1258 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001259 }
1260 else
1261 {
Geoff Lang69cce582015-09-17 13:20:36 -04001262 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001263 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001264 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001265 return false;
1266 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001267 }
1268
1269 // Verify zero border
1270 if (border != 0)
1271 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001272 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001273 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001274 }
1275
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001276 if (isCompressed)
1277 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001278 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001279 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1280 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001281
1282 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1283
1284 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001285 {
Geoff Lange88e4542018-05-03 15:05:57 -04001286 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1287 return false;
1288 }
1289
1290 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1291 context->getExtensions()))
1292 {
1293 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1294 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001295 }
Geoff Lang966c9402017-04-18 12:38:27 -04001296
1297 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001298 {
Geoff Lange88e4542018-05-03 15:05:57 -04001299 // From the OES_compressed_ETC1_RGB8_texture spec:
1300 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1301 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1302 // ETC1_RGB8_OES.
1303 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1304 {
1305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1306 return false;
1307 }
1308
Geoff Lang966c9402017-04-18 12:38:27 -04001309 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1310 height, texture->getWidth(target, level),
1311 texture->getHeight(target, level)))
1312 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001313 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001314 return false;
1315 }
1316
1317 if (format != actualInternalFormat)
1318 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001319 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001320 return false;
1321 }
1322 }
1323 else
1324 {
1325 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1326 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001327 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001328 return false;
1329 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001330 }
1331 }
1332 else
1333 {
1334 // validate <type> by itself (used as secondary key below)
1335 switch (type)
1336 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001337 case GL_UNSIGNED_BYTE:
1338 case GL_UNSIGNED_SHORT_5_6_5:
1339 case GL_UNSIGNED_SHORT_4_4_4_4:
1340 case GL_UNSIGNED_SHORT_5_5_5_1:
1341 case GL_UNSIGNED_SHORT:
1342 case GL_UNSIGNED_INT:
1343 case GL_UNSIGNED_INT_24_8_OES:
1344 case GL_HALF_FLOAT_OES:
1345 case GL_FLOAT:
1346 break;
1347 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001348 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001349 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001350 }
1351
1352 // validate <format> + <type> combinations
1353 // - invalid <format> -> sets INVALID_ENUM
1354 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1355 switch (format)
1356 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001357 case GL_ALPHA:
1358 case GL_LUMINANCE:
1359 case GL_LUMINANCE_ALPHA:
1360 switch (type)
1361 {
1362 case GL_UNSIGNED_BYTE:
1363 case GL_FLOAT:
1364 case GL_HALF_FLOAT_OES:
1365 break;
1366 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001367 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001368 return false;
1369 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001370 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001371 case GL_RED:
1372 case GL_RG:
1373 if (!context->getExtensions().textureRG)
1374 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001375 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001376 return false;
1377 }
1378 switch (type)
1379 {
1380 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001381 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001382 case GL_FLOAT:
1383 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001384 if (!context->getExtensions().textureFloat)
1385 {
1386 context->handleError(InvalidEnum());
1387 return false;
1388 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001389 break;
1390 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001391 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001392 return false;
1393 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001394 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001395 case GL_RGB:
1396 switch (type)
1397 {
1398 case GL_UNSIGNED_BYTE:
1399 case GL_UNSIGNED_SHORT_5_6_5:
1400 case GL_FLOAT:
1401 case GL_HALF_FLOAT_OES:
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 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001407 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001408 case GL_RGBA:
1409 switch (type)
1410 {
1411 case GL_UNSIGNED_BYTE:
1412 case GL_UNSIGNED_SHORT_4_4_4_4:
1413 case GL_UNSIGNED_SHORT_5_5_5_1:
1414 case GL_FLOAT:
1415 case GL_HALF_FLOAT_OES:
1416 break;
1417 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001418 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001419 return false;
1420 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001421 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001422 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001423 if (!context->getExtensions().textureFormatBGRA8888)
1424 {
1425 context->handleError(InvalidEnum());
1426 return false;
1427 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001428 switch (type)
1429 {
1430 case GL_UNSIGNED_BYTE:
1431 break;
1432 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001433 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001434 return false;
1435 }
1436 break;
1437 case GL_SRGB_EXT:
1438 case GL_SRGB_ALPHA_EXT:
1439 if (!context->getExtensions().sRGB)
1440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001441 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001442 return false;
1443 }
1444 switch (type)
1445 {
1446 case GL_UNSIGNED_BYTE:
1447 break;
1448 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001449 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001450 return false;
1451 }
1452 break;
1453 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1454 // handled below
1455 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1456 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1457 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1458 break;
1459 case GL_DEPTH_COMPONENT:
1460 switch (type)
1461 {
1462 case GL_UNSIGNED_SHORT:
1463 case GL_UNSIGNED_INT:
1464 break;
1465 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001466 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 return false;
1468 }
1469 break;
1470 case GL_DEPTH_STENCIL_OES:
1471 switch (type)
1472 {
1473 case GL_UNSIGNED_INT_24_8_OES:
1474 break;
1475 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001477 return false;
1478 }
1479 break;
1480 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001481 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001482 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001483 }
1484
1485 switch (format)
1486 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1488 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1489 if (context->getExtensions().textureCompressionDXT1)
1490 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001491 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001492 return false;
1493 }
1494 else
1495 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001496 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 return false;
1498 }
1499 break;
1500 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1501 if (context->getExtensions().textureCompressionDXT3)
1502 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001503 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001504 return false;
1505 }
1506 else
1507 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001508 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001509 return false;
1510 }
1511 break;
1512 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1513 if (context->getExtensions().textureCompressionDXT5)
1514 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001515 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001516 return false;
1517 }
1518 else
1519 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001520 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001521 return false;
1522 }
1523 break;
1524 case GL_ETC1_RGB8_OES:
1525 if (context->getExtensions().compressedETC1RGB8Texture)
1526 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001527 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001528 return false;
1529 }
1530 else
1531 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001532 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001533 return false;
1534 }
1535 break;
1536 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001537 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1538 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1539 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1540 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001541 if (context->getExtensions().lossyETCDecode)
1542 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001543 context->handleError(InvalidOperation()
1544 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001545 return false;
1546 }
1547 else
1548 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001549 context->handleError(InvalidEnum()
1550 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001551 return false;
1552 }
1553 break;
1554 case GL_DEPTH_COMPONENT:
1555 case GL_DEPTH_STENCIL_OES:
1556 if (!context->getExtensions().depthTextures)
1557 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001558 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001559 return false;
1560 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001561 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001562 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001563 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001564 return false;
1565 }
1566 // OES_depth_texture supports loading depth data and multiple levels,
1567 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001568 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001569 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001570 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1571 return false;
1572 }
1573 if (level != 0)
1574 {
1575 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001576 return false;
1577 }
1578 break;
1579 default:
1580 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001581 }
1582
Geoff Lang6e898aa2017-06-02 11:17:26 -04001583 if (!isSubImage)
1584 {
1585 switch (internalformat)
1586 {
1587 case GL_RGBA32F:
1588 if (!context->getExtensions().colorBufferFloatRGBA)
1589 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001590 context->handleError(InvalidValue()
1591 << "Sized GL_RGBA32F internal format requires "
1592 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001593 return false;
1594 }
1595 if (type != GL_FLOAT)
1596 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001597 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001598 return false;
1599 }
1600 if (format != GL_RGBA)
1601 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001602 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001603 return false;
1604 }
1605 break;
1606
1607 case GL_RGB32F:
1608 if (!context->getExtensions().colorBufferFloatRGB)
1609 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001610 context->handleError(InvalidValue()
1611 << "Sized GL_RGB32F internal format requires "
1612 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001613 return false;
1614 }
1615 if (type != GL_FLOAT)
1616 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001617 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001618 return false;
1619 }
1620 if (format != GL_RGB)
1621 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001622 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001623 return false;
1624 }
1625 break;
1626
1627 default:
1628 break;
1629 }
1630 }
1631
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001632 if (type == GL_FLOAT)
1633 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001634 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001635 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001636 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001637 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001638 }
1639 }
1640 else if (type == GL_HALF_FLOAT_OES)
1641 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001642 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001643 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001644 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001645 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001646 }
1647 }
1648 }
1649
Geoff Langdbcced82017-06-06 15:55:54 -04001650 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001651 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001652 imageSize))
1653 {
1654 return false;
1655 }
1656
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001657 return true;
1658}
1659
He Yunchaoced53ae2016-11-29 15:00:51 +08001660bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001661 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001662 GLsizei levels,
1663 GLenum internalformat,
1664 GLsizei width,
1665 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001666{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001667 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1668 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001669 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001670 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001671 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001672 }
1673
1674 if (width < 1 || height < 1 || levels < 1)
1675 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001676 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001677 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001678 }
1679
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001680 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001681 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001682 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001683 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001684 }
1685
1686 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1687 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001688 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001689 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001690 }
1691
Geoff Langca271392017-04-05 12:30:00 -04001692 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001693 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001694 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001695 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001696 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001697 }
1698
Geoff Langaae65a42014-05-26 12:43:44 -04001699 const gl::Caps &caps = context->getCaps();
1700
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001701 switch (target)
1702 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001703 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001704 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1705 static_cast<GLuint>(height) > caps.max2DTextureSize)
1706 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001707 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001708 return false;
1709 }
1710 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001711 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001712 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1713 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1714 {
1715 context->handleError(InvalidValue());
1716 return false;
1717 }
1718 if (formatInfo.compressed)
1719 {
1720 context->handleError(InvalidEnum()
1721 << "Rectangle texture cannot have a compressed format.");
1722 return false;
1723 }
1724 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001725 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001726 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1727 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1728 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001729 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001730 return false;
1731 }
1732 break;
1733 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001734 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001735 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001736 }
1737
Geoff Langc0b9ef42014-07-02 10:02:37 -04001738 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001739 {
1740 if (!gl::isPow2(width) || !gl::isPow2(height))
1741 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001742 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001743 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001744 }
1745 }
1746
1747 switch (internalformat)
1748 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001749 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1750 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1751 if (!context->getExtensions().textureCompressionDXT1)
1752 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001753 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001754 return false;
1755 }
1756 break;
1757 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1758 if (!context->getExtensions().textureCompressionDXT3)
1759 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001760 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001761 return false;
1762 }
1763 break;
1764 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1765 if (!context->getExtensions().textureCompressionDXT5)
1766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001767 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001768 return false;
1769 }
1770 break;
1771 case GL_ETC1_RGB8_OES:
1772 if (!context->getExtensions().compressedETC1RGB8Texture)
1773 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001774 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001775 return false;
1776 }
1777 break;
1778 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001779 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1780 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1781 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1782 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001783 if (!context->getExtensions().lossyETCDecode)
1784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001785 context->handleError(InvalidEnum()
1786 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001787 return false;
1788 }
1789 break;
1790 case GL_RGBA32F_EXT:
1791 case GL_RGB32F_EXT:
1792 case GL_ALPHA32F_EXT:
1793 case GL_LUMINANCE32F_EXT:
1794 case GL_LUMINANCE_ALPHA32F_EXT:
1795 if (!context->getExtensions().textureFloat)
1796 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001797 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001798 return false;
1799 }
1800 break;
1801 case GL_RGBA16F_EXT:
1802 case GL_RGB16F_EXT:
1803 case GL_ALPHA16F_EXT:
1804 case GL_LUMINANCE16F_EXT:
1805 case GL_LUMINANCE_ALPHA16F_EXT:
1806 if (!context->getExtensions().textureHalfFloat)
1807 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001808 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001809 return false;
1810 }
1811 break;
1812 case GL_R8_EXT:
1813 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001814 if (!context->getExtensions().textureRG)
1815 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001816 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001817 return false;
1818 }
1819 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001820 case GL_R16F_EXT:
1821 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001822 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1823 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001824 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001825 return false;
1826 }
1827 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001828 case GL_R32F_EXT:
1829 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001830 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001831 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001832 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001833 return false;
1834 }
1835 break;
1836 case GL_DEPTH_COMPONENT16:
1837 case GL_DEPTH_COMPONENT32_OES:
1838 case GL_DEPTH24_STENCIL8_OES:
1839 if (!context->getExtensions().depthTextures)
1840 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001841 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001842 return false;
1843 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001844 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001845 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001846 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001847 return false;
1848 }
1849 // ANGLE_depth_texture only supports 1-level textures
1850 if (levels != 1)
1851 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001852 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001853 return false;
1854 }
1855 break;
1856 default:
1857 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001858 }
1859
Geoff Lang691e58c2014-12-19 17:03:25 -05001860 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001861 if (!texture || texture->id() == 0)
1862 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001863 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001864 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001865 }
1866
Geoff Lang69cce582015-09-17 13:20:36 -04001867 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001869 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001870 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001871 }
1872
1873 return true;
1874}
1875
He Yunchaoced53ae2016-11-29 15:00:51 +08001876bool ValidateDiscardFramebufferEXT(Context *context,
1877 GLenum target,
1878 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001879 const GLenum *attachments)
1880{
Jamie Madillc29968b2016-01-20 11:17:23 -05001881 if (!context->getExtensions().discardFramebuffer)
1882 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001883 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001884 return false;
1885 }
1886
Austin Kinross08332632015-05-05 13:35:47 -07001887 bool defaultFramebuffer = false;
1888
1889 switch (target)
1890 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001891 case GL_FRAMEBUFFER:
1892 defaultFramebuffer =
1893 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1894 break;
1895 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001896 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001897 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001898 }
1899
He Yunchaoced53ae2016-11-29 15:00:51 +08001900 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1901 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001902}
1903
Austin Kinrossbc781f32015-10-26 09:27:38 -07001904bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1905{
1906 if (!context->getExtensions().vertexArrayObject)
1907 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001908 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001909 return false;
1910 }
1911
1912 return ValidateBindVertexArrayBase(context, array);
1913}
1914
Jamie Madilld7576732017-08-26 18:49:50 -04001915bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001916{
1917 if (!context->getExtensions().vertexArrayObject)
1918 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001919 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001920 return false;
1921 }
1922
Olli Etuaho41997e72016-03-10 13:38:39 +02001923 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001924}
1925
Jamie Madilld7576732017-08-26 18:49:50 -04001926bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001927{
1928 if (!context->getExtensions().vertexArrayObject)
1929 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001930 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001931 return false;
1932 }
1933
Olli Etuaho41997e72016-03-10 13:38:39 +02001934 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001935}
1936
Jamie Madilld7576732017-08-26 18:49:50 -04001937bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001938{
1939 if (!context->getExtensions().vertexArrayObject)
1940 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001941 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001942 return false;
1943 }
1944
1945 return true;
1946}
Geoff Langc5629752015-12-07 16:29:04 -05001947
1948bool ValidateProgramBinaryOES(Context *context,
1949 GLuint program,
1950 GLenum binaryFormat,
1951 const void *binary,
1952 GLint length)
1953{
1954 if (!context->getExtensions().getProgramBinary)
1955 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001956 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001957 return false;
1958 }
1959
1960 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1961}
1962
1963bool ValidateGetProgramBinaryOES(Context *context,
1964 GLuint program,
1965 GLsizei bufSize,
1966 GLsizei *length,
1967 GLenum *binaryFormat,
1968 void *binary)
1969{
1970 if (!context->getExtensions().getProgramBinary)
1971 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001972 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001973 return false;
1974 }
1975
1976 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1977}
Geoff Lange102fee2015-12-10 11:23:30 -05001978
Geoff Lang70d0f492015-12-10 17:45:46 -05001979static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1980{
1981 switch (source)
1982 {
1983 case GL_DEBUG_SOURCE_API:
1984 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1985 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1986 case GL_DEBUG_SOURCE_OTHER:
1987 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1988 return !mustBeThirdPartyOrApplication;
1989
1990 case GL_DEBUG_SOURCE_THIRD_PARTY:
1991 case GL_DEBUG_SOURCE_APPLICATION:
1992 return true;
1993
1994 default:
1995 return false;
1996 }
1997}
1998
1999static bool ValidDebugType(GLenum type)
2000{
2001 switch (type)
2002 {
2003 case GL_DEBUG_TYPE_ERROR:
2004 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2005 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2006 case GL_DEBUG_TYPE_PERFORMANCE:
2007 case GL_DEBUG_TYPE_PORTABILITY:
2008 case GL_DEBUG_TYPE_OTHER:
2009 case GL_DEBUG_TYPE_MARKER:
2010 case GL_DEBUG_TYPE_PUSH_GROUP:
2011 case GL_DEBUG_TYPE_POP_GROUP:
2012 return true;
2013
2014 default:
2015 return false;
2016 }
2017}
2018
2019static bool ValidDebugSeverity(GLenum severity)
2020{
2021 switch (severity)
2022 {
2023 case GL_DEBUG_SEVERITY_HIGH:
2024 case GL_DEBUG_SEVERITY_MEDIUM:
2025 case GL_DEBUG_SEVERITY_LOW:
2026 case GL_DEBUG_SEVERITY_NOTIFICATION:
2027 return true;
2028
2029 default:
2030 return false;
2031 }
2032}
2033
Geoff Lange102fee2015-12-10 11:23:30 -05002034bool ValidateDebugMessageControlKHR(Context *context,
2035 GLenum source,
2036 GLenum type,
2037 GLenum severity,
2038 GLsizei count,
2039 const GLuint *ids,
2040 GLboolean enabled)
2041{
2042 if (!context->getExtensions().debug)
2043 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002044 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002045 return false;
2046 }
2047
Geoff Lang70d0f492015-12-10 17:45:46 -05002048 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2049 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002051 return false;
2052 }
2053
2054 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2055 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002056 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002057 return false;
2058 }
2059
2060 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2061 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002062 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002063 return false;
2064 }
2065
2066 if (count > 0)
2067 {
2068 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2069 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002070 context->handleError(
2071 InvalidOperation()
2072 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002073 return false;
2074 }
2075
2076 if (severity != GL_DONT_CARE)
2077 {
Jamie Madill437fa652016-05-03 15:13:24 -04002078 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002079 InvalidOperation()
2080 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002081 return false;
2082 }
2083 }
2084
Geoff Lange102fee2015-12-10 11:23:30 -05002085 return true;
2086}
2087
2088bool ValidateDebugMessageInsertKHR(Context *context,
2089 GLenum source,
2090 GLenum type,
2091 GLuint id,
2092 GLenum severity,
2093 GLsizei length,
2094 const GLchar *buf)
2095{
2096 if (!context->getExtensions().debug)
2097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002098 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002099 return false;
2100 }
2101
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002102 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002103 {
2104 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2105 // not generate an error.
2106 return false;
2107 }
2108
2109 if (!ValidDebugSeverity(severity))
2110 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002111 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002112 return false;
2113 }
2114
2115 if (!ValidDebugType(type))
2116 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002117 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002118 return false;
2119 }
2120
2121 if (!ValidDebugSource(source, true))
2122 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002123 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002124 return false;
2125 }
2126
2127 size_t messageLength = (length < 0) ? strlen(buf) : length;
2128 if (messageLength > context->getExtensions().maxDebugMessageLength)
2129 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002130 context->handleError(InvalidValue()
2131 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002132 return false;
2133 }
2134
Geoff Lange102fee2015-12-10 11:23:30 -05002135 return true;
2136}
2137
2138bool ValidateDebugMessageCallbackKHR(Context *context,
2139 GLDEBUGPROCKHR callback,
2140 const void *userParam)
2141{
2142 if (!context->getExtensions().debug)
2143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002145 return false;
2146 }
2147
Geoff Lange102fee2015-12-10 11:23:30 -05002148 return true;
2149}
2150
2151bool ValidateGetDebugMessageLogKHR(Context *context,
2152 GLuint count,
2153 GLsizei bufSize,
2154 GLenum *sources,
2155 GLenum *types,
2156 GLuint *ids,
2157 GLenum *severities,
2158 GLsizei *lengths,
2159 GLchar *messageLog)
2160{
2161 if (!context->getExtensions().debug)
2162 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002163 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002164 return false;
2165 }
2166
Geoff Lang70d0f492015-12-10 17:45:46 -05002167 if (bufSize < 0 && messageLog != nullptr)
2168 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002169 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002170 return false;
2171 }
2172
Geoff Lange102fee2015-12-10 11:23:30 -05002173 return true;
2174}
2175
2176bool ValidatePushDebugGroupKHR(Context *context,
2177 GLenum source,
2178 GLuint id,
2179 GLsizei length,
2180 const GLchar *message)
2181{
2182 if (!context->getExtensions().debug)
2183 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002184 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002185 return false;
2186 }
2187
Geoff Lang70d0f492015-12-10 17:45:46 -05002188 if (!ValidDebugSource(source, true))
2189 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002190 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002191 return false;
2192 }
2193
2194 size_t messageLength = (length < 0) ? strlen(message) : length;
2195 if (messageLength > context->getExtensions().maxDebugMessageLength)
2196 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002197 context->handleError(InvalidValue()
2198 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 return false;
2200 }
2201
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002202 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002203 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002205 context
2206 ->handleError(StackOverflow()
2207 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002208 return false;
2209 }
2210
Geoff Lange102fee2015-12-10 11:23:30 -05002211 return true;
2212}
2213
2214bool ValidatePopDebugGroupKHR(Context *context)
2215{
2216 if (!context->getExtensions().debug)
2217 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002218 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002219 return false;
2220 }
2221
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002222 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002223 if (currentStackSize <= 1)
2224 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002225 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002226 return false;
2227 }
2228
2229 return true;
2230}
2231
2232static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2233{
2234 switch (identifier)
2235 {
2236 case GL_BUFFER:
2237 if (context->getBuffer(name) == nullptr)
2238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002239 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002240 return false;
2241 }
2242 return true;
2243
2244 case GL_SHADER:
2245 if (context->getShader(name) == nullptr)
2246 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002247 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002248 return false;
2249 }
2250 return true;
2251
2252 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002253 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002254 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002255 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002256 return false;
2257 }
2258 return true;
2259
2260 case GL_VERTEX_ARRAY:
2261 if (context->getVertexArray(name) == nullptr)
2262 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002263 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002264 return false;
2265 }
2266 return true;
2267
2268 case GL_QUERY:
2269 if (context->getQuery(name) == nullptr)
2270 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002271 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002272 return false;
2273 }
2274 return true;
2275
2276 case GL_TRANSFORM_FEEDBACK:
2277 if (context->getTransformFeedback(name) == nullptr)
2278 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002279 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002280 return false;
2281 }
2282 return true;
2283
2284 case GL_SAMPLER:
2285 if (context->getSampler(name) == nullptr)
2286 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002287 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002288 return false;
2289 }
2290 return true;
2291
2292 case GL_TEXTURE:
2293 if (context->getTexture(name) == nullptr)
2294 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002295 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002296 return false;
2297 }
2298 return true;
2299
2300 case GL_RENDERBUFFER:
2301 if (context->getRenderbuffer(name) == nullptr)
2302 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002303 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002304 return false;
2305 }
2306 return true;
2307
2308 case GL_FRAMEBUFFER:
2309 if (context->getFramebuffer(name) == nullptr)
2310 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002311 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002312 return false;
2313 }
2314 return true;
2315
2316 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002317 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002318 return false;
2319 }
Geoff Lange102fee2015-12-10 11:23:30 -05002320}
2321
Martin Radev9d901792016-07-15 15:58:58 +03002322static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2323{
2324 size_t labelLength = 0;
2325
2326 if (length < 0)
2327 {
2328 if (label != nullptr)
2329 {
2330 labelLength = strlen(label);
2331 }
2332 }
2333 else
2334 {
2335 labelLength = static_cast<size_t>(length);
2336 }
2337
2338 if (labelLength > context->getExtensions().maxLabelLength)
2339 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002340 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002341 return false;
2342 }
2343
2344 return true;
2345}
2346
Geoff Lange102fee2015-12-10 11:23:30 -05002347bool ValidateObjectLabelKHR(Context *context,
2348 GLenum identifier,
2349 GLuint name,
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 (!ValidateObjectIdentifierAndName(context, identifier, name))
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 ValidateGetObjectLabelKHR(Context *context,
2373 GLenum identifier,
2374 GLuint name,
2375 GLsizei bufSize,
2376 GLsizei *length,
2377 GLchar *label)
2378{
2379 if (!context->getExtensions().debug)
2380 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002382 return false;
2383 }
2384
Geoff Lang70d0f492015-12-10 17:45:46 -05002385 if (bufSize < 0)
2386 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002387 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002388 return false;
2389 }
2390
2391 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2392 {
2393 return false;
2394 }
2395
Martin Radev9d901792016-07-15 15:58:58 +03002396 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002397}
2398
2399static bool ValidateObjectPtrName(Context *context, const void *ptr)
2400{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002401 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002402 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002403 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002404 return false;
2405 }
2406
Geoff Lange102fee2015-12-10 11:23:30 -05002407 return true;
2408}
2409
2410bool ValidateObjectPtrLabelKHR(Context *context,
2411 const void *ptr,
2412 GLsizei length,
2413 const GLchar *label)
2414{
2415 if (!context->getExtensions().debug)
2416 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002417 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002418 return false;
2419 }
2420
Geoff Lang70d0f492015-12-10 17:45:46 -05002421 if (!ValidateObjectPtrName(context, ptr))
2422 {
2423 return false;
2424 }
2425
Martin Radev9d901792016-07-15 15:58:58 +03002426 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002427 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002428 return false;
2429 }
2430
Geoff Lange102fee2015-12-10 11:23:30 -05002431 return true;
2432}
2433
2434bool ValidateGetObjectPtrLabelKHR(Context *context,
2435 const void *ptr,
2436 GLsizei bufSize,
2437 GLsizei *length,
2438 GLchar *label)
2439{
2440 if (!context->getExtensions().debug)
2441 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002442 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002443 return false;
2444 }
2445
Geoff Lang70d0f492015-12-10 17:45:46 -05002446 if (bufSize < 0)
2447 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002448 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002449 return false;
2450 }
2451
2452 if (!ValidateObjectPtrName(context, ptr))
2453 {
2454 return false;
2455 }
2456
Martin Radev9d901792016-07-15 15:58:58 +03002457 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002458}
2459
2460bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2461{
2462 if (!context->getExtensions().debug)
2463 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002464 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002465 return false;
2466 }
2467
Geoff Lang70d0f492015-12-10 17:45:46 -05002468 // TODO: represent this in Context::getQueryParameterInfo.
2469 switch (pname)
2470 {
2471 case GL_DEBUG_CALLBACK_FUNCTION:
2472 case GL_DEBUG_CALLBACK_USER_PARAM:
2473 break;
2474
2475 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002476 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002477 return false;
2478 }
2479
Geoff Lange102fee2015-12-10 11:23:30 -05002480 return true;
2481}
Jamie Madillc29968b2016-01-20 11:17:23 -05002482
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002483bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2484 GLenum pname,
2485 GLsizei bufSize,
2486 GLsizei *length,
2487 void **params)
2488{
2489 UNIMPLEMENTED();
2490 return false;
2491}
2492
Jamie Madillc29968b2016-01-20 11:17:23 -05002493bool ValidateBlitFramebufferANGLE(Context *context,
2494 GLint srcX0,
2495 GLint srcY0,
2496 GLint srcX1,
2497 GLint srcY1,
2498 GLint dstX0,
2499 GLint dstY0,
2500 GLint dstX1,
2501 GLint dstY1,
2502 GLbitfield mask,
2503 GLenum filter)
2504{
2505 if (!context->getExtensions().framebufferBlit)
2506 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002508 return false;
2509 }
2510
2511 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2512 {
2513 // TODO(jmadill): Determine if this should be available on other implementations.
Olli Etuahof0e3c192018-08-15 13:37:21 +03002514 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002515 return false;
2516 }
2517
2518 if (filter == GL_LINEAR)
2519 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002520 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002521 return false;
2522 }
2523
Jamie Madill51f40ec2016-06-15 14:06:00 -04002524 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2525 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002526
2527 if (mask & GL_COLOR_BUFFER_BIT)
2528 {
2529 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2530 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2531
2532 if (readColorAttachment && drawColorAttachment)
2533 {
2534 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002535 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002536 readColorAttachment->type() != GL_RENDERBUFFER &&
2537 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2538 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002539 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2540 BlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002541 return false;
2542 }
2543
Geoff Langa15472a2015-08-11 11:48:03 -04002544 for (size_t drawbufferIdx = 0;
2545 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002546 {
Geoff Langa15472a2015-08-11 11:48:03 -04002547 const FramebufferAttachment *attachment =
2548 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2549 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002550 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002551 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002552 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002553 attachment->type() != GL_RENDERBUFFER &&
2554 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2555 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002556 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2557 BlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002558 return false;
2559 }
2560
2561 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002562 if (!Format::EquivalentForBlit(attachment->getFormat(),
2563 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002564 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002565 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2566 BlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002567 return false;
2568 }
2569 }
2570 }
2571
Jamie Madill427064d2018-04-13 16:20:34 -04002572 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002573 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002574 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2575 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2576 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002577 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2578 BlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002579 return false;
2580 }
2581 }
2582 }
2583
2584 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2585 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2586 for (size_t i = 0; i < 2; i++)
2587 {
2588 if (mask & masks[i])
2589 {
2590 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002591 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002592 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002593 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002594
2595 if (readBuffer && drawBuffer)
2596 {
2597 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2598 dstX0, dstY0, dstX1, dstY1))
2599 {
2600 // only whole-buffer copies are permitted
Olli Etuahof0e3c192018-08-15 13:37:21 +03002601 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2602 BlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002603 return false;
2604 }
2605
2606 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2607 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002608 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2609 BlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002610 return false;
2611 }
2612 }
2613 }
2614 }
2615
2616 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2617 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002618}
Jamie Madillc29968b2016-01-20 11:17:23 -05002619
Jamie Madill5b772312018-03-08 20:28:32 -05002620bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002621{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002622 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002623 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002624
Jamie Madill427064d2018-04-13 16:20:34 -04002625 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002626 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002627 return false;
2628 }
2629
2630 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2631 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002632 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002633 return false;
2634 }
2635
Olli Etuaho94c91a92018-07-19 15:10:24 +03002636 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002637 {
2638 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2639 GL_SIGNED_NORMALIZED};
2640
Corentin Wallez59c41592017-07-11 13:19:54 -04002641 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002642 drawBufferIdx++)
2643 {
2644 if (!ValidateWebGLFramebufferAttachmentClearType(
2645 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2646 {
2647 return false;
2648 }
2649 }
2650 }
2651
Olli Etuaho94c91a92018-07-19 15:10:24 +03002652 if (extensions.multiview && extensions.disjointTimerQuery)
2653 {
2654 const State &state = context->getGLState();
2655 Framebuffer *framebuffer = state.getDrawFramebuffer();
2656 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2657 {
2658 context->handleError(InvalidOperation() << "There is an active query for target "
2659 "GL_TIME_ELAPSED_EXT when the number of "
2660 "views in the active draw framebuffer is "
2661 "greater than 1.");
2662 return false;
2663 }
2664 }
2665
Jamie Madillc29968b2016-01-20 11:17:23 -05002666 return true;
2667}
2668
Jamie Madill5b772312018-03-08 20:28:32 -05002669bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002670{
2671 if (!context->getExtensions().drawBuffers)
2672 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002673 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002674 return false;
2675 }
2676
2677 return ValidateDrawBuffersBase(context, n, bufs);
2678}
2679
Jamie Madill73a84962016-02-12 09:27:23 -05002680bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002681 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002682 GLint level,
2683 GLint internalformat,
2684 GLsizei width,
2685 GLsizei height,
2686 GLint border,
2687 GLenum format,
2688 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002689 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002690{
Martin Radev1be913c2016-07-11 17:59:16 +03002691 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002692 {
2693 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002694 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002695 }
2696
Martin Radev1be913c2016-07-11 17:59:16 +03002697 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002698 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002699 0, 0, width, height, 1, border, format, type, -1,
2700 pixels);
2701}
2702
Brandon Jones416aaf92018-04-10 08:10:16 -07002703bool ValidateTexImage2DRobustANGLE(Context *context,
2704 TextureTarget target,
2705 GLint level,
2706 GLint internalformat,
2707 GLsizei width,
2708 GLsizei height,
2709 GLint border,
2710 GLenum format,
2711 GLenum type,
2712 GLsizei bufSize,
2713 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002714{
2715 if (!ValidateRobustEntryPoint(context, bufSize))
2716 {
2717 return false;
2718 }
2719
2720 if (context->getClientMajorVersion() < 3)
2721 {
2722 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2723 0, 0, width, height, border, format, type, bufSize,
2724 pixels);
2725 }
2726
2727 ASSERT(context->getClientMajorVersion() >= 3);
2728 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2729 0, 0, width, height, 1, border, format, type, bufSize,
2730 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002731}
2732
2733bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002734 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002735 GLint level,
2736 GLint xoffset,
2737 GLint yoffset,
2738 GLsizei width,
2739 GLsizei height,
2740 GLenum format,
2741 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002742 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002743{
2744
Martin Radev1be913c2016-07-11 17:59:16 +03002745 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002746 {
2747 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002748 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002749 }
2750
Martin Radev1be913c2016-07-11 17:59:16 +03002751 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002752 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002753 yoffset, 0, width, height, 1, 0, format, type, -1,
2754 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002755}
2756
Geoff Langc52f6f12016-10-14 10:18:00 -04002757bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002758 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002759 GLint level,
2760 GLint xoffset,
2761 GLint yoffset,
2762 GLsizei width,
2763 GLsizei height,
2764 GLenum format,
2765 GLenum type,
2766 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002767 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002768{
2769 if (!ValidateRobustEntryPoint(context, bufSize))
2770 {
2771 return false;
2772 }
2773
2774 if (context->getClientMajorVersion() < 3)
2775 {
2776 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2777 yoffset, width, height, 0, format, type, bufSize,
2778 pixels);
2779 }
2780
2781 ASSERT(context->getClientMajorVersion() >= 3);
2782 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2783 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2784 pixels);
2785}
2786
Jamie Madill73a84962016-02-12 09:27:23 -05002787bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002788 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002789 GLint level,
2790 GLenum internalformat,
2791 GLsizei width,
2792 GLsizei height,
2793 GLint border,
2794 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002795 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002796{
Martin Radev1be913c2016-07-11 17:59:16 +03002797 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002798 {
2799 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002800 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002801 {
2802 return false;
2803 }
2804 }
2805 else
2806 {
Martin Radev1be913c2016-07-11 17:59:16 +03002807 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002808 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002809 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002810 data))
2811 {
2812 return false;
2813 }
2814 }
2815
Geoff Langca271392017-04-05 12:30:00 -04002816 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002817
2818 GLuint blockSize = 0;
2819 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002820 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002821 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002822 return false;
2823 }
2824
Jamie Madillca2ff382018-07-11 09:01:17 -04002825 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002826 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002827 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002828 return false;
2829 }
2830
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002831 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002832 {
2833 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2834 return false;
2835 }
2836
Jamie Madill73a84962016-02-12 09:27:23 -05002837 return true;
2838}
2839
Corentin Wallezb2931602017-04-11 15:58:57 -04002840bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002841 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002842 GLint level,
2843 GLenum internalformat,
2844 GLsizei width,
2845 GLsizei height,
2846 GLint border,
2847 GLsizei imageSize,
2848 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002849 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002850{
2851 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2852 {
2853 return false;
2854 }
2855
2856 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2857 border, imageSize, data);
2858}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002859
Corentin Wallezb2931602017-04-11 15:58:57 -04002860bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002861 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002862 GLint level,
2863 GLint xoffset,
2864 GLint yoffset,
2865 GLsizei width,
2866 GLsizei height,
2867 GLenum format,
2868 GLsizei imageSize,
2869 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002870 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002871{
2872 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2873 {
2874 return false;
2875 }
2876
2877 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2878 format, imageSize, data);
2879}
2880
Jamie Madill73a84962016-02-12 09:27:23 -05002881bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002882 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002883 GLint level,
2884 GLint xoffset,
2885 GLint yoffset,
2886 GLsizei width,
2887 GLsizei height,
2888 GLenum format,
2889 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002890 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002891{
Martin Radev1be913c2016-07-11 17:59:16 +03002892 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002893 {
2894 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002895 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002896 {
2897 return false;
2898 }
2899 }
2900 else
2901 {
Martin Radev1be913c2016-07-11 17:59:16 +03002902 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002903 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002904 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002905 data))
2906 {
2907 return false;
2908 }
2909 }
2910
Geoff Langca271392017-04-05 12:30:00 -04002911 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002912 GLuint blockSize = 0;
2913 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002914 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002915 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002916 return false;
2917 }
2918
Jamie Madillca2ff382018-07-11 09:01:17 -04002919 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002920 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002921 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002922 return false;
2923 }
2924
2925 return true;
2926}
2927
Corentin Wallez336129f2017-10-17 15:55:40 -04002928bool ValidateGetBufferPointervOES(Context *context,
2929 BufferBinding target,
2930 GLenum pname,
2931 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002932{
Geoff Lang496c02d2016-10-20 11:38:11 -07002933 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002934}
2935
Corentin Wallez336129f2017-10-17 15:55:40 -04002936bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002937{
2938 if (!context->getExtensions().mapBuffer)
2939 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002940 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002941 return false;
2942 }
2943
Corentin Walleze4477002017-12-01 14:39:58 -05002944 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002945 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002946 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002947 return false;
2948 }
2949
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002950 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002951
2952 if (buffer == nullptr)
2953 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002954 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002955 return false;
2956 }
2957
2958 if (access != GL_WRITE_ONLY_OES)
2959 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002960 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002961 return false;
2962 }
2963
2964 if (buffer->isMapped())
2965 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002966 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002967 return false;
2968 }
2969
Geoff Lang79f71042017-08-14 16:43:43 -04002970 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002971}
2972
Corentin Wallez336129f2017-10-17 15:55:40 -04002973bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002974{
2975 if (!context->getExtensions().mapBuffer)
2976 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002977 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002978 return false;
2979 }
2980
2981 return ValidateUnmapBufferBase(context, target);
2982}
2983
2984bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002985 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002986 GLintptr offset,
2987 GLsizeiptr length,
2988 GLbitfield access)
2989{
2990 if (!context->getExtensions().mapBufferRange)
2991 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002992 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002993 return false;
2994 }
2995
2996 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2997}
2998
Corentin Wallez336129f2017-10-17 15:55:40 -04002999bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003000{
3001 Buffer *buffer = context->getGLState().getTargetBuffer(target);
3002 ASSERT(buffer != nullptr);
3003
3004 // Check if this buffer is currently being used as a transform feedback output buffer
3005 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3006 if (transformFeedback != nullptr && transformFeedback->isActive())
3007 {
3008 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3009 {
3010 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3011 if (transformFeedbackBuffer.get() == buffer)
3012 {
3013 context->handleError(InvalidOperation()
3014 << "Buffer is currently bound for transform feedback.");
3015 return false;
3016 }
3017 }
3018 }
3019
James Darpiniane8a93c62018-01-04 18:02:24 -08003020 if (context->getExtensions().webglCompatibility &&
3021 buffer->isBoundForTransformFeedbackAndOtherUse())
3022 {
3023 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
3024 return false;
3025 }
3026
Geoff Lang79f71042017-08-14 16:43:43 -04003027 return true;
3028}
3029
Olli Etuaho4f667482016-03-30 15:56:35 +03003030bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003031 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003032 GLintptr offset,
3033 GLsizeiptr length)
3034{
3035 if (!context->getExtensions().mapBufferRange)
3036 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003037 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003038 return false;
3039 }
3040
3041 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3042}
3043
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003044bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05003045{
Ian Ewell54f87462016-03-10 13:47:21 -05003046 switch (target)
3047 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003048 case TextureType::_2D:
3049 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05003050 break;
3051
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003052 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003053 if (!context->getExtensions().textureRectangle)
3054 {
3055 context->handleError(InvalidEnum()
3056 << "Context does not support GL_ANGLE_texture_rectangle");
3057 return false;
3058 }
3059 break;
3060
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003061 case TextureType::_3D:
3062 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03003063 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003064 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003065 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003066 return false;
3067 }
3068 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003069
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003070 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003071 if (context->getClientVersion() < Version(3, 1))
3072 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003073 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003074 return false;
3075 }
Geoff Lang3b573612016-10-31 14:08:10 -04003076 break;
Olli Etuahod310a432018-08-24 15:40:23 +03003077 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +03003078 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03003079 {
3080 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
3081 return false;
3082 }
3083 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003084 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003085 if (!context->getExtensions().eglImageExternal &&
3086 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003087 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003088 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003089 return false;
3090 }
3091 break;
3092 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003093 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003094 return false;
3095 }
3096
Jamie Madill0fdb9562018-09-17 17:18:43 -04003097 if (texture == 0)
3098 {
3099 return true;
3100 }
3101
3102 Texture *textureObject = context->getTexture(texture);
3103 if (textureObject && textureObject->getType() != target)
3104 {
3105 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
3106 return false;
3107 }
3108
3109 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3110 !context->isTextureGenerated(texture))
3111 {
3112 context->handleError(InvalidOperation() << "Texture was not generated");
3113 return false;
3114 }
3115
Ian Ewell54f87462016-03-10 13:47:21 -05003116 return true;
3117}
3118
Geoff Langd8605522016-04-13 10:19:12 -04003119bool ValidateBindUniformLocationCHROMIUM(Context *context,
3120 GLuint program,
3121 GLint location,
3122 const GLchar *name)
3123{
3124 if (!context->getExtensions().bindUniformLocation)
3125 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003126 context->handleError(InvalidOperation()
3127 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003128 return false;
3129 }
3130
3131 Program *programObject = GetValidProgram(context, program);
3132 if (!programObject)
3133 {
3134 return false;
3135 }
3136
3137 if (location < 0)
3138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003139 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003140 return false;
3141 }
3142
3143 const Caps &caps = context->getCaps();
3144 if (static_cast<size_t>(location) >=
3145 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3146 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003147 context->handleError(InvalidValue() << "Location must be less than "
3148 "(MAX_VERTEX_UNIFORM_VECTORS + "
3149 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003150 return false;
3151 }
3152
Geoff Langfc32e8b2017-05-31 14:16:59 -04003153 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3154 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003155 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003157 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003158 return false;
3159 }
3160
Geoff Langd8605522016-04-13 10:19:12 -04003161 if (strncmp(name, "gl_", 3) == 0)
3162 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003163 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003164 return false;
3165 }
3166
3167 return true;
3168}
3169
Jamie Madille2e406c2016-06-02 13:04:10 -04003170bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003171{
3172 if (!context->getExtensions().framebufferMixedSamples)
3173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003174 context->handleError(InvalidOperation()
3175 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003176 return false;
3177 }
3178 switch (components)
3179 {
3180 case GL_RGB:
3181 case GL_RGBA:
3182 case GL_ALPHA:
3183 case GL_NONE:
3184 break;
3185 default:
3186 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003187 InvalidEnum()
3188 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003189 return false;
3190 }
3191
3192 return true;
3193}
3194
Sami Väisänene45e53b2016-05-25 10:36:04 +03003195// CHROMIUM_path_rendering
3196
Jamie Madill007530e2017-12-28 14:27:04 -05003197bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003198{
Jamie Madill007530e2017-12-28 14:27:04 -05003199 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003200 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003201 return false;
3202 }
Jamie Madill007530e2017-12-28 14:27:04 -05003203
Sami Väisänene45e53b2016-05-25 10:36:04 +03003204 if (matrix == nullptr)
3205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003206 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003207 return false;
3208 }
Jamie Madill007530e2017-12-28 14:27:04 -05003209
Sami Väisänene45e53b2016-05-25 10:36:04 +03003210 return true;
3211}
3212
Jamie Madill007530e2017-12-28 14:27:04 -05003213bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003214{
Jamie Madill007530e2017-12-28 14:27:04 -05003215 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003216}
3217
Jamie Madill007530e2017-12-28 14:27:04 -05003218bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003219{
3220 if (!context->getExtensions().pathRendering)
3221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003222 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003223 return false;
3224 }
3225
3226 // range = 0 is undefined in NV_path_rendering.
3227 // we add stricter semantic check here and require a non zero positive range.
3228 if (range <= 0)
3229 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003230 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003231 return false;
3232 }
3233
3234 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3235 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003236 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003237 return false;
3238 }
3239
3240 return true;
3241}
3242
Jamie Madill007530e2017-12-28 14:27:04 -05003243bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003244{
3245 if (!context->getExtensions().pathRendering)
3246 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003247 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003248 return false;
3249 }
3250
3251 // range = 0 is undefined in NV_path_rendering.
3252 // we add stricter semantic check here and require a non zero positive range.
3253 if (range <= 0)
3254 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003255 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003256 return false;
3257 }
3258
3259 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3260 checkedRange += range;
3261
3262 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3263 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003264 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003265 return false;
3266 }
3267 return true;
3268}
3269
Jamie Madill007530e2017-12-28 14:27:04 -05003270bool ValidatePathCommandsCHROMIUM(Context *context,
3271 GLuint path,
3272 GLsizei numCommands,
3273 const GLubyte *commands,
3274 GLsizei numCoords,
3275 GLenum coordType,
3276 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003277{
3278 if (!context->getExtensions().pathRendering)
3279 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003280 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003281 return false;
3282 }
Brandon Jones59770802018-04-02 13:18:42 -07003283 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003284 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003285 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003286 return false;
3287 }
3288
3289 if (numCommands < 0)
3290 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003291 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003292 return false;
3293 }
3294 else if (numCommands > 0)
3295 {
3296 if (!commands)
3297 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003298 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003299 return false;
3300 }
3301 }
3302
3303 if (numCoords < 0)
3304 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003305 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003306 return false;
3307 }
3308 else if (numCoords > 0)
3309 {
3310 if (!coords)
3311 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003312 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003313 return false;
3314 }
3315 }
3316
3317 std::uint32_t coordTypeSize = 0;
3318 switch (coordType)
3319 {
3320 case GL_BYTE:
3321 coordTypeSize = sizeof(GLbyte);
3322 break;
3323
3324 case GL_UNSIGNED_BYTE:
3325 coordTypeSize = sizeof(GLubyte);
3326 break;
3327
3328 case GL_SHORT:
3329 coordTypeSize = sizeof(GLshort);
3330 break;
3331
3332 case GL_UNSIGNED_SHORT:
3333 coordTypeSize = sizeof(GLushort);
3334 break;
3335
3336 case GL_FLOAT:
3337 coordTypeSize = sizeof(GLfloat);
3338 break;
3339
3340 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003341 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003342 return false;
3343 }
3344
3345 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3346 checkedSize += (coordTypeSize * numCoords);
3347 if (!checkedSize.IsValid())
3348 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003349 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003350 return false;
3351 }
3352
3353 // early return skips command data validation when it doesn't exist.
3354 if (!commands)
3355 return true;
3356
3357 GLsizei expectedNumCoords = 0;
3358 for (GLsizei i = 0; i < numCommands; ++i)
3359 {
3360 switch (commands[i])
3361 {
3362 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3363 break;
3364 case GL_MOVE_TO_CHROMIUM:
3365 case GL_LINE_TO_CHROMIUM:
3366 expectedNumCoords += 2;
3367 break;
3368 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3369 expectedNumCoords += 4;
3370 break;
3371 case GL_CUBIC_CURVE_TO_CHROMIUM:
3372 expectedNumCoords += 6;
3373 break;
3374 case GL_CONIC_CURVE_TO_CHROMIUM:
3375 expectedNumCoords += 5;
3376 break;
3377 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003378 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003379 return false;
3380 }
3381 }
3382 if (expectedNumCoords != numCoords)
3383 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003384 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003385 return false;
3386 }
3387
3388 return true;
3389}
3390
Jamie Madill007530e2017-12-28 14:27:04 -05003391bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003392{
3393 if (!context->getExtensions().pathRendering)
3394 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003395 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003396 return false;
3397 }
Brandon Jones59770802018-04-02 13:18:42 -07003398 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003399 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003401 return false;
3402 }
3403
3404 switch (pname)
3405 {
3406 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3407 if (value < 0.0f)
3408 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003409 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003410 return false;
3411 }
3412 break;
3413 case GL_PATH_END_CAPS_CHROMIUM:
3414 switch (static_cast<GLenum>(value))
3415 {
3416 case GL_FLAT_CHROMIUM:
3417 case GL_SQUARE_CHROMIUM:
3418 case GL_ROUND_CHROMIUM:
3419 break;
3420 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003421 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003422 return false;
3423 }
3424 break;
3425 case GL_PATH_JOIN_STYLE_CHROMIUM:
3426 switch (static_cast<GLenum>(value))
3427 {
3428 case GL_MITER_REVERT_CHROMIUM:
3429 case GL_BEVEL_CHROMIUM:
3430 case GL_ROUND_CHROMIUM:
3431 break;
3432 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003433 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003434 return false;
3435 }
Nico Weber41b072b2018-02-09 10:01:32 -05003436 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003437 case GL_PATH_MITER_LIMIT_CHROMIUM:
3438 if (value < 0.0f)
3439 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003440 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003441 return false;
3442 }
3443 break;
3444
3445 case GL_PATH_STROKE_BOUND_CHROMIUM:
3446 // no errors, only clamping.
3447 break;
3448
3449 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003450 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003451 return false;
3452 }
3453 return true;
3454}
3455
Jamie Madill007530e2017-12-28 14:27:04 -05003456bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3457{
3458 // TODO(jmadill): Use proper clamping cast.
3459 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3460}
3461
3462bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003463{
3464 if (!context->getExtensions().pathRendering)
3465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003466 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003467 return false;
3468 }
3469
Brandon Jones59770802018-04-02 13:18:42 -07003470 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003472 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003473 return false;
3474 }
3475 if (!value)
3476 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003477 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003478 return false;
3479 }
3480
3481 switch (pname)
3482 {
3483 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3484 case GL_PATH_END_CAPS_CHROMIUM:
3485 case GL_PATH_JOIN_STYLE_CHROMIUM:
3486 case GL_PATH_MITER_LIMIT_CHROMIUM:
3487 case GL_PATH_STROKE_BOUND_CHROMIUM:
3488 break;
3489
3490 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003491 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003492 return false;
3493 }
3494
3495 return true;
3496}
3497
Jamie Madill007530e2017-12-28 14:27:04 -05003498bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3499{
3500 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3501 reinterpret_cast<GLfloat *>(value));
3502}
3503
3504bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003505{
3506 if (!context->getExtensions().pathRendering)
3507 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003508 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003509 return false;
3510 }
3511
3512 switch (func)
3513 {
3514 case GL_NEVER:
3515 case GL_ALWAYS:
3516 case GL_LESS:
3517 case GL_LEQUAL:
3518 case GL_EQUAL:
3519 case GL_GEQUAL:
3520 case GL_GREATER:
3521 case GL_NOTEQUAL:
3522 break;
3523 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003524 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003525 return false;
3526 }
3527
3528 return true;
3529}
3530
3531// Note that the spec specifies that for the path drawing commands
3532// if the path object is not an existing path object the command
3533// does nothing and no error is generated.
3534// However if the path object exists but has not been specified any
3535// commands then an error is generated.
3536
Jamie Madill007530e2017-12-28 14:27:04 -05003537bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003538{
3539 if (!context->getExtensions().pathRendering)
3540 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003541 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542 return false;
3543 }
Brandon Jones59770802018-04-02 13:18:42 -07003544 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003545 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003546 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003547 return false;
3548 }
3549
3550 switch (fillMode)
3551 {
3552 case GL_COUNT_UP_CHROMIUM:
3553 case GL_COUNT_DOWN_CHROMIUM:
3554 break;
3555 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003556 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003557 return false;
3558 }
3559
3560 if (!isPow2(mask + 1))
3561 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003562 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003563 return false;
3564 }
3565
3566 return true;
3567}
3568
Jamie Madill007530e2017-12-28 14:27:04 -05003569bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003570{
3571 if (!context->getExtensions().pathRendering)
3572 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003573 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003574 return false;
3575 }
Brandon Jones59770802018-04-02 13:18:42 -07003576 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003577 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003578 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003579 return false;
3580 }
3581
3582 return true;
3583}
3584
Brandon Jonesd1049182018-03-28 10:02:20 -07003585bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3586{
3587 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3588}
3589
3590bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3591{
3592 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3593}
3594
Jamie Madill007530e2017-12-28 14:27:04 -05003595bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003596{
3597 if (!context->getExtensions().pathRendering)
3598 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003599 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003600 return false;
3601 }
Brandon Jones59770802018-04-02 13:18:42 -07003602 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003603 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003605 return false;
3606 }
3607
3608 switch (coverMode)
3609 {
3610 case GL_CONVEX_HULL_CHROMIUM:
3611 case GL_BOUNDING_BOX_CHROMIUM:
3612 break;
3613 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003614 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003615 return false;
3616 }
3617 return true;
3618}
3619
Jamie Madill007530e2017-12-28 14:27:04 -05003620bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3621 GLuint path,
3622 GLenum fillMode,
3623 GLuint mask,
3624 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003625{
Jamie Madill007530e2017-12-28 14:27:04 -05003626 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3627 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003628}
3629
Jamie Madill007530e2017-12-28 14:27:04 -05003630bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3631 GLuint path,
3632 GLint reference,
3633 GLuint mask,
3634 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003635{
Jamie Madill007530e2017-12-28 14:27:04 -05003636 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3637 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003638}
3639
Brandon Jonesd1049182018-03-28 10:02:20 -07003640bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003641{
3642 if (!context->getExtensions().pathRendering)
3643 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003644 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003645 return false;
3646 }
3647 return true;
3648}
3649
Jamie Madill007530e2017-12-28 14:27:04 -05003650bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3651 GLsizei numPaths,
3652 GLenum pathNameType,
3653 const void *paths,
3654 GLuint pathBase,
3655 GLenum coverMode,
3656 GLenum transformType,
3657 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003658{
3659 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3660 transformType, transformValues))
3661 return false;
3662
3663 switch (coverMode)
3664 {
3665 case GL_CONVEX_HULL_CHROMIUM:
3666 case GL_BOUNDING_BOX_CHROMIUM:
3667 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3668 break;
3669 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003670 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003671 return false;
3672 }
3673
3674 return true;
3675}
3676
Jamie Madill007530e2017-12-28 14:27:04 -05003677bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3678 GLsizei numPaths,
3679 GLenum pathNameType,
3680 const void *paths,
3681 GLuint pathBase,
3682 GLenum coverMode,
3683 GLenum transformType,
3684 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003685{
3686 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3687 transformType, transformValues))
3688 return false;
3689
3690 switch (coverMode)
3691 {
3692 case GL_CONVEX_HULL_CHROMIUM:
3693 case GL_BOUNDING_BOX_CHROMIUM:
3694 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3695 break;
3696 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003697 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003698 return false;
3699 }
3700
3701 return true;
3702}
3703
Jamie Madill007530e2017-12-28 14:27:04 -05003704bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3705 GLsizei numPaths,
3706 GLenum pathNameType,
3707 const void *paths,
3708 GLuint pathBase,
3709 GLenum fillMode,
3710 GLuint mask,
3711 GLenum transformType,
3712 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003713{
3714
3715 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3716 transformType, transformValues))
3717 return false;
3718
3719 switch (fillMode)
3720 {
3721 case GL_COUNT_UP_CHROMIUM:
3722 case GL_COUNT_DOWN_CHROMIUM:
3723 break;
3724 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003725 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003726 return false;
3727 }
3728 if (!isPow2(mask + 1))
3729 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003730 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003731 return false;
3732 }
3733 return true;
3734}
3735
Jamie Madill007530e2017-12-28 14:27:04 -05003736bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3737 GLsizei numPaths,
3738 GLenum pathNameType,
3739 const void *paths,
3740 GLuint pathBase,
3741 GLint reference,
3742 GLuint mask,
3743 GLenum transformType,
3744 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003745{
3746 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3747 transformType, transformValues))
3748 return false;
3749
3750 // no more validation here.
3751
3752 return true;
3753}
3754
Jamie Madill007530e2017-12-28 14:27:04 -05003755bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3756 GLsizei numPaths,
3757 GLenum pathNameType,
3758 const void *paths,
3759 GLuint pathBase,
3760 GLenum fillMode,
3761 GLuint mask,
3762 GLenum coverMode,
3763 GLenum transformType,
3764 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003765{
3766 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3767 transformType, transformValues))
3768 return false;
3769
3770 switch (coverMode)
3771 {
3772 case GL_CONVEX_HULL_CHROMIUM:
3773 case GL_BOUNDING_BOX_CHROMIUM:
3774 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3775 break;
3776 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003777 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003778 return false;
3779 }
3780
3781 switch (fillMode)
3782 {
3783 case GL_COUNT_UP_CHROMIUM:
3784 case GL_COUNT_DOWN_CHROMIUM:
3785 break;
3786 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003787 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003788 return false;
3789 }
3790 if (!isPow2(mask + 1))
3791 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003792 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003793 return false;
3794 }
3795
3796 return true;
3797}
3798
Jamie Madill007530e2017-12-28 14:27:04 -05003799bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3800 GLsizei numPaths,
3801 GLenum pathNameType,
3802 const void *paths,
3803 GLuint pathBase,
3804 GLint reference,
3805 GLuint mask,
3806 GLenum coverMode,
3807 GLenum transformType,
3808 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003809{
3810 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3811 transformType, transformValues))
3812 return false;
3813
3814 switch (coverMode)
3815 {
3816 case GL_CONVEX_HULL_CHROMIUM:
3817 case GL_BOUNDING_BOX_CHROMIUM:
3818 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3819 break;
3820 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003821 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003822 return false;
3823 }
3824
3825 return true;
3826}
3827
Jamie Madill007530e2017-12-28 14:27:04 -05003828bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3829 GLuint program,
3830 GLint location,
3831 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003832{
3833 if (!context->getExtensions().pathRendering)
3834 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003835 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003836 return false;
3837 }
3838
3839 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3840 if (location >= MaxLocation)
3841 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003842 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003843 return false;
3844 }
3845
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003846 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003847 if (!programObject)
3848 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003849 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003850 return false;
3851 }
3852
3853 if (!name)
3854 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003855 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003856 return false;
3857 }
3858
3859 if (angle::BeginsWith(name, "gl_"))
3860 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003861 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003862 return false;
3863 }
3864
3865 return true;
3866}
3867
Jamie Madill007530e2017-12-28 14:27:04 -05003868bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3869 GLuint program,
3870 GLint location,
3871 GLenum genMode,
3872 GLint components,
3873 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003874{
3875 if (!context->getExtensions().pathRendering)
3876 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003877 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003878 return false;
3879 }
3880
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003881 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003882 if (!programObject || programObject->isFlaggedForDeletion())
3883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003884 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003885 return false;
3886 }
3887
3888 if (!programObject->isLinked())
3889 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003890 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003891 return false;
3892 }
3893
3894 switch (genMode)
3895 {
3896 case GL_NONE:
3897 if (components != 0)
3898 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003899 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003900 return false;
3901 }
3902 break;
3903
3904 case GL_OBJECT_LINEAR_CHROMIUM:
3905 case GL_EYE_LINEAR_CHROMIUM:
3906 case GL_CONSTANT_CHROMIUM:
3907 if (components < 1 || components > 4)
3908 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003909 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003910 return false;
3911 }
3912 if (!coeffs)
3913 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003914 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003915 return false;
3916 }
3917 break;
3918
3919 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003920 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003921 return false;
3922 }
3923
3924 // If the location is -1 then the command is silently ignored
3925 // and no further validation is needed.
3926 if (location == -1)
3927 return true;
3928
jchen103fd614d2018-08-13 12:21:58 +08003929 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003930
3931 if (!binding.valid)
3932 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003933 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003934 return false;
3935 }
3936
3937 if (binding.type != GL_NONE)
3938 {
3939 GLint expectedComponents = 0;
3940 switch (binding.type)
3941 {
3942 case GL_FLOAT:
3943 expectedComponents = 1;
3944 break;
3945 case GL_FLOAT_VEC2:
3946 expectedComponents = 2;
3947 break;
3948 case GL_FLOAT_VEC3:
3949 expectedComponents = 3;
3950 break;
3951 case GL_FLOAT_VEC4:
3952 expectedComponents = 4;
3953 break;
3954 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003955 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003956 InvalidOperation()
3957 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003958 return false;
3959 }
3960 if (expectedComponents != components && genMode != GL_NONE)
3961 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003962 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003963 return false;
3964 }
3965 }
3966 return true;
3967}
3968
Geoff Lang97073d12016-04-20 10:42:34 -07003969bool ValidateCopyTextureCHROMIUM(Context *context,
3970 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003971 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003972 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003973 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003974 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003975 GLint internalFormat,
3976 GLenum destType,
3977 GLboolean unpackFlipY,
3978 GLboolean unpackPremultiplyAlpha,
3979 GLboolean unpackUnmultiplyAlpha)
3980{
3981 if (!context->getExtensions().copyTexture)
3982 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003983 context->handleError(InvalidOperation()
3984 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003985 return false;
3986 }
3987
Geoff Lang4f0e0032017-05-01 16:04:35 -04003988 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003989 if (source == nullptr)
3990 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003991 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003992 return false;
3993 }
3994
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003995 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003996 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003997 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003998 return false;
3999 }
4000
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004001 TextureType sourceType = source->getType();
4002 ASSERT(sourceType != TextureType::CubeMap);
4003 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004004
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004005 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004006 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004007 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004008 return false;
4009 }
4010
Geoff Lang4f0e0032017-05-01 16:04:35 -04004011 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4012 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4013 if (sourceWidth == 0 || sourceHeight == 0)
4014 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004015 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004016 return false;
4017 }
4018
4019 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4020 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004021 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004022 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004023 return false;
4024 }
4025
Geoff Lang63458a32017-10-30 15:16:53 -04004026 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4027 {
4028 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4029 return false;
4030 }
4031
Geoff Lang4f0e0032017-05-01 16:04:35 -04004032 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004033 if (dest == nullptr)
4034 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004035 context->handleError(InvalidValue()
4036 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004037 return false;
4038 }
4039
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004040 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004042 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004043 return false;
4044 }
4045
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004046 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004047 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004048 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004049 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004050 return false;
4051 }
4052
Geoff Lang97073d12016-04-20 10:42:34 -07004053 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4054 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004055 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004056 return false;
4057 }
4058
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004059 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004060 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004061 context->handleError(
4062 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004063 return false;
4064 }
4065
Geoff Lang97073d12016-04-20 10:42:34 -07004066 if (dest->getImmutableFormat())
4067 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004068 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07004069 return false;
4070 }
4071
4072 return true;
4073}
4074
4075bool ValidateCopySubTextureCHROMIUM(Context *context,
4076 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004077 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004078 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004079 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004080 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004081 GLint xoffset,
4082 GLint yoffset,
4083 GLint x,
4084 GLint y,
4085 GLsizei width,
4086 GLsizei height,
4087 GLboolean unpackFlipY,
4088 GLboolean unpackPremultiplyAlpha,
4089 GLboolean unpackUnmultiplyAlpha)
4090{
4091 if (!context->getExtensions().copyTexture)
4092 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004093 context->handleError(InvalidOperation()
4094 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004095 return false;
4096 }
4097
Geoff Lang4f0e0032017-05-01 16:04:35 -04004098 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004099 if (source == nullptr)
4100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004101 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004102 return false;
4103 }
4104
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004105 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004107 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004108 return false;
4109 }
4110
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004111 TextureType sourceType = source->getType();
4112 ASSERT(sourceType != TextureType::CubeMap);
4113 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004114
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004115 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004116 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004117 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004118 return false;
4119 }
4120
4121 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4122 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004124 context->handleError(InvalidValue()
4125 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004126 return false;
4127 }
4128
4129 if (x < 0 || y < 0)
4130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004131 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004132 return false;
4133 }
4134
4135 if (width < 0 || height < 0)
4136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004137 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004138 return false;
4139 }
4140
Geoff Lang4f0e0032017-05-01 16:04:35 -04004141 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4142 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004144 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004145 return false;
4146 }
4147
Geoff Lang4f0e0032017-05-01 16:04:35 -04004148 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4149 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004150 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004152 return false;
4153 }
4154
Geoff Lang63458a32017-10-30 15:16:53 -04004155 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4156 {
4157 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4158 return false;
4159 }
4160
Geoff Lang4f0e0032017-05-01 16:04:35 -04004161 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004162 if (dest == nullptr)
4163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004164 context->handleError(InvalidValue()
4165 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004166 return false;
4167 }
4168
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004169 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004171 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004172 return false;
4173 }
4174
Brandon Jones28783792018-03-05 09:37:32 -08004175 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4176 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004177 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004178 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004179 return false;
4180 }
4181
Geoff Lang4f0e0032017-05-01 16:04:35 -04004182 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4183 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004184 context
4185 ->handleError(InvalidOperation()
4186 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004187 return false;
4188 }
4189
4190 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4191 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004193 context->handleError(InvalidOperation()
4194 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004195 return false;
4196 }
4197
4198 if (xoffset < 0 || yoffset < 0)
4199 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004200 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004201 return false;
4202 }
4203
Geoff Lang4f0e0032017-05-01 16:04:35 -04004204 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4205 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004207 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004208 return false;
4209 }
4210
4211 return true;
4212}
4213
Geoff Lang47110bf2016-04-20 11:13:22 -07004214bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4215{
4216 if (!context->getExtensions().copyCompressedTexture)
4217 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004218 context->handleError(InvalidOperation()
4219 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004220 return false;
4221 }
4222
4223 const gl::Texture *source = context->getTexture(sourceId);
4224 if (source == nullptr)
4225 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004226 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004227 return false;
4228 }
4229
Corentin Wallez99d492c2018-02-27 15:17:10 -05004230 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004231 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004232 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004233 return false;
4234 }
4235
Corentin Wallez99d492c2018-02-27 15:17:10 -05004236 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4237 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004239 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004240 return false;
4241 }
4242
Corentin Wallez99d492c2018-02-27 15:17:10 -05004243 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004244 if (!sourceFormat.info->compressed)
4245 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004246 context->handleError(InvalidOperation()
4247 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004248 return false;
4249 }
4250
4251 const gl::Texture *dest = context->getTexture(destId);
4252 if (dest == nullptr)
4253 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004254 context->handleError(InvalidValue()
4255 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004256 return false;
4257 }
4258
Corentin Wallez99d492c2018-02-27 15:17:10 -05004259 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004260 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004261 context->handleError(InvalidValue()
4262 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004263 return false;
4264 }
4265
4266 if (dest->getImmutableFormat())
4267 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004268 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004269 return false;
4270 }
4271
4272 return true;
4273}
4274
Jiawei Shao385b3e02018-03-21 09:43:28 +08004275bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004276{
4277 switch (type)
4278 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004279 case ShaderType::Vertex:
4280 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004281 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004282
Jiawei Shao385b3e02018-03-21 09:43:28 +08004283 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004284 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004285 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004286 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004287 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004288 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004289 break;
4290
Jiawei Shao385b3e02018-03-21 09:43:28 +08004291 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004292 if (!context->getExtensions().geometryShader)
4293 {
4294 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4295 return false;
4296 }
4297 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004298 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004299 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004300 return false;
4301 }
Jamie Madill29639852016-09-02 15:00:09 -04004302
4303 return true;
4304}
4305
Jamie Madill5b772312018-03-08 20:28:32 -05004306bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004307 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004308 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004309 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004310 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004311{
4312 if (size < 0)
4313 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004314 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004315 return false;
4316 }
4317
4318 switch (usage)
4319 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004320 case BufferUsage::StreamDraw:
4321 case BufferUsage::StaticDraw:
4322 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004323 break;
4324
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004325 case BufferUsage::StreamRead:
4326 case BufferUsage::StaticRead:
4327 case BufferUsage::DynamicRead:
4328 case BufferUsage::StreamCopy:
4329 case BufferUsage::StaticCopy:
4330 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004331 if (context->getClientMajorVersion() < 3)
4332 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004333 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004334 return false;
4335 }
4336 break;
4337
4338 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004339 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004340 return false;
4341 }
4342
Corentin Walleze4477002017-12-01 14:39:58 -05004343 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004344 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004345 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004346 return false;
4347 }
4348
4349 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4350
4351 if (!buffer)
4352 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004354 return false;
4355 }
4356
James Darpiniane8a93c62018-01-04 18:02:24 -08004357 if (context->getExtensions().webglCompatibility &&
4358 buffer->isBoundForTransformFeedbackAndOtherUse())
4359 {
4360 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4361 return false;
4362 }
4363
Jamie Madill29639852016-09-02 15:00:09 -04004364 return true;
4365}
4366
Jamie Madill5b772312018-03-08 20:28:32 -05004367bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004368 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004369 GLintptr offset,
4370 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004371 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004372{
Brandon Jones6cad5662017-06-14 13:25:13 -07004373 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004374 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004375 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4376 return false;
4377 }
4378
4379 if (offset < 0)
4380 {
4381 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004382 return false;
4383 }
4384
Corentin Walleze4477002017-12-01 14:39:58 -05004385 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004386 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004387 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004388 return false;
4389 }
4390
4391 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4392
4393 if (!buffer)
4394 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004396 return false;
4397 }
4398
4399 if (buffer->isMapped())
4400 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004401 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004402 return false;
4403 }
4404
James Darpiniane8a93c62018-01-04 18:02:24 -08004405 if (context->getExtensions().webglCompatibility &&
4406 buffer->isBoundForTransformFeedbackAndOtherUse())
4407 {
4408 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4409 return false;
4410 }
4411
Jamie Madill29639852016-09-02 15:00:09 -04004412 // Check for possible overflow of size + offset
4413 angle::CheckedNumeric<size_t> checkedSize(size);
4414 checkedSize += offset;
4415 if (!checkedSize.IsValid())
4416 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004417 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004418 return false;
4419 }
4420
4421 if (size + offset > buffer->getSize())
4422 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004423 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004424 return false;
4425 }
4426
Martin Radev4c4c8e72016-08-04 12:25:34 +03004427 return true;
4428}
4429
Geoff Lang111a99e2017-10-17 10:58:41 -04004430bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004431{
Geoff Langc339c4e2016-11-29 10:37:36 -05004432 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004434 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004435 return false;
4436 }
4437
Geoff Lang111a99e2017-10-17 10:58:41 -04004438 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004439 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004440 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004441 return false;
4442 }
4443
4444 return true;
4445}
4446
Jamie Madill5b772312018-03-08 20:28:32 -05004447bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004448{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004449 if (context->getClientMajorVersion() < 2)
4450 {
4451 return ValidateMultitextureUnit(context, texture);
4452 }
4453
Jamie Madillef300b12016-10-07 15:12:09 -04004454 if (texture < GL_TEXTURE0 ||
4455 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4456 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004457 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004458 return false;
4459 }
4460
4461 return true;
4462}
4463
Jamie Madill5b772312018-03-08 20:28:32 -05004464bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004465{
4466 Program *programObject = GetValidProgram(context, program);
4467 if (!programObject)
4468 {
4469 return false;
4470 }
4471
4472 Shader *shaderObject = GetValidShader(context, shader);
4473 if (!shaderObject)
4474 {
4475 return false;
4476 }
4477
Jiawei Shao385b3e02018-03-21 09:43:28 +08004478 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004479 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004480 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4481 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004482 }
4483
4484 return true;
4485}
4486
Jamie Madill5b772312018-03-08 20:28:32 -05004487bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004488{
4489 if (index >= MAX_VERTEX_ATTRIBS)
4490 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004491 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004492 return false;
4493 }
4494
4495 if (strncmp(name, "gl_", 3) == 0)
4496 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004497 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004498 return false;
4499 }
4500
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004501 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004502 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004503 const size_t length = strlen(name);
4504
4505 if (!IsValidESSLString(name, length))
4506 {
4507 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4508 // for shader-related entry points
4509 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4510 return false;
4511 }
4512
4513 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4514 {
4515 return false;
4516 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004517 }
4518
Jamie Madill01a80ee2016-11-07 12:06:18 -05004519 return GetValidProgram(context, program) != nullptr;
4520}
4521
Jamie Madill5b772312018-03-08 20:28:32 -05004522bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004523{
Corentin Walleze4477002017-12-01 14:39:58 -05004524 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004525 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004526 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004527 return false;
4528 }
4529
4530 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4531 !context->isBufferGenerated(buffer))
4532 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004533 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004534 return false;
4535 }
4536
4537 return true;
4538}
4539
Jamie Madill5b772312018-03-08 20:28:32 -05004540bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004541{
Geoff Lange8afa902017-09-27 15:00:43 -04004542 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004543 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004544 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004545 return false;
4546 }
4547
4548 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4549 !context->isFramebufferGenerated(framebuffer))
4550 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004551 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004552 return false;
4553 }
4554
4555 return true;
4556}
4557
Jamie Madill5b772312018-03-08 20:28:32 -05004558bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004559{
4560 if (target != GL_RENDERBUFFER)
4561 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004562 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004563 return false;
4564 }
4565
4566 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4567 !context->isRenderbufferGenerated(renderbuffer))
4568 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004569 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004570 return false;
4571 }
4572
4573 return true;
4574}
4575
Jamie Madill5b772312018-03-08 20:28:32 -05004576static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004577{
4578 switch (mode)
4579 {
4580 case GL_FUNC_ADD:
4581 case GL_FUNC_SUBTRACT:
4582 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004583 return true;
4584
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004585 case GL_MIN:
4586 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004587 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004588
4589 default:
4590 return false;
4591 }
4592}
4593
Jamie Madill5b772312018-03-08 20:28:32 -05004594bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004595{
4596 return true;
4597}
4598
Jamie Madill5b772312018-03-08 20:28:32 -05004599bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004600{
Geoff Lang50cac572017-09-26 17:37:43 -04004601 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004602 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004603 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004604 return false;
4605 }
4606
4607 return true;
4608}
4609
Jamie Madill5b772312018-03-08 20:28:32 -05004610bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004611{
Geoff Lang50cac572017-09-26 17:37:43 -04004612 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004613 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004614 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004615 return false;
4616 }
4617
Geoff Lang50cac572017-09-26 17:37:43 -04004618 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004619 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004620 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004621 return false;
4622 }
4623
4624 return true;
4625}
4626
Jamie Madill5b772312018-03-08 20:28:32 -05004627bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004628{
4629 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4630}
4631
Jamie Madill5b772312018-03-08 20:28:32 -05004632bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004633 GLenum srcRGB,
4634 GLenum dstRGB,
4635 GLenum srcAlpha,
4636 GLenum dstAlpha)
4637{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004638 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004639 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004640 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004641 return false;
4642 }
4643
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004644 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004645 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004646 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004647 return false;
4648 }
4649
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004650 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004651 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004652 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004653 return false;
4654 }
4655
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004656 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004657 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004658 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004659 return false;
4660 }
4661
Frank Henigman146e8a12017-03-02 23:22:37 -05004662 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4663 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004664 {
4665 bool constantColorUsed =
4666 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4667 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4668
4669 bool constantAlphaUsed =
4670 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4671 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4672
4673 if (constantColorUsed && constantAlphaUsed)
4674 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004675 const char *msg;
4676 if (context->getExtensions().webglCompatibility)
4677 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004678 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004679 }
4680 else
4681 {
4682 msg =
4683 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4684 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4685 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004686 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004687 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004688 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004689 return false;
4690 }
4691 }
4692
4693 return true;
4694}
4695
Geoff Langc339c4e2016-11-29 10:37:36 -05004696bool ValidateGetString(Context *context, GLenum name)
4697{
4698 switch (name)
4699 {
4700 case GL_VENDOR:
4701 case GL_RENDERER:
4702 case GL_VERSION:
4703 case GL_SHADING_LANGUAGE_VERSION:
4704 case GL_EXTENSIONS:
4705 break;
4706
4707 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4708 if (!context->getExtensions().requestExtension)
4709 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004710 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004711 return false;
4712 }
4713 break;
4714
4715 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004716 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004717 return false;
4718 }
4719
4720 return true;
4721}
4722
Jamie Madill5b772312018-03-08 20:28:32 -05004723bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004724{
4725 if (width <= 0.0f || isNaN(width))
4726 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004727 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004728 return false;
4729 }
4730
4731 return true;
4732}
4733
Jamie Madill5b772312018-03-08 20:28:32 -05004734bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004735 GLuint index,
4736 GLint size,
4737 GLenum type,
4738 GLboolean normalized,
4739 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004740 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004741{
Shao80957d92017-02-20 21:25:59 +08004742 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004743 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004744 return false;
4745 }
4746
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004747 if (stride < 0)
4748 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004749 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004750 return false;
4751 }
4752
Shao80957d92017-02-20 21:25:59 +08004753 const Caps &caps = context->getCaps();
4754 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004755 {
Shao80957d92017-02-20 21:25:59 +08004756 if (stride > caps.maxVertexAttribStride)
4757 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004758 context->handleError(InvalidValue()
4759 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004760 return false;
4761 }
4762
4763 if (index >= caps.maxVertexAttribBindings)
4764 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004765 context->handleError(InvalidValue()
4766 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004767 return false;
4768 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004769 }
4770
4771 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4772 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4773 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4774 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004775 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4776 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004777 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4778 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004779 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004780 context
4781 ->handleError(InvalidOperation()
4782 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004783 return false;
4784 }
4785
4786 if (context->getExtensions().webglCompatibility)
4787 {
4788 // WebGL 1.0 [Section 6.14] Fixed point support
4789 // The WebGL API does not support the GL_FIXED data type.
4790 if (type == GL_FIXED)
4791 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004792 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004793 return false;
4794 }
4795
Geoff Lang2d62ab72017-03-23 16:54:40 -04004796 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004797 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004798 return false;
4799 }
4800 }
4801
4802 return true;
4803}
4804
Jamie Madill5b772312018-03-08 20:28:32 -05004805bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004806{
4807 if (context->getExtensions().webglCompatibility && zNear > zFar)
4808 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004809 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004810 return false;
4811 }
4812
4813 return true;
4814}
4815
Jamie Madill5b772312018-03-08 20:28:32 -05004816bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004817 GLenum target,
4818 GLenum internalformat,
4819 GLsizei width,
4820 GLsizei height)
4821{
4822 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4823 height);
4824}
4825
Jamie Madill5b772312018-03-08 20:28:32 -05004826bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004827 GLenum target,
4828 GLsizei samples,
4829 GLenum internalformat,
4830 GLsizei width,
4831 GLsizei height)
4832{
4833 if (!context->getExtensions().framebufferMultisample)
4834 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004835 context->handleError(InvalidOperation()
4836 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004837 return false;
4838 }
4839
4840 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4841 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4842 // generated.
4843 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4844 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004845 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004846 return false;
4847 }
4848
4849 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4850 // the specified storage. This is different than ES 3.0 in which a sample number higher
4851 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4852 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4853 if (context->getClientMajorVersion() >= 3)
4854 {
4855 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4856 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4857 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004858 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004859 return false;
4860 }
4861 }
4862
4863 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4864 width, height);
4865}
4866
Jamie Madill5b772312018-03-08 20:28:32 -05004867bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004868{
Geoff Lange8afa902017-09-27 15:00:43 -04004869 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004870 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004871 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004872 return false;
4873 }
4874
4875 return true;
4876}
4877
Jamie Madill5b772312018-03-08 20:28:32 -05004878bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004879{
4880 return true;
4881}
4882
Jamie Madill5b772312018-03-08 20:28:32 -05004883bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004884{
4885 return true;
4886}
4887
Jamie Madill5b772312018-03-08 20:28:32 -05004888bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004889{
4890 return true;
4891}
4892
Jamie Madill5b772312018-03-08 20:28:32 -05004893bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894 GLboolean red,
4895 GLboolean green,
4896 GLboolean blue,
4897 GLboolean alpha)
4898{
4899 return true;
4900}
4901
Jamie Madill5b772312018-03-08 20:28:32 -05004902bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004903{
4904 return true;
4905}
4906
Jamie Madill5b772312018-03-08 20:28:32 -05004907bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004908{
4909 return true;
4910}
4911
Jamie Madill5b772312018-03-08 20:28:32 -05004912bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004913{
4914 switch (mode)
4915 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004916 case CullFaceMode::Front:
4917 case CullFaceMode::Back:
4918 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004919 break;
4920
4921 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004922 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004923 return false;
4924 }
4925
4926 return true;
4927}
4928
Jamie Madill5b772312018-03-08 20:28:32 -05004929bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004930{
4931 if (program == 0)
4932 {
4933 return false;
4934 }
4935
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004936 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004937 {
4938 if (context->getShader(program))
4939 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004940 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004941 return false;
4942 }
4943 else
4944 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004945 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004946 return false;
4947 }
4948 }
4949
4950 return true;
4951}
4952
Jamie Madill5b772312018-03-08 20:28:32 -05004953bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004954{
4955 if (shader == 0)
4956 {
4957 return false;
4958 }
4959
4960 if (!context->getShader(shader))
4961 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004962 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004963 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004964 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004965 return false;
4966 }
4967 else
4968 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004969 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004970 return false;
4971 }
4972 }
4973
4974 return true;
4975}
4976
Jamie Madill5b772312018-03-08 20:28:32 -05004977bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004978{
4979 switch (func)
4980 {
4981 case GL_NEVER:
4982 case GL_ALWAYS:
4983 case GL_LESS:
4984 case GL_LEQUAL:
4985 case GL_EQUAL:
4986 case GL_GREATER:
4987 case GL_GEQUAL:
4988 case GL_NOTEQUAL:
4989 break;
4990
4991 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004992 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004993 return false;
4994 }
4995
4996 return true;
4997}
4998
Jamie Madill5b772312018-03-08 20:28:32 -05004999bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005000{
5001 return true;
5002}
5003
Jamie Madill5b772312018-03-08 20:28:32 -05005004bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005005{
5006 Program *programObject = GetValidProgram(context, program);
5007 if (!programObject)
5008 {
5009 return false;
5010 }
5011
5012 Shader *shaderObject = GetValidShader(context, shader);
5013 if (!shaderObject)
5014 {
5015 return false;
5016 }
5017
Jiawei Shao385b3e02018-03-21 09:43:28 +08005018 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005019 if (attachedShader != shaderObject)
5020 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005021 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005022 return false;
5023 }
5024
5025 return true;
5026}
5027
Jamie Madill5b772312018-03-08 20:28:32 -05005028bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005029{
5030 if (index >= MAX_VERTEX_ATTRIBS)
5031 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005032 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005033 return false;
5034 }
5035
5036 return true;
5037}
5038
Jamie Madill5b772312018-03-08 20:28:32 -05005039bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005040{
5041 if (index >= MAX_VERTEX_ATTRIBS)
5042 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005043 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005044 return false;
5045 }
5046
5047 return true;
5048}
5049
Jamie Madill5b772312018-03-08 20:28:32 -05005050bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005051{
5052 return true;
5053}
5054
Jamie Madill5b772312018-03-08 20:28:32 -05005055bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005056{
5057 return true;
5058}
5059
Jamie Madill5b772312018-03-08 20:28:32 -05005060bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005061{
5062 switch (mode)
5063 {
5064 case GL_CW:
5065 case GL_CCW:
5066 break;
5067 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005068 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005069 return false;
5070 }
5071
5072 return true;
5073}
5074
Jamie Madill5b772312018-03-08 20:28:32 -05005075bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005076 GLuint program,
5077 GLuint index,
5078 GLsizei bufsize,
5079 GLsizei *length,
5080 GLint *size,
5081 GLenum *type,
5082 GLchar *name)
5083{
5084 if (bufsize < 0)
5085 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005086 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005087 return false;
5088 }
5089
5090 Program *programObject = GetValidProgram(context, program);
5091
5092 if (!programObject)
5093 {
5094 return false;
5095 }
5096
5097 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5098 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005099 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005100 return false;
5101 }
5102
5103 return true;
5104}
5105
Jamie Madill5b772312018-03-08 20:28:32 -05005106bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005107 GLuint program,
5108 GLuint index,
5109 GLsizei bufsize,
5110 GLsizei *length,
5111 GLint *size,
5112 GLenum *type,
5113 GLchar *name)
5114{
5115 if (bufsize < 0)
5116 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005117 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005118 return false;
5119 }
5120
5121 Program *programObject = GetValidProgram(context, program);
5122
5123 if (!programObject)
5124 {
5125 return false;
5126 }
5127
5128 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5129 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005130 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005131 return false;
5132 }
5133
5134 return true;
5135}
5136
Jamie Madill5b772312018-03-08 20:28:32 -05005137bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005138 GLuint program,
5139 GLsizei maxcount,
5140 GLsizei *count,
5141 GLuint *shaders)
5142{
5143 if (maxcount < 0)
5144 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005145 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005146 return false;
5147 }
5148
5149 Program *programObject = GetValidProgram(context, program);
5150
5151 if (!programObject)
5152 {
5153 return false;
5154 }
5155
5156 return true;
5157}
5158
Jamie Madill5b772312018-03-08 20:28:32 -05005159bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005160{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005161 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5162 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005163 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005165 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005166 return false;
5167 }
5168
Jamie Madillc1d770e2017-04-13 17:31:24 -04005169 Program *programObject = GetValidProgram(context, program);
5170
5171 if (!programObject)
5172 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005173 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005174 return false;
5175 }
5176
5177 if (!programObject->isLinked())
5178 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005179 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005180 return false;
5181 }
5182
5183 return true;
5184}
5185
Jamie Madill5b772312018-03-08 20:28:32 -05005186bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *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 ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005194{
5195 return true;
5196}
5197
Jamie Madill5b772312018-03-08 20:28:32 -05005198bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005199{
5200 GLenum nativeType;
5201 unsigned int numParams = 0;
5202 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5203}
5204
Jamie Madill5b772312018-03-08 20:28:32 -05005205bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005206{
5207 GLenum nativeType;
5208 unsigned int numParams = 0;
5209 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5210}
5211
Jamie Madill5b772312018-03-08 20:28:32 -05005212bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 GLuint program,
5214 GLsizei bufsize,
5215 GLsizei *length,
5216 GLchar *infolog)
5217{
5218 if (bufsize < 0)
5219 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005220 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005221 return false;
5222 }
5223
5224 Program *programObject = GetValidProgram(context, program);
5225 if (!programObject)
5226 {
5227 return false;
5228 }
5229
5230 return true;
5231}
5232
Jamie Madill5b772312018-03-08 20:28:32 -05005233bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005234 GLuint shader,
5235 GLsizei bufsize,
5236 GLsizei *length,
5237 GLchar *infolog)
5238{
5239 if (bufsize < 0)
5240 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005241 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005242 return false;
5243 }
5244
5245 Shader *shaderObject = GetValidShader(context, shader);
5246 if (!shaderObject)
5247 {
5248 return false;
5249 }
5250
5251 return true;
5252}
5253
Jamie Madill5b772312018-03-08 20:28:32 -05005254bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005255 GLenum shadertype,
5256 GLenum precisiontype,
5257 GLint *range,
5258 GLint *precision)
5259{
5260 switch (shadertype)
5261 {
5262 case GL_VERTEX_SHADER:
5263 case GL_FRAGMENT_SHADER:
5264 break;
5265 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005266 context->handleError(InvalidOperation()
5267 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005268 return false;
5269 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005270 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005271 return false;
5272 }
5273
5274 switch (precisiontype)
5275 {
5276 case GL_LOW_FLOAT:
5277 case GL_MEDIUM_FLOAT:
5278 case GL_HIGH_FLOAT:
5279 case GL_LOW_INT:
5280 case GL_MEDIUM_INT:
5281 case GL_HIGH_INT:
5282 break;
5283
5284 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005285 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005286 return false;
5287 }
5288
5289 return true;
5290}
5291
Jamie Madill5b772312018-03-08 20:28:32 -05005292bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293 GLuint shader,
5294 GLsizei bufsize,
5295 GLsizei *length,
5296 GLchar *source)
5297{
5298 if (bufsize < 0)
5299 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005300 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005301 return false;
5302 }
5303
5304 Shader *shaderObject = GetValidShader(context, shader);
5305 if (!shaderObject)
5306 {
5307 return false;
5308 }
5309
5310 return true;
5311}
5312
Jamie Madill5b772312018-03-08 20:28:32 -05005313bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005314{
5315 if (strstr(name, "gl_") == name)
5316 {
5317 return false;
5318 }
5319
Geoff Langfc32e8b2017-05-31 14:16:59 -04005320 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5321 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005322 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005323 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005324 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005325 return false;
5326 }
5327
Jamie Madillc1d770e2017-04-13 17:31:24 -04005328 Program *programObject = GetValidProgram(context, program);
5329
5330 if (!programObject)
5331 {
5332 return false;
5333 }
5334
5335 if (!programObject->isLinked())
5336 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005337 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005338 return false;
5339 }
5340
5341 return true;
5342}
5343
Jamie Madill5b772312018-03-08 20:28:32 -05005344bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345{
5346 switch (mode)
5347 {
5348 case GL_FASTEST:
5349 case GL_NICEST:
5350 case GL_DONT_CARE:
5351 break;
5352
5353 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005354 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005355 return false;
5356 }
5357
5358 switch (target)
5359 {
5360 case GL_GENERATE_MIPMAP_HINT:
5361 break;
5362
Geoff Lange7bd2182017-06-16 16:13:13 -04005363 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5364 if (context->getClientVersion() < ES_3_0 &&
5365 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005366 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005367 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368 return false;
5369 }
5370 break;
5371
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005372 case GL_PERSPECTIVE_CORRECTION_HINT:
5373 case GL_POINT_SMOOTH_HINT:
5374 case GL_LINE_SMOOTH_HINT:
5375 case GL_FOG_HINT:
5376 if (context->getClientMajorVersion() >= 2)
5377 {
5378 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5379 return false;
5380 }
5381 break;
5382
Jamie Madillc1d770e2017-04-13 17:31:24 -04005383 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005384 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385 return false;
5386 }
5387
5388 return true;
5389}
5390
Jamie Madill5b772312018-03-08 20:28:32 -05005391bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005392{
5393 return true;
5394}
5395
Jamie Madill5b772312018-03-08 20:28:32 -05005396bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397{
5398 return true;
5399}
5400
Jamie Madill5b772312018-03-08 20:28:32 -05005401bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005402{
5403 return true;
5404}
5405
Jamie Madill5b772312018-03-08 20:28:32 -05005406bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005407{
5408 return true;
5409}
5410
Jamie Madill5b772312018-03-08 20:28:32 -05005411bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005412{
5413 return true;
5414}
5415
Jamie Madill5b772312018-03-08 20:28:32 -05005416bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005417{
5418 return true;
5419}
5420
Jamie Madill5b772312018-03-08 20:28:32 -05005421bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005422{
5423 if (context->getClientMajorVersion() < 3)
5424 {
5425 switch (pname)
5426 {
5427 case GL_UNPACK_IMAGE_HEIGHT:
5428 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005429 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005430 return false;
5431
5432 case GL_UNPACK_ROW_LENGTH:
5433 case GL_UNPACK_SKIP_ROWS:
5434 case GL_UNPACK_SKIP_PIXELS:
5435 if (!context->getExtensions().unpackSubimage)
5436 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005437 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005438 return false;
5439 }
5440 break;
5441
5442 case GL_PACK_ROW_LENGTH:
5443 case GL_PACK_SKIP_ROWS:
5444 case GL_PACK_SKIP_PIXELS:
5445 if (!context->getExtensions().packSubimage)
5446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005447 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005448 return false;
5449 }
5450 break;
5451 }
5452 }
5453
5454 if (param < 0)
5455 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005456 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005457 return false;
5458 }
5459
5460 switch (pname)
5461 {
5462 case GL_UNPACK_ALIGNMENT:
5463 if (param != 1 && param != 2 && param != 4 && param != 8)
5464 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005465 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005466 return false;
5467 }
5468 break;
5469
5470 case GL_PACK_ALIGNMENT:
5471 if (param != 1 && param != 2 && param != 4 && param != 8)
5472 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005473 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005474 return false;
5475 }
5476 break;
5477
5478 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005479 if (!context->getExtensions().packReverseRowOrder)
5480 {
5481 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5482 }
5483 break;
5484
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485 case GL_UNPACK_ROW_LENGTH:
5486 case GL_UNPACK_IMAGE_HEIGHT:
5487 case GL_UNPACK_SKIP_IMAGES:
5488 case GL_UNPACK_SKIP_ROWS:
5489 case GL_UNPACK_SKIP_PIXELS:
5490 case GL_PACK_ROW_LENGTH:
5491 case GL_PACK_SKIP_ROWS:
5492 case GL_PACK_SKIP_PIXELS:
5493 break;
5494
5495 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005496 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005497 return false;
5498 }
5499
5500 return true;
5501}
5502
Jamie Madill5b772312018-03-08 20:28:32 -05005503bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005504{
5505 return true;
5506}
5507
Jamie Madill5b772312018-03-08 20:28:32 -05005508bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005509{
5510 return true;
5511}
5512
Jamie Madill5b772312018-03-08 20:28:32 -05005513bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005514{
5515 return true;
5516}
5517
Jamie Madill5b772312018-03-08 20:28:32 -05005518bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005519{
5520 if (width < 0 || height < 0)
5521 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005522 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005523 return false;
5524 }
5525
5526 return true;
5527}
5528
Jamie Madill5b772312018-03-08 20:28:32 -05005529bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005530 GLsizei n,
5531 const GLuint *shaders,
5532 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005533 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005534 GLsizei length)
5535{
5536 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5537 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5538 shaderBinaryFormats.end())
5539 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005540 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005541 return false;
5542 }
5543
5544 return true;
5545}
5546
Jamie Madill5b772312018-03-08 20:28:32 -05005547bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005548 GLuint shader,
5549 GLsizei count,
5550 const GLchar *const *string,
5551 const GLint *length)
5552{
5553 if (count < 0)
5554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005555 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556 return false;
5557 }
5558
Geoff Langfc32e8b2017-05-31 14:16:59 -04005559 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5560 // shader-related entry points
5561 if (context->getExtensions().webglCompatibility)
5562 {
5563 for (GLsizei i = 0; i < count; i++)
5564 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005565 size_t len =
5566 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005567
5568 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005569 if (!IsValidESSLShaderSourceString(string[i], len,
5570 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005571 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005572 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005573 return false;
5574 }
5575 }
5576 }
5577
Jamie Madillc1d770e2017-04-13 17:31:24 -04005578 Shader *shaderObject = GetValidShader(context, shader);
5579 if (!shaderObject)
5580 {
5581 return false;
5582 }
5583
5584 return true;
5585}
5586
Jamie Madill5b772312018-03-08 20:28:32 -05005587bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005588{
5589 if (!IsValidStencilFunc(func))
5590 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005591 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005592 return false;
5593 }
5594
5595 return true;
5596}
5597
Jamie Madill5b772312018-03-08 20:28:32 -05005598bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005599{
5600 if (!IsValidStencilFace(face))
5601 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005602 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005603 return false;
5604 }
5605
5606 if (!IsValidStencilFunc(func))
5607 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005609 return false;
5610 }
5611
5612 return true;
5613}
5614
Jamie Madill5b772312018-03-08 20:28:32 -05005615bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005616{
5617 return true;
5618}
5619
Jamie Madill5b772312018-03-08 20:28:32 -05005620bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005621{
5622 if (!IsValidStencilFace(face))
5623 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005624 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005625 return false;
5626 }
5627
5628 return true;
5629}
5630
Jamie Madill5b772312018-03-08 20:28:32 -05005631bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005632{
5633 if (!IsValidStencilOp(fail))
5634 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005635 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005636 return false;
5637 }
5638
5639 if (!IsValidStencilOp(zfail))
5640 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005641 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005642 return false;
5643 }
5644
5645 if (!IsValidStencilOp(zpass))
5646 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005647 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005648 return false;
5649 }
5650
5651 return true;
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655 GLenum face,
5656 GLenum fail,
5657 GLenum zfail,
5658 GLenum zpass)
5659{
5660 if (!IsValidStencilFace(face))
5661 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005662 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005663 return false;
5664 }
5665
5666 return ValidateStencilOp(context, fail, zfail, zpass);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670{
5671 return ValidateUniform(context, GL_FLOAT, location, 1);
5672}
5673
Jamie Madill5b772312018-03-08 20:28:32 -05005674bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675{
5676 return ValidateUniform(context, GL_FLOAT, location, count);
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005680{
5681 return ValidateUniform1iv(context, location, 1, &x);
5682}
5683
Jamie Madill5b772312018-03-08 20:28:32 -05005684bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005685{
5686 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5687}
5688
Jamie Madill5b772312018-03-08 20:28:32 -05005689bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005690{
5691 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5692}
5693
Jamie Madill5b772312018-03-08 20:28:32 -05005694bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005695{
5696 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5697}
5698
Jamie Madill5b772312018-03-08 20:28:32 -05005699bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005700{
5701 return ValidateUniform(context, GL_INT_VEC2, location, count);
5702}
5703
Jamie Madill5b772312018-03-08 20:28:32 -05005704bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005705{
5706 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5707}
5708
Jamie Madill5b772312018-03-08 20:28:32 -05005709bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005710{
5711 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5712}
5713
Jamie Madill5b772312018-03-08 20:28:32 -05005714bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005715{
5716 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5717}
5718
Jamie Madill5b772312018-03-08 20:28:32 -05005719bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005720{
5721 return ValidateUniform(context, GL_INT_VEC3, location, count);
5722}
5723
Jamie Madill5b772312018-03-08 20:28:32 -05005724bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005725{
5726 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5727}
5728
Jamie Madill5b772312018-03-08 20:28:32 -05005729bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005730{
5731 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5732}
5733
Jamie Madill5b772312018-03-08 20:28:32 -05005734bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005735{
5736 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5737}
5738
Jamie Madill5b772312018-03-08 20:28:32 -05005739bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005740{
5741 return ValidateUniform(context, GL_INT_VEC4, location, count);
5742}
5743
Jamie Madill5b772312018-03-08 20:28:32 -05005744bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005745 GLint location,
5746 GLsizei count,
5747 GLboolean transpose,
5748 const GLfloat *value)
5749{
5750 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5751}
5752
Jamie Madill5b772312018-03-08 20:28:32 -05005753bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005754 GLint location,
5755 GLsizei count,
5756 GLboolean transpose,
5757 const GLfloat *value)
5758{
5759 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5760}
5761
Jamie Madill5b772312018-03-08 20:28:32 -05005762bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005763 GLint location,
5764 GLsizei count,
5765 GLboolean transpose,
5766 const GLfloat *value)
5767{
5768 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5769}
5770
Jamie Madill5b772312018-03-08 20:28:32 -05005771bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005772{
5773 Program *programObject = GetValidProgram(context, program);
5774
5775 if (!programObject)
5776 {
5777 return false;
5778 }
5779
5780 return true;
5781}
5782
Jamie Madill5b772312018-03-08 20:28:32 -05005783bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005784{
5785 return ValidateVertexAttribIndex(context, index);
5786}
5787
Jamie Madill5b772312018-03-08 20:28:32 -05005788bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005789{
5790 return ValidateVertexAttribIndex(context, index);
5791}
5792
Jamie Madill5b772312018-03-08 20:28:32 -05005793bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005794{
5795 return ValidateVertexAttribIndex(context, index);
5796}
5797
Jamie Madill5b772312018-03-08 20:28:32 -05005798bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005799{
5800 return ValidateVertexAttribIndex(context, index);
5801}
5802
Jamie Madill5b772312018-03-08 20:28:32 -05005803bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005804{
5805 return ValidateVertexAttribIndex(context, index);
5806}
5807
Jamie Madill5b772312018-03-08 20:28:32 -05005808bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005809{
5810 return ValidateVertexAttribIndex(context, index);
5811}
5812
Jamie Madill5b772312018-03-08 20:28:32 -05005813bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005814 GLuint index,
5815 GLfloat x,
5816 GLfloat y,
5817 GLfloat z,
5818 GLfloat w)
5819{
5820 return ValidateVertexAttribIndex(context, index);
5821}
5822
Jamie Madill5b772312018-03-08 20:28:32 -05005823bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005824{
5825 return ValidateVertexAttribIndex(context, index);
5826}
5827
Jamie Madill5b772312018-03-08 20:28:32 -05005828bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005829{
5830 if (width < 0 || height < 0)
5831 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005832 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005833 return false;
5834 }
5835
5836 return true;
5837}
5838
Jamie Madill5b772312018-03-08 20:28:32 -05005839bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005840 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005841 GLsizei count,
5842 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005843 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005844{
5845 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5846}
5847
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005848bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005849 GLenum target,
5850 GLenum attachment,
5851 GLenum pname,
5852 GLint *params)
5853{
5854 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5855 nullptr);
5856}
5857
Jamie Madill5b772312018-03-08 20:28:32 -05005858bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005859{
5860 return ValidateGetProgramivBase(context, program, pname, nullptr);
5861}
5862
Jamie Madill5b772312018-03-08 20:28:32 -05005863bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005864 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005865 GLint level,
5866 GLenum internalformat,
5867 GLint x,
5868 GLint y,
5869 GLsizei width,
5870 GLsizei height,
5871 GLint border)
5872{
5873 if (context->getClientMajorVersion() < 3)
5874 {
5875 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5876 0, x, y, width, height, border);
5877 }
5878
5879 ASSERT(context->getClientMajorVersion() == 3);
5880 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5881 0, x, y, width, height, border);
5882}
5883
5884bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005885 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005886 GLint level,
5887 GLint xoffset,
5888 GLint yoffset,
5889 GLint x,
5890 GLint y,
5891 GLsizei width,
5892 GLsizei height)
5893{
5894 if (context->getClientMajorVersion() < 3)
5895 {
5896 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5897 yoffset, x, y, width, height, 0);
5898 }
5899
5900 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5901 yoffset, 0, x, y, width, height, 0);
5902}
5903
5904bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5905{
5906 return ValidateGenOrDelete(context, n);
5907}
5908
5909bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5910{
5911 return ValidateGenOrDelete(context, n);
5912}
5913
5914bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5915{
5916 return ValidateGenOrDelete(context, n);
5917}
5918
5919bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5920{
5921 return ValidateGenOrDelete(context, n);
5922}
5923
5924bool ValidateDisable(Context *context, GLenum cap)
5925{
5926 if (!ValidCap(context, cap, false))
5927 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005928 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005929 return false;
5930 }
5931
5932 return true;
5933}
5934
5935bool ValidateEnable(Context *context, GLenum cap)
5936{
5937 if (!ValidCap(context, cap, false))
5938 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005939 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005940 return false;
5941 }
5942
5943 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5944 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5945 {
5946 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005947 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005948
5949 // We also output an error message to the debugger window if tracing is active, so that
5950 // developers can see the error message.
5951 ERR() << errorMessage;
5952 return false;
5953 }
5954
5955 return true;
5956}
5957
5958bool ValidateFramebufferRenderbuffer(Context *context,
5959 GLenum target,
5960 GLenum attachment,
5961 GLenum renderbuffertarget,
5962 GLuint renderbuffer)
5963{
Geoff Lange8afa902017-09-27 15:00:43 -04005964 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005965 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005966 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5967 return false;
5968 }
5969
5970 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5971 {
5972 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005973 return false;
5974 }
5975
5976 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5977 renderbuffertarget, renderbuffer);
5978}
5979
5980bool ValidateFramebufferTexture2D(Context *context,
5981 GLenum target,
5982 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005983 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005984 GLuint texture,
5985 GLint level)
5986{
5987 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5988 // extension
5989 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5990 level != 0)
5991 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005992 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005993 return false;
5994 }
5995
5996 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5997 {
5998 return false;
5999 }
6000
6001 if (texture != 0)
6002 {
6003 gl::Texture *tex = context->getTexture(texture);
6004 ASSERT(tex);
6005
6006 const gl::Caps &caps = context->getCaps();
6007
6008 switch (textarget)
6009 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006010 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006011 {
6012 if (level > gl::log2(caps.max2DTextureSize))
6013 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006014 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006015 return false;
6016 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006017 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006018 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006019 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006020 return false;
6021 }
6022 }
6023 break;
6024
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006025 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006026 {
6027 if (level != 0)
6028 {
6029 context->handleError(InvalidValue());
6030 return false;
6031 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006032 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006033 {
6034 context->handleError(InvalidOperation()
6035 << "Textarget must match the texture target type.");
6036 return false;
6037 }
6038 }
6039 break;
6040
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006041 case TextureTarget::CubeMapNegativeX:
6042 case TextureTarget::CubeMapNegativeY:
6043 case TextureTarget::CubeMapNegativeZ:
6044 case TextureTarget::CubeMapPositiveX:
6045 case TextureTarget::CubeMapPositiveY:
6046 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006047 {
6048 if (level > gl::log2(caps.maxCubeMapTextureSize))
6049 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006050 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006051 return false;
6052 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006053 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006054 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006055 context->handleError(InvalidOperation()
6056 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006057 return false;
6058 }
6059 }
6060 break;
6061
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006062 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006063 {
6064 if (context->getClientVersion() < ES_3_1)
6065 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006066 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006067 return false;
6068 }
6069
6070 if (level != 0)
6071 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006072 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006073 return false;
6074 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006075 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006076 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006077 context->handleError(InvalidOperation()
6078 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006079 return false;
6080 }
6081 }
6082 break;
6083
6084 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006085 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006086 return false;
6087 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006088 }
6089
6090 return true;
6091}
6092
6093bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6094{
6095 return ValidateGenOrDelete(context, n);
6096}
6097
6098bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6099{
6100 return ValidateGenOrDelete(context, n);
6101}
6102
6103bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6104{
6105 return ValidateGenOrDelete(context, n);
6106}
6107
6108bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6109{
6110 return ValidateGenOrDelete(context, n);
6111}
6112
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006113bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006114{
6115 if (!ValidTextureTarget(context, target))
6116 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006117 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006118 return false;
6119 }
6120
6121 Texture *texture = context->getTargetTexture(target);
6122
6123 if (texture == nullptr)
6124 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006125 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006126 return false;
6127 }
6128
6129 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6130
6131 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6132 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6133 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006135 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006136 return false;
6137 }
6138
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006139 TextureTarget baseTarget = (target == TextureType::CubeMap)
6140 ? TextureTarget::CubeMapPositiveX
6141 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006142 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6143 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6144 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006145 {
6146 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6147 return false;
6148 }
6149
Geoff Lang536eca12017-09-13 11:23:35 -04006150 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6151 bool formatUnsized = !format.sized;
6152 bool formatColorRenderableAndFilterable =
6153 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006154 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006155 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006156 {
Geoff Lang536eca12017-09-13 11:23:35 -04006157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006158 return false;
6159 }
6160
Geoff Lang536eca12017-09-13 11:23:35 -04006161 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6162 // generation
6163 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6164 {
6165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6166 return false;
6167 }
6168
Jiange2c00842018-07-13 16:50:49 +08006169 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6170 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6171 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006172 {
Geoff Lang536eca12017-09-13 11:23:35 -04006173 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006174 return false;
6175 }
6176
6177 // Non-power of 2 ES2 check
6178 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6179 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6180 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6181 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006182 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6183 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006184 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006185 return false;
6186 }
6187
6188 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006189 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006190 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006191 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006192 return false;
6193 }
6194
6195 return true;
6196}
6197
Jamie Madill5b772312018-03-08 20:28:32 -05006198bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006199 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006200 GLenum pname,
6201 GLint *params)
6202{
6203 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6204}
6205
6206bool ValidateGetRenderbufferParameteriv(Context *context,
6207 GLenum target,
6208 GLenum pname,
6209 GLint *params)
6210{
6211 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6212}
6213
6214bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6215{
6216 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6217}
6218
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006219bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006220{
6221 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6222}
6223
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006224bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006225{
6226 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6227}
6228
6229bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6230{
6231 return ValidateGetUniformBase(context, program, location);
6232}
6233
6234bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6235{
6236 return ValidateGetUniformBase(context, program, location);
6237}
6238
6239bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6240{
6241 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6242}
6243
6244bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6245{
6246 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6247}
6248
6249bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6250{
6251 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6252}
6253
6254bool ValidateIsEnabled(Context *context, GLenum cap)
6255{
6256 if (!ValidCap(context, cap, true))
6257 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006258 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006259 return false;
6260 }
6261
6262 return true;
6263}
6264
6265bool ValidateLinkProgram(Context *context, GLuint program)
6266{
6267 if (context->hasActiveTransformFeedback(program))
6268 {
6269 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006270 context->handleError(InvalidOperation() << "Cannot link program while program is "
6271 "associated with an active transform "
6272 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006273 return false;
6274 }
6275
6276 Program *programObject = GetValidProgram(context, program);
6277 if (!programObject)
6278 {
6279 return false;
6280 }
6281
6282 return true;
6283}
6284
Jamie Madill4928b7c2017-06-20 12:57:39 -04006285bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006286 GLint x,
6287 GLint y,
6288 GLsizei width,
6289 GLsizei height,
6290 GLenum format,
6291 GLenum type,
6292 void *pixels)
6293{
6294 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6295 nullptr, pixels);
6296}
6297
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006298bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006299{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006300 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006301}
6302
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006303bool ValidateTexParameterfv(Context *context,
6304 TextureType target,
6305 GLenum pname,
6306 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006307{
6308 return ValidateTexParameterBase(context, target, pname, -1, params);
6309}
6310
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006311bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006312{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006313 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006314}
6315
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006316bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006317{
6318 return ValidateTexParameterBase(context, target, pname, -1, params);
6319}
6320
6321bool ValidateUseProgram(Context *context, GLuint program)
6322{
6323 if (program != 0)
6324 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006325 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006326 if (!programObject)
6327 {
6328 // ES 3.1.0 section 7.3 page 72
6329 if (context->getShader(program))
6330 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006331 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006332 return false;
6333 }
6334 else
6335 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006336 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006337 return false;
6338 }
6339 }
6340 if (!programObject->isLinked())
6341 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006342 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006343 return false;
6344 }
6345 }
6346 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6347 {
6348 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006349 context
6350 ->handleError(InvalidOperation()
6351 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006352 return false;
6353 }
6354
6355 return true;
6356}
6357
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006358bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6359{
6360 if (!context->getExtensions().fence)
6361 {
6362 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6363 return false;
6364 }
6365
6366 if (n < 0)
6367 {
6368 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6369 return false;
6370 }
6371
6372 return true;
6373}
6374
6375bool ValidateFinishFenceNV(Context *context, GLuint fence)
6376{
6377 if (!context->getExtensions().fence)
6378 {
6379 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6380 return false;
6381 }
6382
6383 FenceNV *fenceObject = context->getFenceNV(fence);
6384
6385 if (fenceObject == nullptr)
6386 {
6387 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6388 return false;
6389 }
6390
6391 if (!fenceObject->isSet())
6392 {
6393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6394 return false;
6395 }
6396
6397 return true;
6398}
6399
6400bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6401{
6402 if (!context->getExtensions().fence)
6403 {
6404 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6405 return false;
6406 }
6407
6408 if (n < 0)
6409 {
6410 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6411 return false;
6412 }
6413
6414 return true;
6415}
6416
6417bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6418{
6419 if (!context->getExtensions().fence)
6420 {
6421 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6422 return false;
6423 }
6424
6425 FenceNV *fenceObject = context->getFenceNV(fence);
6426
6427 if (fenceObject == nullptr)
6428 {
6429 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6430 return false;
6431 }
6432
6433 if (!fenceObject->isSet())
6434 {
6435 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6436 return false;
6437 }
6438
6439 switch (pname)
6440 {
6441 case GL_FENCE_STATUS_NV:
6442 case GL_FENCE_CONDITION_NV:
6443 break;
6444
6445 default:
6446 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6447 return false;
6448 }
6449
6450 return true;
6451}
6452
6453bool ValidateGetGraphicsResetStatusEXT(Context *context)
6454{
6455 if (!context->getExtensions().robustness)
6456 {
6457 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6458 return false;
6459 }
6460
6461 return true;
6462}
6463
6464bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6465 GLuint shader,
6466 GLsizei bufsize,
6467 GLsizei *length,
6468 GLchar *source)
6469{
6470 if (!context->getExtensions().translatedShaderSource)
6471 {
6472 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6473 return false;
6474 }
6475
6476 if (bufsize < 0)
6477 {
6478 context->handleError(InvalidValue());
6479 return false;
6480 }
6481
6482 Shader *shaderObject = context->getShader(shader);
6483
6484 if (!shaderObject)
6485 {
6486 context->handleError(InvalidOperation());
6487 return false;
6488 }
6489
6490 return true;
6491}
6492
6493bool ValidateIsFenceNV(Context *context, GLuint fence)
6494{
6495 if (!context->getExtensions().fence)
6496 {
6497 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6498 return false;
6499 }
6500
6501 return true;
6502}
6503
Jamie Madill007530e2017-12-28 14:27:04 -05006504bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6505{
6506 if (!context->getExtensions().fence)
6507 {
6508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6509 return false;
6510 }
6511
6512 if (condition != GL_ALL_COMPLETED_NV)
6513 {
6514 context->handleError(InvalidEnum());
6515 return false;
6516 }
6517
6518 FenceNV *fenceObject = context->getFenceNV(fence);
6519
6520 if (fenceObject == nullptr)
6521 {
6522 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6523 return false;
6524 }
6525
6526 return true;
6527}
6528
6529bool ValidateTestFenceNV(Context *context, GLuint fence)
6530{
6531 if (!context->getExtensions().fence)
6532 {
6533 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6534 return false;
6535 }
6536
6537 FenceNV *fenceObject = context->getFenceNV(fence);
6538
6539 if (fenceObject == nullptr)
6540 {
6541 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6542 return false;
6543 }
6544
6545 if (fenceObject->isSet() != GL_TRUE)
6546 {
6547 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6548 return false;
6549 }
6550
6551 return true;
6552}
6553
6554bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006555 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006556 GLsizei levels,
6557 GLenum internalformat,
6558 GLsizei width,
6559 GLsizei height)
6560{
6561 if (!context->getExtensions().textureStorage)
6562 {
6563 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6564 return false;
6565 }
6566
6567 if (context->getClientMajorVersion() < 3)
6568 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006569 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006570 height);
6571 }
6572
6573 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006574 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006575 1);
6576}
6577
6578bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6579{
6580 if (!context->getExtensions().instancedArrays)
6581 {
6582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6583 return false;
6584 }
6585
6586 if (index >= MAX_VERTEX_ATTRIBS)
6587 {
6588 context->handleError(InvalidValue());
6589 return false;
6590 }
6591
6592 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6593 {
6594 if (index == 0 && divisor != 0)
6595 {
6596 const char *errorMessage =
6597 "The current context doesn't support setting a non-zero divisor on the "
6598 "attribute with index zero. "
6599 "Please reorder the attributes in your vertex shader so that attribute zero "
6600 "can have a zero divisor.";
6601 context->handleError(InvalidOperation() << errorMessage);
6602
6603 // We also output an error message to the debugger window if tracing is active, so
6604 // that developers can see the error message.
6605 ERR() << errorMessage;
6606 return false;
6607 }
6608 }
6609
6610 return true;
6611}
6612
6613bool ValidateTexImage3DOES(Context *context,
6614 GLenum target,
6615 GLint level,
6616 GLenum internalformat,
6617 GLsizei width,
6618 GLsizei height,
6619 GLsizei depth,
6620 GLint border,
6621 GLenum format,
6622 GLenum type,
6623 const void *pixels)
6624{
6625 UNIMPLEMENTED(); // FIXME
6626 return false;
6627}
6628
6629bool ValidatePopGroupMarkerEXT(Context *context)
6630{
6631 if (!context->getExtensions().debugMarker)
6632 {
6633 // The debug marker calls should not set error state
6634 // However, it seems reasonable to set an error state if the extension is not enabled
6635 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6636 return false;
6637 }
6638
6639 return true;
6640}
6641
Jamie Madillfa920eb2018-01-04 11:45:50 -05006642bool ValidateTexStorage1DEXT(Context *context,
6643 GLenum target,
6644 GLsizei levels,
6645 GLenum internalformat,
6646 GLsizei width)
6647{
6648 UNIMPLEMENTED();
6649 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6650 return false;
6651}
6652
6653bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006654 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006655 GLsizei levels,
6656 GLenum internalformat,
6657 GLsizei width,
6658 GLsizei height,
6659 GLsizei depth)
6660{
6661 if (!context->getExtensions().textureStorage)
6662 {
6663 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6664 return false;
6665 }
6666
6667 if (context->getClientMajorVersion() < 3)
6668 {
6669 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6670 return false;
6671 }
6672
6673 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6674 depth);
6675}
6676
jchen1082af6202018-06-22 10:59:52 +08006677bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6678{
6679 if (!context->getExtensions().parallelShaderCompile)
6680 {
6681 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6682 return false;
6683 }
6684 return true;
6685}
6686
Jamie Madillc29968b2016-01-20 11:17:23 -05006687} // namespace gl