blob: 5e3460d27622b15d1e9197c7085e2d807e7551ca [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 Yang13b708f2018-03-21 12:14:10 -0700802 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700803 case GL_POINT_SIZE_ARRAY_OES:
804 return context->getClientVersion() < Version(2, 0) &&
805 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700806 case GL_TEXTURE_CUBE_MAP:
807 return context->getClientVersion() < Version(2, 0) &&
808 context->getExtensions().textureCubeMap;
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700809
Jamie Madillbe849e42017-05-02 15:49:00 -0400810 default:
811 return false;
812 }
813}
814
Geoff Langfc32e8b2017-05-31 14:16:59 -0400815// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
816// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400817bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400818{
819 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400820 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
821 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400822 {
823 return true;
824 }
825
826 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
827 if (c >= 9 && c <= 13)
828 {
829 return true;
830 }
831
832 return false;
833}
834
Geoff Langcab92ee2017-07-19 17:32:07 -0400835bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400836{
Geoff Langa71a98e2017-06-19 15:15:00 -0400837 for (size_t i = 0; i < len; i++)
838 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400839 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400840 {
841 return false;
842 }
843 }
844
845 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400846}
847
Geoff Langcab92ee2017-07-19 17:32:07 -0400848bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
849{
850 enum class ParseState
851 {
852 // Have not seen an ASCII non-whitespace character yet on
853 // this line. Possible that we might see a preprocessor
854 // directive.
855 BEGINING_OF_LINE,
856
857 // Have seen at least one ASCII non-whitespace character
858 // on this line.
859 MIDDLE_OF_LINE,
860
861 // Handling a preprocessor directive. Passes through all
862 // characters up to the end of the line. Disables comment
863 // processing.
864 IN_PREPROCESSOR_DIRECTIVE,
865
866 // Handling a single-line comment. The comment text is
867 // replaced with a single space.
868 IN_SINGLE_LINE_COMMENT,
869
870 // Handling a multi-line comment. Newlines are passed
871 // through to preserve line numbers.
872 IN_MULTI_LINE_COMMENT
873 };
874
875 ParseState state = ParseState::BEGINING_OF_LINE;
876 size_t pos = 0;
877
878 while (pos < len)
879 {
880 char c = str[pos];
881 char next = pos + 1 < len ? str[pos + 1] : 0;
882
883 // Check for newlines
884 if (c == '\n' || c == '\r')
885 {
886 if (state != ParseState::IN_MULTI_LINE_COMMENT)
887 {
888 state = ParseState::BEGINING_OF_LINE;
889 }
890
891 pos++;
892 continue;
893 }
894
895 switch (state)
896 {
897 case ParseState::BEGINING_OF_LINE:
898 if (c == ' ')
899 {
900 // Maintain the BEGINING_OF_LINE state until a non-space is seen
901 pos++;
902 }
903 else if (c == '#')
904 {
905 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
906 pos++;
907 }
908 else
909 {
910 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
911 state = ParseState::MIDDLE_OF_LINE;
912 }
913 break;
914
915 case ParseState::MIDDLE_OF_LINE:
916 if (c == '/' && next == '/')
917 {
918 state = ParseState::IN_SINGLE_LINE_COMMENT;
919 pos++;
920 }
921 else if (c == '/' && next == '*')
922 {
923 state = ParseState::IN_MULTI_LINE_COMMENT;
924 pos++;
925 }
926 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
927 {
928 // Skip line continuation characters
929 }
930 else if (!IsValidESSLCharacter(c))
931 {
932 return false;
933 }
934 pos++;
935 break;
936
937 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700938 // Line-continuation characters may not be permitted.
939 // Otherwise, just pass it through. Do not parse comments in this state.
940 if (!lineContinuationAllowed && c == '\\')
941 {
942 return false;
943 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400944 pos++;
945 break;
946
947 case ParseState::IN_SINGLE_LINE_COMMENT:
948 // Line-continuation characters are processed before comment processing.
949 // Advance string if a new line character is immediately behind
950 // line-continuation character.
951 if (c == '\\' && (next == '\n' || next == '\r'))
952 {
953 pos++;
954 }
955 pos++;
956 break;
957
958 case ParseState::IN_MULTI_LINE_COMMENT:
959 if (c == '*' && next == '/')
960 {
961 state = ParseState::MIDDLE_OF_LINE;
962 pos++;
963 }
964 pos++;
965 break;
966 }
967 }
968
969 return true;
970}
971
Jamie Madill5b772312018-03-08 20:28:32 -0500972bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700973{
974 ASSERT(context->isWebGL());
975
976 // WebGL 1.0 [Section 6.16] GLSL Constructs
977 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
978 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
979 {
980 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
981 return false;
982 }
983
984 return true;
985}
986
Jamie Madill5b772312018-03-08 20:28:32 -0500987bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700988{
989 ASSERT(context->isWebGL());
990
991 if (context->isWebGL1() && length > 256)
992 {
993 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
994 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
995 // locations.
996 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
997
998 return false;
999 }
1000 else if (length > 1024)
1001 {
1002 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1003 // uniform and attribute locations.
1004 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1005 return false;
1006 }
1007
1008 return true;
1009}
1010
Jamie Madill007530e2017-12-28 14:27:04 -05001011bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1012{
1013 if (!context->getExtensions().pathRendering)
1014 {
1015 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1016 return false;
1017 }
1018
1019 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1020 {
1021 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1022 return false;
1023 }
1024 return true;
1025}
Jamie Madillc29968b2016-01-20 11:17:23 -05001026} // anonymous namespace
1027
Geoff Langff5b2d52016-09-07 11:32:23 -04001028bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001029 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001030 GLint level,
1031 GLenum internalformat,
1032 bool isCompressed,
1033 bool isSubImage,
1034 GLint xoffset,
1035 GLint yoffset,
1036 GLsizei width,
1037 GLsizei height,
1038 GLint border,
1039 GLenum format,
1040 GLenum type,
1041 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001042 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001043{
Jamie Madill6f38f822014-06-06 17:12:20 -04001044 if (!ValidTexture2DDestinationTarget(context, target))
1045 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001046 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001047 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001048 }
1049
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001050 TextureType texType = TextureTargetToType(target);
1051 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001052 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001053 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001054 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001055 }
1056
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001057 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001058 {
1059 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1060 return false;
1061 }
1062
1063 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001064 std::numeric_limits<GLsizei>::max() - yoffset < height)
1065 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001066 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001067 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001068 }
1069
Geoff Lang6e898aa2017-06-02 11:17:26 -04001070 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1071 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1072 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1073 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1074 // case.
1075 bool nonEqualFormatsAllowed =
1076 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1077 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1078
1079 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001080 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001081 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001082 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001083 }
1084
Geoff Langaae65a42014-05-26 12:43:44 -04001085 const gl::Caps &caps = context->getCaps();
1086
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001087 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001088 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001089 case TextureType::_2D:
1090 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1091 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1092 {
1093 context->handleError(InvalidValue());
1094 return false;
1095 }
1096 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001097
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001098 case TextureType::Rectangle:
1099 ASSERT(level == 0);
1100 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1101 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1102 {
1103 context->handleError(InvalidValue());
1104 return false;
1105 }
1106 if (isCompressed)
1107 {
1108 context->handleError(InvalidEnum()
1109 << "Rectangle texture cannot have a compressed format.");
1110 return false;
1111 }
1112 break;
1113
1114 case TextureType::CubeMap:
1115 if (!isSubImage && width != height)
1116 {
1117 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1118 return false;
1119 }
1120
1121 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1122 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1123 {
1124 context->handleError(InvalidValue());
1125 return false;
1126 }
1127 break;
1128
1129 default:
1130 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001131 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001132 }
1133
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001134 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001135 if (!texture)
1136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001137 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001138 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001139 }
1140
Geoff Langa9be0dc2014-12-17 12:34:40 -05001141 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001142 {
Geoff Langca271392017-04-05 12:30:00 -04001143 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1144 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001145 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001146 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001147 return false;
1148 }
1149
Geoff Langa9be0dc2014-12-17 12:34:40 -05001150 if (format != GL_NONE)
1151 {
Geoff Langca271392017-04-05 12:30:00 -04001152 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1153 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001154 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001155 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001156 return false;
1157 }
1158 }
1159
1160 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1161 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001163 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001164 return false;
1165 }
Geoff Langfb052642017-10-24 13:42:09 -04001166
1167 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001168 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001169 {
1170 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1171 return false;
1172 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001173 }
1174 else
1175 {
Geoff Lang69cce582015-09-17 13:20:36 -04001176 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001177 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001178 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001179 return false;
1180 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001181 }
1182
1183 // Verify zero border
1184 if (border != 0)
1185 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001186 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001187 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001188 }
1189
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001190 if (isCompressed)
1191 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001192 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001193 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1194 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001195 switch (actualInternalFormat)
1196 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001197 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1198 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1199 if (!context->getExtensions().textureCompressionDXT1)
1200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001201 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001202 return false;
1203 }
1204 break;
1205 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001206 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001207 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001208 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001209 return false;
1210 }
1211 break;
1212 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1213 if (!context->getExtensions().textureCompressionDXT5)
1214 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001215 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001216 return false;
1217 }
1218 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001219 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1220 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1221 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1222 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1223 if (!context->getExtensions().textureCompressionS3TCsRGB)
1224 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001225 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001226 return false;
1227 }
1228 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001229 case GL_ETC1_RGB8_OES:
1230 if (!context->getExtensions().compressedETC1RGB8Texture)
1231 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001232 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001233 return false;
1234 }
Geoff Lang86f81162017-10-30 15:10:45 -04001235 if (isSubImage)
1236 {
1237 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1238 return false;
1239 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001240 break;
1241 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001242 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1243 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1244 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1245 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001246 if (!context->getExtensions().lossyETCDecode)
1247 {
Geoff Lang86f81162017-10-30 15:10:45 -04001248 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001249 return false;
1250 }
1251 break;
1252 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001253 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001254 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001255 }
Geoff Lang966c9402017-04-18 12:38:27 -04001256
1257 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001258 {
Geoff Lang966c9402017-04-18 12:38:27 -04001259 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1260 height, texture->getWidth(target, level),
1261 texture->getHeight(target, level)))
1262 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001263 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001264 return false;
1265 }
1266
1267 if (format != actualInternalFormat)
1268 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001269 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001270 return false;
1271 }
1272 }
1273 else
1274 {
1275 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1276 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001277 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001278 return false;
1279 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001280 }
1281 }
1282 else
1283 {
1284 // validate <type> by itself (used as secondary key below)
1285 switch (type)
1286 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001287 case GL_UNSIGNED_BYTE:
1288 case GL_UNSIGNED_SHORT_5_6_5:
1289 case GL_UNSIGNED_SHORT_4_4_4_4:
1290 case GL_UNSIGNED_SHORT_5_5_5_1:
1291 case GL_UNSIGNED_SHORT:
1292 case GL_UNSIGNED_INT:
1293 case GL_UNSIGNED_INT_24_8_OES:
1294 case GL_HALF_FLOAT_OES:
1295 case GL_FLOAT:
1296 break;
1297 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001298 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001299 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001300 }
1301
1302 // validate <format> + <type> combinations
1303 // - invalid <format> -> sets INVALID_ENUM
1304 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1305 switch (format)
1306 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001307 case GL_ALPHA:
1308 case GL_LUMINANCE:
1309 case GL_LUMINANCE_ALPHA:
1310 switch (type)
1311 {
1312 case GL_UNSIGNED_BYTE:
1313 case GL_FLOAT:
1314 case GL_HALF_FLOAT_OES:
1315 break;
1316 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001317 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001318 return false;
1319 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001320 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001321 case GL_RED:
1322 case GL_RG:
1323 if (!context->getExtensions().textureRG)
1324 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001325 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001326 return false;
1327 }
1328 switch (type)
1329 {
1330 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001331 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001332 case GL_FLOAT:
1333 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001334 if (!context->getExtensions().textureFloat)
1335 {
1336 context->handleError(InvalidEnum());
1337 return false;
1338 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001339 break;
1340 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001341 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001342 return false;
1343 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001344 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001345 case GL_RGB:
1346 switch (type)
1347 {
1348 case GL_UNSIGNED_BYTE:
1349 case GL_UNSIGNED_SHORT_5_6_5:
1350 case GL_FLOAT:
1351 case GL_HALF_FLOAT_OES:
1352 break;
1353 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001355 return false;
1356 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001357 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001358 case GL_RGBA:
1359 switch (type)
1360 {
1361 case GL_UNSIGNED_BYTE:
1362 case GL_UNSIGNED_SHORT_4_4_4_4:
1363 case GL_UNSIGNED_SHORT_5_5_5_1:
1364 case GL_FLOAT:
1365 case GL_HALF_FLOAT_OES:
1366 break;
1367 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 return false;
1370 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001371 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001372 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001373 if (!context->getExtensions().textureFormatBGRA8888)
1374 {
1375 context->handleError(InvalidEnum());
1376 return false;
1377 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001378 switch (type)
1379 {
1380 case GL_UNSIGNED_BYTE:
1381 break;
1382 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001383 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001384 return false;
1385 }
1386 break;
1387 case GL_SRGB_EXT:
1388 case GL_SRGB_ALPHA_EXT:
1389 if (!context->getExtensions().sRGB)
1390 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001391 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001392 return false;
1393 }
1394 switch (type)
1395 {
1396 case GL_UNSIGNED_BYTE:
1397 break;
1398 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001400 return false;
1401 }
1402 break;
1403 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1404 // handled below
1405 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1406 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1407 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1408 break;
1409 case GL_DEPTH_COMPONENT:
1410 switch (type)
1411 {
1412 case GL_UNSIGNED_SHORT:
1413 case GL_UNSIGNED_INT:
1414 break;
1415 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001416 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001417 return false;
1418 }
1419 break;
1420 case GL_DEPTH_STENCIL_OES:
1421 switch (type)
1422 {
1423 case GL_UNSIGNED_INT_24_8_OES:
1424 break;
1425 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001426 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001427 return false;
1428 }
1429 break;
1430 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001431 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001432 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001433 }
1434
1435 switch (format)
1436 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001437 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1438 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1439 if (context->getExtensions().textureCompressionDXT1)
1440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001441 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001442 return false;
1443 }
1444 else
1445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001446 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001447 return false;
1448 }
1449 break;
1450 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1451 if (context->getExtensions().textureCompressionDXT3)
1452 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001453 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001454 return false;
1455 }
1456 else
1457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001458 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001459 return false;
1460 }
1461 break;
1462 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1463 if (context->getExtensions().textureCompressionDXT5)
1464 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001465 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001466 return false;
1467 }
1468 else
1469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001470 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001471 return false;
1472 }
1473 break;
1474 case GL_ETC1_RGB8_OES:
1475 if (context->getExtensions().compressedETC1RGB8Texture)
1476 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001477 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001478 return false;
1479 }
1480 else
1481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001482 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001483 return false;
1484 }
1485 break;
1486 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001487 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1488 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1489 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1490 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001491 if (context->getExtensions().lossyETCDecode)
1492 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001493 context->handleError(InvalidOperation()
1494 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001495 return false;
1496 }
1497 else
1498 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001499 context->handleError(InvalidEnum()
1500 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001501 return false;
1502 }
1503 break;
1504 case GL_DEPTH_COMPONENT:
1505 case GL_DEPTH_STENCIL_OES:
1506 if (!context->getExtensions().depthTextures)
1507 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001508 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001509 return false;
1510 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001511 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001512 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001513 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001514 return false;
1515 }
1516 // OES_depth_texture supports loading depth data and multiple levels,
1517 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001518 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001519 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001520 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1521 return false;
1522 }
1523 if (level != 0)
1524 {
1525 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001526 return false;
1527 }
1528 break;
1529 default:
1530 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001531 }
1532
Geoff Lang6e898aa2017-06-02 11:17:26 -04001533 if (!isSubImage)
1534 {
1535 switch (internalformat)
1536 {
1537 case GL_RGBA32F:
1538 if (!context->getExtensions().colorBufferFloatRGBA)
1539 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001540 context->handleError(InvalidValue()
1541 << "Sized GL_RGBA32F internal format requires "
1542 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001543 return false;
1544 }
1545 if (type != GL_FLOAT)
1546 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001547 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001548 return false;
1549 }
1550 if (format != GL_RGBA)
1551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001552 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001553 return false;
1554 }
1555 break;
1556
1557 case GL_RGB32F:
1558 if (!context->getExtensions().colorBufferFloatRGB)
1559 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001560 context->handleError(InvalidValue()
1561 << "Sized GL_RGB32F internal format requires "
1562 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001563 return false;
1564 }
1565 if (type != GL_FLOAT)
1566 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001567 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001568 return false;
1569 }
1570 if (format != GL_RGB)
1571 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001572 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001573 return false;
1574 }
1575 break;
1576
1577 default:
1578 break;
1579 }
1580 }
1581
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001582 if (type == GL_FLOAT)
1583 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001584 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001585 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001586 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001587 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001588 }
1589 }
1590 else if (type == GL_HALF_FLOAT_OES)
1591 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001592 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001593 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001594 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001595 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001596 }
1597 }
1598 }
1599
Geoff Langdbcced82017-06-06 15:55:54 -04001600 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001601 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001602 imageSize))
1603 {
1604 return false;
1605 }
1606
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001607 return true;
1608}
1609
He Yunchaoced53ae2016-11-29 15:00:51 +08001610bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001611 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001612 GLsizei levels,
1613 GLenum internalformat,
1614 GLsizei width,
1615 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001616{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001617 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1618 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001619 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001620 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001621 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001622 }
1623
1624 if (width < 1 || height < 1 || levels < 1)
1625 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001626 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001627 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001628 }
1629
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001630 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001631 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001632 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001633 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001634 }
1635
1636 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1637 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001638 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001639 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001640 }
1641
Geoff Langca271392017-04-05 12:30:00 -04001642 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001643 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001644 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001645 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001646 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001647 }
1648
Geoff Langaae65a42014-05-26 12:43:44 -04001649 const gl::Caps &caps = context->getCaps();
1650
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001651 switch (target)
1652 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001653 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001654 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1655 static_cast<GLuint>(height) > caps.max2DTextureSize)
1656 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001657 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001658 return false;
1659 }
1660 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001661 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001662 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1663 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1664 {
1665 context->handleError(InvalidValue());
1666 return false;
1667 }
1668 if (formatInfo.compressed)
1669 {
1670 context->handleError(InvalidEnum()
1671 << "Rectangle texture cannot have a compressed format.");
1672 return false;
1673 }
1674 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001675 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001676 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1677 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1678 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001679 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001680 return false;
1681 }
1682 break;
1683 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001684 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001685 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001686 }
1687
Geoff Langc0b9ef42014-07-02 10:02:37 -04001688 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001689 {
1690 if (!gl::isPow2(width) || !gl::isPow2(height))
1691 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001692 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001693 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001694 }
1695 }
1696
1697 switch (internalformat)
1698 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001699 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1700 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1701 if (!context->getExtensions().textureCompressionDXT1)
1702 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001703 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001704 return false;
1705 }
1706 break;
1707 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1708 if (!context->getExtensions().textureCompressionDXT3)
1709 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001710 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001711 return false;
1712 }
1713 break;
1714 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1715 if (!context->getExtensions().textureCompressionDXT5)
1716 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001717 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001718 return false;
1719 }
1720 break;
1721 case GL_ETC1_RGB8_OES:
1722 if (!context->getExtensions().compressedETC1RGB8Texture)
1723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001724 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001725 return false;
1726 }
1727 break;
1728 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001729 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1730 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1731 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1732 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001733 if (!context->getExtensions().lossyETCDecode)
1734 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001735 context->handleError(InvalidEnum()
1736 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001737 return false;
1738 }
1739 break;
1740 case GL_RGBA32F_EXT:
1741 case GL_RGB32F_EXT:
1742 case GL_ALPHA32F_EXT:
1743 case GL_LUMINANCE32F_EXT:
1744 case GL_LUMINANCE_ALPHA32F_EXT:
1745 if (!context->getExtensions().textureFloat)
1746 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001747 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001748 return false;
1749 }
1750 break;
1751 case GL_RGBA16F_EXT:
1752 case GL_RGB16F_EXT:
1753 case GL_ALPHA16F_EXT:
1754 case GL_LUMINANCE16F_EXT:
1755 case GL_LUMINANCE_ALPHA16F_EXT:
1756 if (!context->getExtensions().textureHalfFloat)
1757 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001758 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001759 return false;
1760 }
1761 break;
1762 case GL_R8_EXT:
1763 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001764 if (!context->getExtensions().textureRG)
1765 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001766 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001767 return false;
1768 }
1769 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001770 case GL_R16F_EXT:
1771 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001772 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1773 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001774 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001775 return false;
1776 }
1777 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001778 case GL_R32F_EXT:
1779 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001780 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001781 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001782 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001783 return false;
1784 }
1785 break;
1786 case GL_DEPTH_COMPONENT16:
1787 case GL_DEPTH_COMPONENT32_OES:
1788 case GL_DEPTH24_STENCIL8_OES:
1789 if (!context->getExtensions().depthTextures)
1790 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001791 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001792 return false;
1793 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001794 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001795 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001796 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001797 return false;
1798 }
1799 // ANGLE_depth_texture only supports 1-level textures
1800 if (levels != 1)
1801 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001802 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001803 return false;
1804 }
1805 break;
1806 default:
1807 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001808 }
1809
Geoff Lang691e58c2014-12-19 17:03:25 -05001810 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001811 if (!texture || texture->id() == 0)
1812 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001813 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001814 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001815 }
1816
Geoff Lang69cce582015-09-17 13:20:36 -04001817 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001818 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001819 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001820 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001821 }
1822
1823 return true;
1824}
1825
He Yunchaoced53ae2016-11-29 15:00:51 +08001826bool ValidateDiscardFramebufferEXT(Context *context,
1827 GLenum target,
1828 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001829 const GLenum *attachments)
1830{
Jamie Madillc29968b2016-01-20 11:17:23 -05001831 if (!context->getExtensions().discardFramebuffer)
1832 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001833 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001834 return false;
1835 }
1836
Austin Kinross08332632015-05-05 13:35:47 -07001837 bool defaultFramebuffer = false;
1838
1839 switch (target)
1840 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001841 case GL_FRAMEBUFFER:
1842 defaultFramebuffer =
1843 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1844 break;
1845 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001846 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001847 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001848 }
1849
He Yunchaoced53ae2016-11-29 15:00:51 +08001850 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1851 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001852}
1853
Austin Kinrossbc781f32015-10-26 09:27:38 -07001854bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1855{
1856 if (!context->getExtensions().vertexArrayObject)
1857 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001858 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001859 return false;
1860 }
1861
1862 return ValidateBindVertexArrayBase(context, array);
1863}
1864
Jamie Madilld7576732017-08-26 18:49:50 -04001865bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001866{
1867 if (!context->getExtensions().vertexArrayObject)
1868 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001869 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870 return false;
1871 }
1872
Olli Etuaho41997e72016-03-10 13:38:39 +02001873 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001874}
1875
Jamie Madilld7576732017-08-26 18:49:50 -04001876bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001877{
1878 if (!context->getExtensions().vertexArrayObject)
1879 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001880 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001881 return false;
1882 }
1883
Olli Etuaho41997e72016-03-10 13:38:39 +02001884 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001885}
1886
Jamie Madilld7576732017-08-26 18:49:50 -04001887bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001888{
1889 if (!context->getExtensions().vertexArrayObject)
1890 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001891 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001892 return false;
1893 }
1894
1895 return true;
1896}
Geoff Langc5629752015-12-07 16:29:04 -05001897
1898bool ValidateProgramBinaryOES(Context *context,
1899 GLuint program,
1900 GLenum binaryFormat,
1901 const void *binary,
1902 GLint length)
1903{
1904 if (!context->getExtensions().getProgramBinary)
1905 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001906 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001907 return false;
1908 }
1909
1910 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1911}
1912
1913bool ValidateGetProgramBinaryOES(Context *context,
1914 GLuint program,
1915 GLsizei bufSize,
1916 GLsizei *length,
1917 GLenum *binaryFormat,
1918 void *binary)
1919{
1920 if (!context->getExtensions().getProgramBinary)
1921 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001922 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001923 return false;
1924 }
1925
1926 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1927}
Geoff Lange102fee2015-12-10 11:23:30 -05001928
Geoff Lang70d0f492015-12-10 17:45:46 -05001929static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1930{
1931 switch (source)
1932 {
1933 case GL_DEBUG_SOURCE_API:
1934 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1935 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1936 case GL_DEBUG_SOURCE_OTHER:
1937 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1938 return !mustBeThirdPartyOrApplication;
1939
1940 case GL_DEBUG_SOURCE_THIRD_PARTY:
1941 case GL_DEBUG_SOURCE_APPLICATION:
1942 return true;
1943
1944 default:
1945 return false;
1946 }
1947}
1948
1949static bool ValidDebugType(GLenum type)
1950{
1951 switch (type)
1952 {
1953 case GL_DEBUG_TYPE_ERROR:
1954 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1955 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1956 case GL_DEBUG_TYPE_PERFORMANCE:
1957 case GL_DEBUG_TYPE_PORTABILITY:
1958 case GL_DEBUG_TYPE_OTHER:
1959 case GL_DEBUG_TYPE_MARKER:
1960 case GL_DEBUG_TYPE_PUSH_GROUP:
1961 case GL_DEBUG_TYPE_POP_GROUP:
1962 return true;
1963
1964 default:
1965 return false;
1966 }
1967}
1968
1969static bool ValidDebugSeverity(GLenum severity)
1970{
1971 switch (severity)
1972 {
1973 case GL_DEBUG_SEVERITY_HIGH:
1974 case GL_DEBUG_SEVERITY_MEDIUM:
1975 case GL_DEBUG_SEVERITY_LOW:
1976 case GL_DEBUG_SEVERITY_NOTIFICATION:
1977 return true;
1978
1979 default:
1980 return false;
1981 }
1982}
1983
Geoff Lange102fee2015-12-10 11:23:30 -05001984bool ValidateDebugMessageControlKHR(Context *context,
1985 GLenum source,
1986 GLenum type,
1987 GLenum severity,
1988 GLsizei count,
1989 const GLuint *ids,
1990 GLboolean enabled)
1991{
1992 if (!context->getExtensions().debug)
1993 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001994 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001995 return false;
1996 }
1997
Geoff Lang70d0f492015-12-10 17:45:46 -05001998 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1999 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002000 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002001 return false;
2002 }
2003
2004 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2005 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002006 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002007 return false;
2008 }
2009
2010 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2011 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002012 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002013 return false;
2014 }
2015
2016 if (count > 0)
2017 {
2018 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2019 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002020 context->handleError(
2021 InvalidOperation()
2022 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002023 return false;
2024 }
2025
2026 if (severity != GL_DONT_CARE)
2027 {
Jamie Madill437fa652016-05-03 15:13:24 -04002028 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002029 InvalidOperation()
2030 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002031 return false;
2032 }
2033 }
2034
Geoff Lange102fee2015-12-10 11:23:30 -05002035 return true;
2036}
2037
2038bool ValidateDebugMessageInsertKHR(Context *context,
2039 GLenum source,
2040 GLenum type,
2041 GLuint id,
2042 GLenum severity,
2043 GLsizei length,
2044 const GLchar *buf)
2045{
2046 if (!context->getExtensions().debug)
2047 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002048 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002049 return false;
2050 }
2051
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002052 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002053 {
2054 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2055 // not generate an error.
2056 return false;
2057 }
2058
2059 if (!ValidDebugSeverity(severity))
2060 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002061 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002062 return false;
2063 }
2064
2065 if (!ValidDebugType(type))
2066 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002067 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002068 return false;
2069 }
2070
2071 if (!ValidDebugSource(source, true))
2072 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002073 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002074 return false;
2075 }
2076
2077 size_t messageLength = (length < 0) ? strlen(buf) : length;
2078 if (messageLength > context->getExtensions().maxDebugMessageLength)
2079 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002080 context->handleError(InvalidValue()
2081 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002082 return false;
2083 }
2084
Geoff Lange102fee2015-12-10 11:23:30 -05002085 return true;
2086}
2087
2088bool ValidateDebugMessageCallbackKHR(Context *context,
2089 GLDEBUGPROCKHR callback,
2090 const void *userParam)
2091{
2092 if (!context->getExtensions().debug)
2093 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002094 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002095 return false;
2096 }
2097
Geoff Lange102fee2015-12-10 11:23:30 -05002098 return true;
2099}
2100
2101bool ValidateGetDebugMessageLogKHR(Context *context,
2102 GLuint count,
2103 GLsizei bufSize,
2104 GLenum *sources,
2105 GLenum *types,
2106 GLuint *ids,
2107 GLenum *severities,
2108 GLsizei *lengths,
2109 GLchar *messageLog)
2110{
2111 if (!context->getExtensions().debug)
2112 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002113 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002114 return false;
2115 }
2116
Geoff Lang70d0f492015-12-10 17:45:46 -05002117 if (bufSize < 0 && messageLog != nullptr)
2118 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002119 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002120 return false;
2121 }
2122
Geoff Lange102fee2015-12-10 11:23:30 -05002123 return true;
2124}
2125
2126bool ValidatePushDebugGroupKHR(Context *context,
2127 GLenum source,
2128 GLuint id,
2129 GLsizei length,
2130 const GLchar *message)
2131{
2132 if (!context->getExtensions().debug)
2133 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002134 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002135 return false;
2136 }
2137
Geoff Lang70d0f492015-12-10 17:45:46 -05002138 if (!ValidDebugSource(source, true))
2139 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002140 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002141 return false;
2142 }
2143
2144 size_t messageLength = (length < 0) ? strlen(message) : length;
2145 if (messageLength > context->getExtensions().maxDebugMessageLength)
2146 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002147 context->handleError(InvalidValue()
2148 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002149 return false;
2150 }
2151
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002152 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002153 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002155 context
2156 ->handleError(StackOverflow()
2157 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002158 return false;
2159 }
2160
Geoff Lange102fee2015-12-10 11:23:30 -05002161 return true;
2162}
2163
2164bool ValidatePopDebugGroupKHR(Context *context)
2165{
2166 if (!context->getExtensions().debug)
2167 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002168 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002169 return false;
2170 }
2171
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002172 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002173 if (currentStackSize <= 1)
2174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002175 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002176 return false;
2177 }
2178
2179 return true;
2180}
2181
2182static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2183{
2184 switch (identifier)
2185 {
2186 case GL_BUFFER:
2187 if (context->getBuffer(name) == nullptr)
2188 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002189 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002190 return false;
2191 }
2192 return true;
2193
2194 case GL_SHADER:
2195 if (context->getShader(name) == nullptr)
2196 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002197 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002198 return false;
2199 }
2200 return true;
2201
2202 case GL_PROGRAM:
2203 if (context->getProgram(name) == nullptr)
2204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002205 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002206 return false;
2207 }
2208 return true;
2209
2210 case GL_VERTEX_ARRAY:
2211 if (context->getVertexArray(name) == nullptr)
2212 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002213 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002214 return false;
2215 }
2216 return true;
2217
2218 case GL_QUERY:
2219 if (context->getQuery(name) == nullptr)
2220 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002221 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002222 return false;
2223 }
2224 return true;
2225
2226 case GL_TRANSFORM_FEEDBACK:
2227 if (context->getTransformFeedback(name) == nullptr)
2228 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002229 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002230 return false;
2231 }
2232 return true;
2233
2234 case GL_SAMPLER:
2235 if (context->getSampler(name) == nullptr)
2236 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002237 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002238 return false;
2239 }
2240 return true;
2241
2242 case GL_TEXTURE:
2243 if (context->getTexture(name) == nullptr)
2244 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002245 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002246 return false;
2247 }
2248 return true;
2249
2250 case GL_RENDERBUFFER:
2251 if (context->getRenderbuffer(name) == nullptr)
2252 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002253 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002254 return false;
2255 }
2256 return true;
2257
2258 case GL_FRAMEBUFFER:
2259 if (context->getFramebuffer(name) == nullptr)
2260 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002261 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002262 return false;
2263 }
2264 return true;
2265
2266 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002267 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002268 return false;
2269 }
Geoff Lange102fee2015-12-10 11:23:30 -05002270}
2271
Martin Radev9d901792016-07-15 15:58:58 +03002272static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2273{
2274 size_t labelLength = 0;
2275
2276 if (length < 0)
2277 {
2278 if (label != nullptr)
2279 {
2280 labelLength = strlen(label);
2281 }
2282 }
2283 else
2284 {
2285 labelLength = static_cast<size_t>(length);
2286 }
2287
2288 if (labelLength > context->getExtensions().maxLabelLength)
2289 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002290 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002291 return false;
2292 }
2293
2294 return true;
2295}
2296
Geoff Lange102fee2015-12-10 11:23:30 -05002297bool ValidateObjectLabelKHR(Context *context,
2298 GLenum identifier,
2299 GLuint name,
2300 GLsizei length,
2301 const GLchar *label)
2302{
2303 if (!context->getExtensions().debug)
2304 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002306 return false;
2307 }
2308
Geoff Lang70d0f492015-12-10 17:45:46 -05002309 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2310 {
2311 return false;
2312 }
2313
Martin Radev9d901792016-07-15 15:58:58 +03002314 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002315 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002316 return false;
2317 }
2318
Geoff Lange102fee2015-12-10 11:23:30 -05002319 return true;
2320}
2321
2322bool ValidateGetObjectLabelKHR(Context *context,
2323 GLenum identifier,
2324 GLuint name,
2325 GLsizei bufSize,
2326 GLsizei *length,
2327 GLchar *label)
2328{
2329 if (!context->getExtensions().debug)
2330 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002331 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002332 return false;
2333 }
2334
Geoff Lang70d0f492015-12-10 17:45:46 -05002335 if (bufSize < 0)
2336 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002337 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002338 return false;
2339 }
2340
2341 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2342 {
2343 return false;
2344 }
2345
Martin Radev9d901792016-07-15 15:58:58 +03002346 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002347}
2348
2349static bool ValidateObjectPtrName(Context *context, const void *ptr)
2350{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002351 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002352 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002353 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002354 return false;
2355 }
2356
Geoff Lange102fee2015-12-10 11:23:30 -05002357 return true;
2358}
2359
2360bool ValidateObjectPtrLabelKHR(Context *context,
2361 const void *ptr,
2362 GLsizei length,
2363 const GLchar *label)
2364{
2365 if (!context->getExtensions().debug)
2366 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002367 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002368 return false;
2369 }
2370
Geoff Lang70d0f492015-12-10 17:45:46 -05002371 if (!ValidateObjectPtrName(context, ptr))
2372 {
2373 return false;
2374 }
2375
Martin Radev9d901792016-07-15 15:58:58 +03002376 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002377 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002378 return false;
2379 }
2380
Geoff Lange102fee2015-12-10 11:23:30 -05002381 return true;
2382}
2383
2384bool ValidateGetObjectPtrLabelKHR(Context *context,
2385 const void *ptr,
2386 GLsizei bufSize,
2387 GLsizei *length,
2388 GLchar *label)
2389{
2390 if (!context->getExtensions().debug)
2391 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002392 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002393 return false;
2394 }
2395
Geoff Lang70d0f492015-12-10 17:45:46 -05002396 if (bufSize < 0)
2397 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002398 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002399 return false;
2400 }
2401
2402 if (!ValidateObjectPtrName(context, ptr))
2403 {
2404 return false;
2405 }
2406
Martin Radev9d901792016-07-15 15:58:58 +03002407 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002408}
2409
2410bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2411{
2412 if (!context->getExtensions().debug)
2413 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002414 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002415 return false;
2416 }
2417
Geoff Lang70d0f492015-12-10 17:45:46 -05002418 // TODO: represent this in Context::getQueryParameterInfo.
2419 switch (pname)
2420 {
2421 case GL_DEBUG_CALLBACK_FUNCTION:
2422 case GL_DEBUG_CALLBACK_USER_PARAM:
2423 break;
2424
2425 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002426 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002427 return false;
2428 }
2429
Geoff Lange102fee2015-12-10 11:23:30 -05002430 return true;
2431}
Jamie Madillc29968b2016-01-20 11:17:23 -05002432
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002433bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2434 GLenum pname,
2435 GLsizei bufSize,
2436 GLsizei *length,
2437 void **params)
2438{
2439 UNIMPLEMENTED();
2440 return false;
2441}
2442
Jamie Madillc29968b2016-01-20 11:17:23 -05002443bool ValidateBlitFramebufferANGLE(Context *context,
2444 GLint srcX0,
2445 GLint srcY0,
2446 GLint srcX1,
2447 GLint srcY1,
2448 GLint dstX0,
2449 GLint dstY0,
2450 GLint dstX1,
2451 GLint dstY1,
2452 GLbitfield mask,
2453 GLenum filter)
2454{
2455 if (!context->getExtensions().framebufferBlit)
2456 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002457 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002458 return false;
2459 }
2460
2461 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2462 {
2463 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002464 context->handleError(InvalidOperation() << "Scaling and flipping in "
2465 "BlitFramebufferANGLE not supported by this "
2466 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002467 return false;
2468 }
2469
2470 if (filter == GL_LINEAR)
2471 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002472 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002473 return false;
2474 }
2475
Jamie Madill51f40ec2016-06-15 14:06:00 -04002476 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2477 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002478
2479 if (mask & GL_COLOR_BUFFER_BIT)
2480 {
2481 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2482 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2483
2484 if (readColorAttachment && drawColorAttachment)
2485 {
2486 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002487 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002488 readColorAttachment->type() != GL_RENDERBUFFER &&
2489 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2490 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002491 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002492 return false;
2493 }
2494
Geoff Langa15472a2015-08-11 11:48:03 -04002495 for (size_t drawbufferIdx = 0;
2496 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002497 {
Geoff Langa15472a2015-08-11 11:48:03 -04002498 const FramebufferAttachment *attachment =
2499 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2500 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002501 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002502 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002503 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002504 attachment->type() != GL_RENDERBUFFER &&
2505 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2506 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002507 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002508 return false;
2509 }
2510
2511 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002512 if (!Format::EquivalentForBlit(attachment->getFormat(),
2513 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002514 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002515 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002516 return false;
2517 }
2518 }
2519 }
2520
Jamie Madill427064d2018-04-13 16:20:34 -04002521 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002522 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002523 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2524 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2525 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002526 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002527 return false;
2528 }
2529 }
2530 }
2531
2532 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2533 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2534 for (size_t i = 0; i < 2; i++)
2535 {
2536 if (mask & masks[i])
2537 {
2538 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002539 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002540 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002541 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002542
2543 if (readBuffer && drawBuffer)
2544 {
2545 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2546 dstX0, dstY0, dstX1, dstY1))
2547 {
2548 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002549 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2550 "stencil blits are supported by "
2551 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002552 return false;
2553 }
2554
2555 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2556 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002557 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002558 return false;
2559 }
2560 }
2561 }
2562 }
2563
2564 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2565 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002566}
Jamie Madillc29968b2016-01-20 11:17:23 -05002567
Jamie Madill5b772312018-03-08 20:28:32 -05002568bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002569{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002570 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002571
Jamie Madill427064d2018-04-13 16:20:34 -04002572 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002573 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002574 return false;
2575 }
2576
2577 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2578 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002579 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002580 return false;
2581 }
2582
Geoff Lang76e65652017-03-27 14:58:02 -04002583 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2584 {
2585 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2586 GL_SIGNED_NORMALIZED};
2587
Corentin Wallez59c41592017-07-11 13:19:54 -04002588 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002589 drawBufferIdx++)
2590 {
2591 if (!ValidateWebGLFramebufferAttachmentClearType(
2592 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2593 {
2594 return false;
2595 }
2596 }
2597 }
2598
Jamie Madillc29968b2016-01-20 11:17:23 -05002599 return true;
2600}
2601
Jamie Madill5b772312018-03-08 20:28:32 -05002602bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002603{
2604 if (!context->getExtensions().drawBuffers)
2605 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002606 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002607 return false;
2608 }
2609
2610 return ValidateDrawBuffersBase(context, n, bufs);
2611}
2612
Jamie Madill73a84962016-02-12 09:27:23 -05002613bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002614 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002615 GLint level,
2616 GLint internalformat,
2617 GLsizei width,
2618 GLsizei height,
2619 GLint border,
2620 GLenum format,
2621 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002622 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002623{
Martin Radev1be913c2016-07-11 17:59:16 +03002624 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002625 {
2626 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002627 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002628 }
2629
Martin Radev1be913c2016-07-11 17:59:16 +03002630 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002631 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002632 0, 0, width, height, 1, border, format, type, -1,
2633 pixels);
2634}
2635
Brandon Jones416aaf92018-04-10 08:10:16 -07002636bool ValidateTexImage2DRobustANGLE(Context *context,
2637 TextureTarget target,
2638 GLint level,
2639 GLint internalformat,
2640 GLsizei width,
2641 GLsizei height,
2642 GLint border,
2643 GLenum format,
2644 GLenum type,
2645 GLsizei bufSize,
2646 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002647{
2648 if (!ValidateRobustEntryPoint(context, bufSize))
2649 {
2650 return false;
2651 }
2652
2653 if (context->getClientMajorVersion() < 3)
2654 {
2655 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2656 0, 0, width, height, border, format, type, bufSize,
2657 pixels);
2658 }
2659
2660 ASSERT(context->getClientMajorVersion() >= 3);
2661 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2662 0, 0, width, height, 1, border, format, type, bufSize,
2663 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002664}
2665
2666bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002667 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002668 GLint level,
2669 GLint xoffset,
2670 GLint yoffset,
2671 GLsizei width,
2672 GLsizei height,
2673 GLenum format,
2674 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002675 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002676{
2677
Martin Radev1be913c2016-07-11 17:59:16 +03002678 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002679 {
2680 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002681 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002682 }
2683
Martin Radev1be913c2016-07-11 17:59:16 +03002684 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002685 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002686 yoffset, 0, width, height, 1, 0, format, type, -1,
2687 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002688}
2689
Geoff Langc52f6f12016-10-14 10:18:00 -04002690bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002691 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002692 GLint level,
2693 GLint xoffset,
2694 GLint yoffset,
2695 GLsizei width,
2696 GLsizei height,
2697 GLenum format,
2698 GLenum type,
2699 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002700 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002701{
2702 if (!ValidateRobustEntryPoint(context, bufSize))
2703 {
2704 return false;
2705 }
2706
2707 if (context->getClientMajorVersion() < 3)
2708 {
2709 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2710 yoffset, width, height, 0, format, type, bufSize,
2711 pixels);
2712 }
2713
2714 ASSERT(context->getClientMajorVersion() >= 3);
2715 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2716 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2717 pixels);
2718}
2719
Jamie Madill73a84962016-02-12 09:27:23 -05002720bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002721 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002722 GLint level,
2723 GLenum internalformat,
2724 GLsizei width,
2725 GLsizei height,
2726 GLint border,
2727 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002728 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002729{
Martin Radev1be913c2016-07-11 17:59:16 +03002730 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002731 {
2732 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002733 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002734 {
2735 return false;
2736 }
2737 }
2738 else
2739 {
Martin Radev1be913c2016-07-11 17:59:16 +03002740 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002741 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002742 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002743 data))
2744 {
2745 return false;
2746 }
2747 }
2748
Geoff Langca271392017-04-05 12:30:00 -04002749 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002750 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002751 if (blockSizeOrErr.isError())
2752 {
2753 context->handleError(blockSizeOrErr.getError());
2754 return false;
2755 }
2756
2757 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002758 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002759 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002760 return false;
2761 }
2762
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002763 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002764 {
2765 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2766 return false;
2767 }
2768
Jamie Madill73a84962016-02-12 09:27:23 -05002769 return true;
2770}
2771
Corentin Wallezb2931602017-04-11 15:58:57 -04002772bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002773 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002774 GLint level,
2775 GLenum internalformat,
2776 GLsizei width,
2777 GLsizei height,
2778 GLint border,
2779 GLsizei imageSize,
2780 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002781 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002782{
2783 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2784 {
2785 return false;
2786 }
2787
2788 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2789 border, imageSize, data);
2790}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002791
Corentin Wallezb2931602017-04-11 15:58:57 -04002792bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002793 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002794 GLint level,
2795 GLint xoffset,
2796 GLint yoffset,
2797 GLsizei width,
2798 GLsizei height,
2799 GLenum format,
2800 GLsizei imageSize,
2801 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002802 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002803{
2804 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2805 {
2806 return false;
2807 }
2808
2809 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2810 format, imageSize, data);
2811}
2812
Jamie Madill73a84962016-02-12 09:27:23 -05002813bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002814 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002815 GLint level,
2816 GLint xoffset,
2817 GLint yoffset,
2818 GLsizei width,
2819 GLsizei height,
2820 GLenum format,
2821 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002822 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002823{
Martin Radev1be913c2016-07-11 17:59:16 +03002824 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002825 {
2826 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002827 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002828 {
2829 return false;
2830 }
2831 }
2832 else
2833 {
Martin Radev1be913c2016-07-11 17:59:16 +03002834 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002835 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002836 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002837 data))
2838 {
2839 return false;
2840 }
2841 }
2842
Geoff Langca271392017-04-05 12:30:00 -04002843 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002844 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002845 if (blockSizeOrErr.isError())
2846 {
2847 context->handleError(blockSizeOrErr.getError());
2848 return false;
2849 }
2850
2851 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002852 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002853 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002854 return false;
2855 }
2856
2857 return true;
2858}
2859
Corentin Wallez336129f2017-10-17 15:55:40 -04002860bool ValidateGetBufferPointervOES(Context *context,
2861 BufferBinding target,
2862 GLenum pname,
2863 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002864{
Geoff Lang496c02d2016-10-20 11:38:11 -07002865 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002866}
2867
Corentin Wallez336129f2017-10-17 15:55:40 -04002868bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002869{
2870 if (!context->getExtensions().mapBuffer)
2871 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002872 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002873 return false;
2874 }
2875
Corentin Walleze4477002017-12-01 14:39:58 -05002876 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002877 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002878 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002879 return false;
2880 }
2881
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002882 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002883
2884 if (buffer == nullptr)
2885 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002886 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002887 return false;
2888 }
2889
2890 if (access != GL_WRITE_ONLY_OES)
2891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002892 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002893 return false;
2894 }
2895
2896 if (buffer->isMapped())
2897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002898 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002899 return false;
2900 }
2901
Geoff Lang79f71042017-08-14 16:43:43 -04002902 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002903}
2904
Corentin Wallez336129f2017-10-17 15:55:40 -04002905bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002906{
2907 if (!context->getExtensions().mapBuffer)
2908 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002909 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002910 return false;
2911 }
2912
2913 return ValidateUnmapBufferBase(context, target);
2914}
2915
2916bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002917 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002918 GLintptr offset,
2919 GLsizeiptr length,
2920 GLbitfield access)
2921{
2922 if (!context->getExtensions().mapBufferRange)
2923 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002924 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002925 return false;
2926 }
2927
2928 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2929}
2930
Corentin Wallez336129f2017-10-17 15:55:40 -04002931bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002932{
2933 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2934 ASSERT(buffer != nullptr);
2935
2936 // Check if this buffer is currently being used as a transform feedback output buffer
2937 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2938 if (transformFeedback != nullptr && transformFeedback->isActive())
2939 {
2940 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2941 {
2942 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2943 if (transformFeedbackBuffer.get() == buffer)
2944 {
2945 context->handleError(InvalidOperation()
2946 << "Buffer is currently bound for transform feedback.");
2947 return false;
2948 }
2949 }
2950 }
2951
James Darpiniane8a93c62018-01-04 18:02:24 -08002952 if (context->getExtensions().webglCompatibility &&
2953 buffer->isBoundForTransformFeedbackAndOtherUse())
2954 {
2955 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2956 return false;
2957 }
2958
Geoff Lang79f71042017-08-14 16:43:43 -04002959 return true;
2960}
2961
Olli Etuaho4f667482016-03-30 15:56:35 +03002962bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002963 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002964 GLintptr offset,
2965 GLsizeiptr length)
2966{
2967 if (!context->getExtensions().mapBufferRange)
2968 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002969 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002970 return false;
2971 }
2972
2973 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2974}
2975
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002976bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002977{
2978 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002979 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002980 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002981 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002982 return false;
2983 }
2984
Geoff Langf41a7152016-09-19 15:11:17 -04002985 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2986 !context->isTextureGenerated(texture))
2987 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002988 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002989 return false;
2990 }
2991
Ian Ewell54f87462016-03-10 13:47:21 -05002992 switch (target)
2993 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002994 case TextureType::_2D:
2995 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002996 break;
2997
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002998 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002999 if (!context->getExtensions().textureRectangle)
3000 {
3001 context->handleError(InvalidEnum()
3002 << "Context does not support GL_ANGLE_texture_rectangle");
3003 return false;
3004 }
3005 break;
3006
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003007 case TextureType::_3D:
3008 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03003009 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003010 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003011 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003012 return false;
3013 }
3014 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003015
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003016 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003017 if (context->getClientVersion() < Version(3, 1))
3018 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003019 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003020 return false;
3021 }
Geoff Lang3b573612016-10-31 14:08:10 -04003022 break;
3023
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003024 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003025 if (!context->getExtensions().eglImageExternal &&
3026 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003027 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003028 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003029 return false;
3030 }
3031 break;
3032 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003033 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003034 return false;
3035 }
3036
3037 return true;
3038}
3039
Geoff Langd8605522016-04-13 10:19:12 -04003040bool ValidateBindUniformLocationCHROMIUM(Context *context,
3041 GLuint program,
3042 GLint location,
3043 const GLchar *name)
3044{
3045 if (!context->getExtensions().bindUniformLocation)
3046 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003047 context->handleError(InvalidOperation()
3048 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003049 return false;
3050 }
3051
3052 Program *programObject = GetValidProgram(context, program);
3053 if (!programObject)
3054 {
3055 return false;
3056 }
3057
3058 if (location < 0)
3059 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003060 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003061 return false;
3062 }
3063
3064 const Caps &caps = context->getCaps();
3065 if (static_cast<size_t>(location) >=
3066 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3067 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003068 context->handleError(InvalidValue() << "Location must be less than "
3069 "(MAX_VERTEX_UNIFORM_VECTORS + "
3070 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003071 return false;
3072 }
3073
Geoff Langfc32e8b2017-05-31 14:16:59 -04003074 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3075 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003076 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003077 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003078 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003079 return false;
3080 }
3081
Geoff Langd8605522016-04-13 10:19:12 -04003082 if (strncmp(name, "gl_", 3) == 0)
3083 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003084 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003085 return false;
3086 }
3087
3088 return true;
3089}
3090
Jamie Madille2e406c2016-06-02 13:04:10 -04003091bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003092{
3093 if (!context->getExtensions().framebufferMixedSamples)
3094 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003095 context->handleError(InvalidOperation()
3096 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003097 return false;
3098 }
3099 switch (components)
3100 {
3101 case GL_RGB:
3102 case GL_RGBA:
3103 case GL_ALPHA:
3104 case GL_NONE:
3105 break;
3106 default:
3107 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003108 InvalidEnum()
3109 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003110 return false;
3111 }
3112
3113 return true;
3114}
3115
Sami Väisänene45e53b2016-05-25 10:36:04 +03003116// CHROMIUM_path_rendering
3117
Jamie Madill007530e2017-12-28 14:27:04 -05003118bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003119{
Jamie Madill007530e2017-12-28 14:27:04 -05003120 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003121 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003122 return false;
3123 }
Jamie Madill007530e2017-12-28 14:27:04 -05003124
Sami Väisänene45e53b2016-05-25 10:36:04 +03003125 if (matrix == nullptr)
3126 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003127 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003128 return false;
3129 }
Jamie Madill007530e2017-12-28 14:27:04 -05003130
Sami Väisänene45e53b2016-05-25 10:36:04 +03003131 return true;
3132}
3133
Jamie Madill007530e2017-12-28 14:27:04 -05003134bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003135{
Jamie Madill007530e2017-12-28 14:27:04 -05003136 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003137}
3138
Jamie Madill007530e2017-12-28 14:27:04 -05003139bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003140{
3141 if (!context->getExtensions().pathRendering)
3142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003143 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003144 return false;
3145 }
3146
3147 // range = 0 is undefined in NV_path_rendering.
3148 // we add stricter semantic check here and require a non zero positive range.
3149 if (range <= 0)
3150 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003151 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003152 return false;
3153 }
3154
3155 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003158 return false;
3159 }
3160
3161 return true;
3162}
3163
Jamie Madill007530e2017-12-28 14:27:04 -05003164bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003165{
3166 if (!context->getExtensions().pathRendering)
3167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003168 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003169 return false;
3170 }
3171
3172 // range = 0 is undefined in NV_path_rendering.
3173 // we add stricter semantic check here and require a non zero positive range.
3174 if (range <= 0)
3175 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003176 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003177 return false;
3178 }
3179
3180 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3181 checkedRange += range;
3182
3183 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3184 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003185 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003186 return false;
3187 }
3188 return true;
3189}
3190
Jamie Madill007530e2017-12-28 14:27:04 -05003191bool ValidatePathCommandsCHROMIUM(Context *context,
3192 GLuint path,
3193 GLsizei numCommands,
3194 const GLubyte *commands,
3195 GLsizei numCoords,
3196 GLenum coordType,
3197 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003198{
3199 if (!context->getExtensions().pathRendering)
3200 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003201 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003202 return false;
3203 }
Brandon Jones59770802018-04-02 13:18:42 -07003204 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003205 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003206 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003207 return false;
3208 }
3209
3210 if (numCommands < 0)
3211 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003212 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003213 return false;
3214 }
3215 else if (numCommands > 0)
3216 {
3217 if (!commands)
3218 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003219 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003220 return false;
3221 }
3222 }
3223
3224 if (numCoords < 0)
3225 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003226 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003227 return false;
3228 }
3229 else if (numCoords > 0)
3230 {
3231 if (!coords)
3232 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003233 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003234 return false;
3235 }
3236 }
3237
3238 std::uint32_t coordTypeSize = 0;
3239 switch (coordType)
3240 {
3241 case GL_BYTE:
3242 coordTypeSize = sizeof(GLbyte);
3243 break;
3244
3245 case GL_UNSIGNED_BYTE:
3246 coordTypeSize = sizeof(GLubyte);
3247 break;
3248
3249 case GL_SHORT:
3250 coordTypeSize = sizeof(GLshort);
3251 break;
3252
3253 case GL_UNSIGNED_SHORT:
3254 coordTypeSize = sizeof(GLushort);
3255 break;
3256
3257 case GL_FLOAT:
3258 coordTypeSize = sizeof(GLfloat);
3259 break;
3260
3261 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003262 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003263 return false;
3264 }
3265
3266 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3267 checkedSize += (coordTypeSize * numCoords);
3268 if (!checkedSize.IsValid())
3269 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003270 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003271 return false;
3272 }
3273
3274 // early return skips command data validation when it doesn't exist.
3275 if (!commands)
3276 return true;
3277
3278 GLsizei expectedNumCoords = 0;
3279 for (GLsizei i = 0; i < numCommands; ++i)
3280 {
3281 switch (commands[i])
3282 {
3283 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3284 break;
3285 case GL_MOVE_TO_CHROMIUM:
3286 case GL_LINE_TO_CHROMIUM:
3287 expectedNumCoords += 2;
3288 break;
3289 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3290 expectedNumCoords += 4;
3291 break;
3292 case GL_CUBIC_CURVE_TO_CHROMIUM:
3293 expectedNumCoords += 6;
3294 break;
3295 case GL_CONIC_CURVE_TO_CHROMIUM:
3296 expectedNumCoords += 5;
3297 break;
3298 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003299 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003300 return false;
3301 }
3302 }
3303 if (expectedNumCoords != numCoords)
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
3309 return true;
3310}
3311
Jamie Madill007530e2017-12-28 14:27:04 -05003312bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003313{
3314 if (!context->getExtensions().pathRendering)
3315 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003316 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317 return false;
3318 }
Brandon Jones59770802018-04-02 13:18:42 -07003319 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003320 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003321 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003322 return false;
3323 }
3324
3325 switch (pname)
3326 {
3327 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3328 if (value < 0.0f)
3329 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003330 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003331 return false;
3332 }
3333 break;
3334 case GL_PATH_END_CAPS_CHROMIUM:
3335 switch (static_cast<GLenum>(value))
3336 {
3337 case GL_FLAT_CHROMIUM:
3338 case GL_SQUARE_CHROMIUM:
3339 case GL_ROUND_CHROMIUM:
3340 break;
3341 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003342 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003343 return false;
3344 }
3345 break;
3346 case GL_PATH_JOIN_STYLE_CHROMIUM:
3347 switch (static_cast<GLenum>(value))
3348 {
3349 case GL_MITER_REVERT_CHROMIUM:
3350 case GL_BEVEL_CHROMIUM:
3351 case GL_ROUND_CHROMIUM:
3352 break;
3353 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003354 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003355 return false;
3356 }
Nico Weber41b072b2018-02-09 10:01:32 -05003357 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003358 case GL_PATH_MITER_LIMIT_CHROMIUM:
3359 if (value < 0.0f)
3360 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003361 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003362 return false;
3363 }
3364 break;
3365
3366 case GL_PATH_STROKE_BOUND_CHROMIUM:
3367 // no errors, only clamping.
3368 break;
3369
3370 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003371 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003372 return false;
3373 }
3374 return true;
3375}
3376
Jamie Madill007530e2017-12-28 14:27:04 -05003377bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3378{
3379 // TODO(jmadill): Use proper clamping cast.
3380 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3381}
3382
3383bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003384{
3385 if (!context->getExtensions().pathRendering)
3386 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003387 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003388 return false;
3389 }
3390
Brandon Jones59770802018-04-02 13:18:42 -07003391 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003392 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003394 return false;
3395 }
3396 if (!value)
3397 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003398 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003399 return false;
3400 }
3401
3402 switch (pname)
3403 {
3404 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3405 case GL_PATH_END_CAPS_CHROMIUM:
3406 case GL_PATH_JOIN_STYLE_CHROMIUM:
3407 case GL_PATH_MITER_LIMIT_CHROMIUM:
3408 case GL_PATH_STROKE_BOUND_CHROMIUM:
3409 break;
3410
3411 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003412 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003413 return false;
3414 }
3415
3416 return true;
3417}
3418
Jamie Madill007530e2017-12-28 14:27:04 -05003419bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3420{
3421 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3422 reinterpret_cast<GLfloat *>(value));
3423}
3424
3425bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003426{
3427 if (!context->getExtensions().pathRendering)
3428 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003429 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003430 return false;
3431 }
3432
3433 switch (func)
3434 {
3435 case GL_NEVER:
3436 case GL_ALWAYS:
3437 case GL_LESS:
3438 case GL_LEQUAL:
3439 case GL_EQUAL:
3440 case GL_GEQUAL:
3441 case GL_GREATER:
3442 case GL_NOTEQUAL:
3443 break;
3444 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003445 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003446 return false;
3447 }
3448
3449 return true;
3450}
3451
3452// Note that the spec specifies that for the path drawing commands
3453// if the path object is not an existing path object the command
3454// does nothing and no error is generated.
3455// However if the path object exists but has not been specified any
3456// commands then an error is generated.
3457
Jamie Madill007530e2017-12-28 14:27:04 -05003458bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003459{
3460 if (!context->getExtensions().pathRendering)
3461 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003462 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003463 return false;
3464 }
Brandon Jones59770802018-04-02 13:18:42 -07003465 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003466 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003467 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003468 return false;
3469 }
3470
3471 switch (fillMode)
3472 {
3473 case GL_COUNT_UP_CHROMIUM:
3474 case GL_COUNT_DOWN_CHROMIUM:
3475 break;
3476 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003477 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003478 return false;
3479 }
3480
3481 if (!isPow2(mask + 1))
3482 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003483 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003484 return false;
3485 }
3486
3487 return true;
3488}
3489
Jamie Madill007530e2017-12-28 14:27:04 -05003490bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003491{
3492 if (!context->getExtensions().pathRendering)
3493 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003494 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003495 return false;
3496 }
Brandon Jones59770802018-04-02 13:18:42 -07003497 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003498 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003499 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003500 return false;
3501 }
3502
3503 return true;
3504}
3505
Brandon Jonesd1049182018-03-28 10:02:20 -07003506bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3507{
3508 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3509}
3510
3511bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3512{
3513 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3514}
3515
Jamie Madill007530e2017-12-28 14:27:04 -05003516bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003517{
3518 if (!context->getExtensions().pathRendering)
3519 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003520 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003521 return false;
3522 }
Brandon Jones59770802018-04-02 13:18:42 -07003523 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003524 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003525 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003526 return false;
3527 }
3528
3529 switch (coverMode)
3530 {
3531 case GL_CONVEX_HULL_CHROMIUM:
3532 case GL_BOUNDING_BOX_CHROMIUM:
3533 break;
3534 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003535 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003536 return false;
3537 }
3538 return true;
3539}
3540
Jamie Madill007530e2017-12-28 14:27:04 -05003541bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3542 GLuint path,
3543 GLenum fillMode,
3544 GLuint mask,
3545 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546{
Jamie Madill007530e2017-12-28 14:27:04 -05003547 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3548 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003549}
3550
Jamie Madill007530e2017-12-28 14:27:04 -05003551bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3552 GLuint path,
3553 GLint reference,
3554 GLuint mask,
3555 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003556{
Jamie Madill007530e2017-12-28 14:27:04 -05003557 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3558 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003559}
3560
Brandon Jonesd1049182018-03-28 10:02:20 -07003561bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003562{
3563 if (!context->getExtensions().pathRendering)
3564 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003565 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003566 return false;
3567 }
3568 return true;
3569}
3570
Jamie Madill007530e2017-12-28 14:27:04 -05003571bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3572 GLsizei numPaths,
3573 GLenum pathNameType,
3574 const void *paths,
3575 GLuint pathBase,
3576 GLenum coverMode,
3577 GLenum transformType,
3578 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003579{
3580 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3581 transformType, transformValues))
3582 return false;
3583
3584 switch (coverMode)
3585 {
3586 case GL_CONVEX_HULL_CHROMIUM:
3587 case GL_BOUNDING_BOX_CHROMIUM:
3588 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3589 break;
3590 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003591 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003592 return false;
3593 }
3594
3595 return true;
3596}
3597
Jamie Madill007530e2017-12-28 14:27:04 -05003598bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3599 GLsizei numPaths,
3600 GLenum pathNameType,
3601 const void *paths,
3602 GLuint pathBase,
3603 GLenum coverMode,
3604 GLenum transformType,
3605 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003606{
3607 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3608 transformType, transformValues))
3609 return false;
3610
3611 switch (coverMode)
3612 {
3613 case GL_CONVEX_HULL_CHROMIUM:
3614 case GL_BOUNDING_BOX_CHROMIUM:
3615 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3616 break;
3617 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003618 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003619 return false;
3620 }
3621
3622 return true;
3623}
3624
Jamie Madill007530e2017-12-28 14:27:04 -05003625bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3626 GLsizei numPaths,
3627 GLenum pathNameType,
3628 const void *paths,
3629 GLuint pathBase,
3630 GLenum fillMode,
3631 GLuint mask,
3632 GLenum transformType,
3633 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003634{
3635
3636 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3637 transformType, transformValues))
3638 return false;
3639
3640 switch (fillMode)
3641 {
3642 case GL_COUNT_UP_CHROMIUM:
3643 case GL_COUNT_DOWN_CHROMIUM:
3644 break;
3645 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003646 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003647 return false;
3648 }
3649 if (!isPow2(mask + 1))
3650 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003651 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003652 return false;
3653 }
3654 return true;
3655}
3656
Jamie Madill007530e2017-12-28 14:27:04 -05003657bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3658 GLsizei numPaths,
3659 GLenum pathNameType,
3660 const void *paths,
3661 GLuint pathBase,
3662 GLint reference,
3663 GLuint mask,
3664 GLenum transformType,
3665 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003666{
3667 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3668 transformType, transformValues))
3669 return false;
3670
3671 // no more validation here.
3672
3673 return true;
3674}
3675
Jamie Madill007530e2017-12-28 14:27:04 -05003676bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3677 GLsizei numPaths,
3678 GLenum pathNameType,
3679 const void *paths,
3680 GLuint pathBase,
3681 GLenum fillMode,
3682 GLuint mask,
3683 GLenum coverMode,
3684 GLenum transformType,
3685 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003686{
3687 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3688 transformType, transformValues))
3689 return false;
3690
3691 switch (coverMode)
3692 {
3693 case GL_CONVEX_HULL_CHROMIUM:
3694 case GL_BOUNDING_BOX_CHROMIUM:
3695 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3696 break;
3697 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003698 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003699 return false;
3700 }
3701
3702 switch (fillMode)
3703 {
3704 case GL_COUNT_UP_CHROMIUM:
3705 case GL_COUNT_DOWN_CHROMIUM:
3706 break;
3707 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003708 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003709 return false;
3710 }
3711 if (!isPow2(mask + 1))
3712 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003713 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003714 return false;
3715 }
3716
3717 return true;
3718}
3719
Jamie Madill007530e2017-12-28 14:27:04 -05003720bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3721 GLsizei numPaths,
3722 GLenum pathNameType,
3723 const void *paths,
3724 GLuint pathBase,
3725 GLint reference,
3726 GLuint mask,
3727 GLenum coverMode,
3728 GLenum transformType,
3729 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003730{
3731 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3732 transformType, transformValues))
3733 return false;
3734
3735 switch (coverMode)
3736 {
3737 case GL_CONVEX_HULL_CHROMIUM:
3738 case GL_BOUNDING_BOX_CHROMIUM:
3739 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3740 break;
3741 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003742 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003743 return false;
3744 }
3745
3746 return true;
3747}
3748
Jamie Madill007530e2017-12-28 14:27:04 -05003749bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3750 GLuint program,
3751 GLint location,
3752 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003753{
3754 if (!context->getExtensions().pathRendering)
3755 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003756 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003757 return false;
3758 }
3759
3760 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3761 if (location >= MaxLocation)
3762 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003763 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003764 return false;
3765 }
3766
3767 const auto *programObject = context->getProgram(program);
3768 if (!programObject)
3769 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003770 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003771 return false;
3772 }
3773
3774 if (!name)
3775 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003776 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003777 return false;
3778 }
3779
3780 if (angle::BeginsWith(name, "gl_"))
3781 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003782 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003783 return false;
3784 }
3785
3786 return true;
3787}
3788
Jamie Madill007530e2017-12-28 14:27:04 -05003789bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3790 GLuint program,
3791 GLint location,
3792 GLenum genMode,
3793 GLint components,
3794 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003795{
3796 if (!context->getExtensions().pathRendering)
3797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003798 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003799 return false;
3800 }
3801
3802 const auto *programObject = context->getProgram(program);
3803 if (!programObject || programObject->isFlaggedForDeletion())
3804 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003805 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003806 return false;
3807 }
3808
3809 if (!programObject->isLinked())
3810 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003811 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003812 return false;
3813 }
3814
3815 switch (genMode)
3816 {
3817 case GL_NONE:
3818 if (components != 0)
3819 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003820 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003821 return false;
3822 }
3823 break;
3824
3825 case GL_OBJECT_LINEAR_CHROMIUM:
3826 case GL_EYE_LINEAR_CHROMIUM:
3827 case GL_CONSTANT_CHROMIUM:
3828 if (components < 1 || components > 4)
3829 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003830 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003831 return false;
3832 }
3833 if (!coeffs)
3834 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003835 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003836 return false;
3837 }
3838 break;
3839
3840 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003841 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003842 return false;
3843 }
3844
3845 // If the location is -1 then the command is silently ignored
3846 // and no further validation is needed.
3847 if (location == -1)
3848 return true;
3849
Jamie Madillbd044ed2017-06-05 12:59:21 -04003850 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003851
3852 if (!binding.valid)
3853 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003854 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003855 return false;
3856 }
3857
3858 if (binding.type != GL_NONE)
3859 {
3860 GLint expectedComponents = 0;
3861 switch (binding.type)
3862 {
3863 case GL_FLOAT:
3864 expectedComponents = 1;
3865 break;
3866 case GL_FLOAT_VEC2:
3867 expectedComponents = 2;
3868 break;
3869 case GL_FLOAT_VEC3:
3870 expectedComponents = 3;
3871 break;
3872 case GL_FLOAT_VEC4:
3873 expectedComponents = 4;
3874 break;
3875 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003876 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003877 InvalidOperation()
3878 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003879 return false;
3880 }
3881 if (expectedComponents != components && genMode != GL_NONE)
3882 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003883 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003884 return false;
3885 }
3886 }
3887 return true;
3888}
3889
Geoff Lang97073d12016-04-20 10:42:34 -07003890bool ValidateCopyTextureCHROMIUM(Context *context,
3891 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003892 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003893 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003894 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003895 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003896 GLint internalFormat,
3897 GLenum destType,
3898 GLboolean unpackFlipY,
3899 GLboolean unpackPremultiplyAlpha,
3900 GLboolean unpackUnmultiplyAlpha)
3901{
3902 if (!context->getExtensions().copyTexture)
3903 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003904 context->handleError(InvalidOperation()
3905 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003906 return false;
3907 }
3908
Geoff Lang4f0e0032017-05-01 16:04:35 -04003909 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003910 if (source == nullptr)
3911 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003912 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003913 return false;
3914 }
3915
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003916 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003917 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003918 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003919 return false;
3920 }
3921
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003922 TextureType sourceType = source->getType();
3923 ASSERT(sourceType != TextureType::CubeMap);
3924 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003925
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003926 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003927 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003928 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003929 return false;
3930 }
3931
Geoff Lang4f0e0032017-05-01 16:04:35 -04003932 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3933 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3934 if (sourceWidth == 0 || sourceHeight == 0)
3935 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003936 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003937 return false;
3938 }
3939
3940 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3941 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003942 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003943 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003944 return false;
3945 }
3946
Geoff Lang63458a32017-10-30 15:16:53 -04003947 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3948 {
3949 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3950 return false;
3951 }
3952
Geoff Lang4f0e0032017-05-01 16:04:35 -04003953 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003954 if (dest == nullptr)
3955 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003956 context->handleError(InvalidValue()
3957 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003958 return false;
3959 }
3960
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003961 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003962 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003963 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003964 return false;
3965 }
3966
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003967 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003968 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003969 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003970 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003971 return false;
3972 }
3973
Geoff Lang97073d12016-04-20 10:42:34 -07003974 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3975 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003976 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003977 return false;
3978 }
3979
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003980 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003981 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003982 context->handleError(
3983 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003984 return false;
3985 }
3986
Geoff Lang97073d12016-04-20 10:42:34 -07003987 if (dest->getImmutableFormat())
3988 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003989 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003990 return false;
3991 }
3992
3993 return true;
3994}
3995
3996bool ValidateCopySubTextureCHROMIUM(Context *context,
3997 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003998 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003999 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004000 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004001 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004002 GLint xoffset,
4003 GLint yoffset,
4004 GLint x,
4005 GLint y,
4006 GLsizei width,
4007 GLsizei height,
4008 GLboolean unpackFlipY,
4009 GLboolean unpackPremultiplyAlpha,
4010 GLboolean unpackUnmultiplyAlpha)
4011{
4012 if (!context->getExtensions().copyTexture)
4013 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004014 context->handleError(InvalidOperation()
4015 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004016 return false;
4017 }
4018
Geoff Lang4f0e0032017-05-01 16:04:35 -04004019 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004020 if (source == nullptr)
4021 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004022 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004023 return false;
4024 }
4025
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004026 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004027 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004028 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004029 return false;
4030 }
4031
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004032 TextureType sourceType = source->getType();
4033 ASSERT(sourceType != TextureType::CubeMap);
4034 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004035
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004036 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004037 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004038 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004039 return false;
4040 }
4041
4042 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4043 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004044 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004045 context->handleError(InvalidValue()
4046 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004047 return false;
4048 }
4049
4050 if (x < 0 || y < 0)
4051 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004052 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004053 return false;
4054 }
4055
4056 if (width < 0 || height < 0)
4057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004058 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004059 return false;
4060 }
4061
Geoff Lang4f0e0032017-05-01 16:04:35 -04004062 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4063 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004064 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004065 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004066 return false;
4067 }
4068
Geoff Lang4f0e0032017-05-01 16:04:35 -04004069 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4070 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004071 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004072 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004073 return false;
4074 }
4075
Geoff Lang63458a32017-10-30 15:16:53 -04004076 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4077 {
4078 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4079 return false;
4080 }
4081
Geoff Lang4f0e0032017-05-01 16:04:35 -04004082 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004083 if (dest == nullptr)
4084 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004085 context->handleError(InvalidValue()
4086 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004087 return false;
4088 }
4089
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004090 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004091 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004092 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004093 return false;
4094 }
4095
Brandon Jones28783792018-03-05 09:37:32 -08004096 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4097 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004098 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004099 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004100 return false;
4101 }
4102
Geoff Lang4f0e0032017-05-01 16:04:35 -04004103 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4104 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004105 context
4106 ->handleError(InvalidOperation()
4107 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004108 return false;
4109 }
4110
4111 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4112 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004113 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004114 context->handleError(InvalidOperation()
4115 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004116 return false;
4117 }
4118
4119 if (xoffset < 0 || yoffset < 0)
4120 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004121 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004122 return false;
4123 }
4124
Geoff Lang4f0e0032017-05-01 16:04:35 -04004125 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4126 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004127 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004128 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004129 return false;
4130 }
4131
4132 return true;
4133}
4134
Geoff Lang47110bf2016-04-20 11:13:22 -07004135bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4136{
4137 if (!context->getExtensions().copyCompressedTexture)
4138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004139 context->handleError(InvalidOperation()
4140 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004141 return false;
4142 }
4143
4144 const gl::Texture *source = context->getTexture(sourceId);
4145 if (source == nullptr)
4146 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004147 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004148 return false;
4149 }
4150
Corentin Wallez99d492c2018-02-27 15:17:10 -05004151 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004152 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004153 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004154 return false;
4155 }
4156
Corentin Wallez99d492c2018-02-27 15:17:10 -05004157 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4158 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004159 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004160 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004161 return false;
4162 }
4163
Corentin Wallez99d492c2018-02-27 15:17:10 -05004164 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004165 if (!sourceFormat.info->compressed)
4166 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004167 context->handleError(InvalidOperation()
4168 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004169 return false;
4170 }
4171
4172 const gl::Texture *dest = context->getTexture(destId);
4173 if (dest == nullptr)
4174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004175 context->handleError(InvalidValue()
4176 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004177 return false;
4178 }
4179
Corentin Wallez99d492c2018-02-27 15:17:10 -05004180 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004182 context->handleError(InvalidValue()
4183 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004184 return false;
4185 }
4186
4187 if (dest->getImmutableFormat())
4188 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004189 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004190 return false;
4191 }
4192
4193 return true;
4194}
4195
Jiawei Shao385b3e02018-03-21 09:43:28 +08004196bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004197{
4198 switch (type)
4199 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004200 case ShaderType::Vertex:
4201 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004202 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004203
Jiawei Shao385b3e02018-03-21 09:43:28 +08004204 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004205 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004206 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004207 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004208 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004209 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004210 break;
4211
Jiawei Shao385b3e02018-03-21 09:43:28 +08004212 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004213 if (!context->getExtensions().geometryShader)
4214 {
4215 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4216 return false;
4217 }
4218 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004219 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004220 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004221 return false;
4222 }
Jamie Madill29639852016-09-02 15:00:09 -04004223
4224 return true;
4225}
4226
Jamie Madill5b772312018-03-08 20:28:32 -05004227bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004228 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004229 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004230 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004231 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004232{
4233 if (size < 0)
4234 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004235 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004236 return false;
4237 }
4238
4239 switch (usage)
4240 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004241 case BufferUsage::StreamDraw:
4242 case BufferUsage::StaticDraw:
4243 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004244 break;
4245
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004246 case BufferUsage::StreamRead:
4247 case BufferUsage::StaticRead:
4248 case BufferUsage::DynamicRead:
4249 case BufferUsage::StreamCopy:
4250 case BufferUsage::StaticCopy:
4251 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004252 if (context->getClientMajorVersion() < 3)
4253 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004254 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004255 return false;
4256 }
4257 break;
4258
4259 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004260 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004261 return false;
4262 }
4263
Corentin Walleze4477002017-12-01 14:39:58 -05004264 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004265 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004266 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004267 return false;
4268 }
4269
4270 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4271
4272 if (!buffer)
4273 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004274 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004275 return false;
4276 }
4277
James Darpiniane8a93c62018-01-04 18:02:24 -08004278 if (context->getExtensions().webglCompatibility &&
4279 buffer->isBoundForTransformFeedbackAndOtherUse())
4280 {
4281 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4282 return false;
4283 }
4284
Jamie Madill29639852016-09-02 15:00:09 -04004285 return true;
4286}
4287
Jamie Madill5b772312018-03-08 20:28:32 -05004288bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004289 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004290 GLintptr offset,
4291 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004292 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004293{
Brandon Jones6cad5662017-06-14 13:25:13 -07004294 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004295 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004296 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4297 return false;
4298 }
4299
4300 if (offset < 0)
4301 {
4302 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004303 return false;
4304 }
4305
Corentin Walleze4477002017-12-01 14:39:58 -05004306 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004307 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004308 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004309 return false;
4310 }
4311
4312 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4313
4314 if (!buffer)
4315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004317 return false;
4318 }
4319
4320 if (buffer->isMapped())
4321 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004322 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004323 return false;
4324 }
4325
James Darpiniane8a93c62018-01-04 18:02:24 -08004326 if (context->getExtensions().webglCompatibility &&
4327 buffer->isBoundForTransformFeedbackAndOtherUse())
4328 {
4329 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4330 return false;
4331 }
4332
Jamie Madill29639852016-09-02 15:00:09 -04004333 // Check for possible overflow of size + offset
4334 angle::CheckedNumeric<size_t> checkedSize(size);
4335 checkedSize += offset;
4336 if (!checkedSize.IsValid())
4337 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004338 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004339 return false;
4340 }
4341
4342 if (size + offset > buffer->getSize())
4343 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004344 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004345 return false;
4346 }
4347
Martin Radev4c4c8e72016-08-04 12:25:34 +03004348 return true;
4349}
4350
Geoff Lang111a99e2017-10-17 10:58:41 -04004351bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004352{
Geoff Langc339c4e2016-11-29 10:37:36 -05004353 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004354 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004355 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004356 return false;
4357 }
4358
Geoff Lang111a99e2017-10-17 10:58:41 -04004359 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004360 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004361 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004362 return false;
4363 }
4364
4365 return true;
4366}
4367
Jamie Madill5b772312018-03-08 20:28:32 -05004368bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004369{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004370 if (context->getClientMajorVersion() < 2)
4371 {
4372 return ValidateMultitextureUnit(context, texture);
4373 }
4374
Jamie Madillef300b12016-10-07 15:12:09 -04004375 if (texture < GL_TEXTURE0 ||
4376 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4377 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004378 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004379 return false;
4380 }
4381
4382 return true;
4383}
4384
Jamie Madill5b772312018-03-08 20:28:32 -05004385bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004386{
4387 Program *programObject = GetValidProgram(context, program);
4388 if (!programObject)
4389 {
4390 return false;
4391 }
4392
4393 Shader *shaderObject = GetValidShader(context, shader);
4394 if (!shaderObject)
4395 {
4396 return false;
4397 }
4398
Jiawei Shao385b3e02018-03-21 09:43:28 +08004399 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004400 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004401 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4402 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004403 }
4404
4405 return true;
4406}
4407
Jamie Madill5b772312018-03-08 20:28:32 -05004408bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004409{
4410 if (index >= MAX_VERTEX_ATTRIBS)
4411 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004412 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004413 return false;
4414 }
4415
4416 if (strncmp(name, "gl_", 3) == 0)
4417 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004418 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004419 return false;
4420 }
4421
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004422 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004423 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004424 const size_t length = strlen(name);
4425
4426 if (!IsValidESSLString(name, length))
4427 {
4428 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4429 // for shader-related entry points
4430 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4431 return false;
4432 }
4433
4434 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4435 {
4436 return false;
4437 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004438 }
4439
Jamie Madill01a80ee2016-11-07 12:06:18 -05004440 return GetValidProgram(context, program) != nullptr;
4441}
4442
Jamie Madill5b772312018-03-08 20:28:32 -05004443bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444{
Corentin Walleze4477002017-12-01 14:39:58 -05004445 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004446 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004447 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004448 return false;
4449 }
4450
4451 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4452 !context->isBufferGenerated(buffer))
4453 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004454 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004455 return false;
4456 }
4457
4458 return true;
4459}
4460
Jamie Madill5b772312018-03-08 20:28:32 -05004461bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004462{
Geoff Lange8afa902017-09-27 15:00:43 -04004463 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004464 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004465 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004466 return false;
4467 }
4468
4469 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4470 !context->isFramebufferGenerated(framebuffer))
4471 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004472 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004473 return false;
4474 }
4475
4476 return true;
4477}
4478
Jamie Madill5b772312018-03-08 20:28:32 -05004479bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004480{
4481 if (target != GL_RENDERBUFFER)
4482 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004483 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004484 return false;
4485 }
4486
4487 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4488 !context->isRenderbufferGenerated(renderbuffer))
4489 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004490 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004491 return false;
4492 }
4493
4494 return true;
4495}
4496
Jamie Madill5b772312018-03-08 20:28:32 -05004497static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004498{
4499 switch (mode)
4500 {
4501 case GL_FUNC_ADD:
4502 case GL_FUNC_SUBTRACT:
4503 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004504 return true;
4505
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004506 case GL_MIN:
4507 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004508 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004509
4510 default:
4511 return false;
4512 }
4513}
4514
Jamie Madill5b772312018-03-08 20:28:32 -05004515bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004516{
4517 return true;
4518}
4519
Jamie Madill5b772312018-03-08 20:28:32 -05004520bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004521{
Geoff Lang50cac572017-09-26 17:37:43 -04004522 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004523 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004524 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004525 return false;
4526 }
4527
4528 return true;
4529}
4530
Jamie Madill5b772312018-03-08 20:28:32 -05004531bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004532{
Geoff Lang50cac572017-09-26 17:37:43 -04004533 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004534 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004535 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004536 return false;
4537 }
4538
Geoff Lang50cac572017-09-26 17:37:43 -04004539 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004540 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004541 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004542 return false;
4543 }
4544
4545 return true;
4546}
4547
Jamie Madill5b772312018-03-08 20:28:32 -05004548bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004549{
4550 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4551}
4552
4553static bool ValidSrcBlendFunc(GLenum srcBlend)
4554{
4555 switch (srcBlend)
4556 {
4557 case GL_ZERO:
4558 case GL_ONE:
4559 case GL_SRC_COLOR:
4560 case GL_ONE_MINUS_SRC_COLOR:
4561 case GL_DST_COLOR:
4562 case GL_ONE_MINUS_DST_COLOR:
4563 case GL_SRC_ALPHA:
4564 case GL_ONE_MINUS_SRC_ALPHA:
4565 case GL_DST_ALPHA:
4566 case GL_ONE_MINUS_DST_ALPHA:
4567 case GL_CONSTANT_COLOR:
4568 case GL_ONE_MINUS_CONSTANT_COLOR:
4569 case GL_CONSTANT_ALPHA:
4570 case GL_ONE_MINUS_CONSTANT_ALPHA:
4571 case GL_SRC_ALPHA_SATURATE:
4572 return true;
4573
4574 default:
4575 return false;
4576 }
4577}
4578
4579static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4580{
4581 switch (dstBlend)
4582 {
4583 case GL_ZERO:
4584 case GL_ONE:
4585 case GL_SRC_COLOR:
4586 case GL_ONE_MINUS_SRC_COLOR:
4587 case GL_DST_COLOR:
4588 case GL_ONE_MINUS_DST_COLOR:
4589 case GL_SRC_ALPHA:
4590 case GL_ONE_MINUS_SRC_ALPHA:
4591 case GL_DST_ALPHA:
4592 case GL_ONE_MINUS_DST_ALPHA:
4593 case GL_CONSTANT_COLOR:
4594 case GL_ONE_MINUS_CONSTANT_COLOR:
4595 case GL_CONSTANT_ALPHA:
4596 case GL_ONE_MINUS_CONSTANT_ALPHA:
4597 return true;
4598
4599 case GL_SRC_ALPHA_SATURATE:
4600 return (contextMajorVersion >= 3);
4601
4602 default:
4603 return false;
4604 }
4605}
4606
Jamie Madill5b772312018-03-08 20:28:32 -05004607bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004608 GLenum srcRGB,
4609 GLenum dstRGB,
4610 GLenum srcAlpha,
4611 GLenum dstAlpha)
4612{
4613 if (!ValidSrcBlendFunc(srcRGB))
4614 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004615 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004616 return false;
4617 }
4618
4619 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4620 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004621 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004622 return false;
4623 }
4624
4625 if (!ValidSrcBlendFunc(srcAlpha))
4626 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004627 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004628 return false;
4629 }
4630
4631 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4632 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004633 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004634 return false;
4635 }
4636
Frank Henigman146e8a12017-03-02 23:22:37 -05004637 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4638 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004639 {
4640 bool constantColorUsed =
4641 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4642 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4643
4644 bool constantAlphaUsed =
4645 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4646 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4647
4648 if (constantColorUsed && constantAlphaUsed)
4649 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004650 const char *msg;
4651 if (context->getExtensions().webglCompatibility)
4652 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004653 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004654 }
4655 else
4656 {
4657 msg =
4658 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4659 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4660 "implementation.";
4661 ERR() << msg;
4662 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004663 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004664 return false;
4665 }
4666 }
4667
4668 return true;
4669}
4670
Geoff Langc339c4e2016-11-29 10:37:36 -05004671bool ValidateGetString(Context *context, GLenum name)
4672{
4673 switch (name)
4674 {
4675 case GL_VENDOR:
4676 case GL_RENDERER:
4677 case GL_VERSION:
4678 case GL_SHADING_LANGUAGE_VERSION:
4679 case GL_EXTENSIONS:
4680 break;
4681
4682 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4683 if (!context->getExtensions().requestExtension)
4684 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004685 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004686 return false;
4687 }
4688 break;
4689
4690 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004691 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004692 return false;
4693 }
4694
4695 return true;
4696}
4697
Jamie Madill5b772312018-03-08 20:28:32 -05004698bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004699{
4700 if (width <= 0.0f || isNaN(width))
4701 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004702 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004703 return false;
4704 }
4705
4706 return true;
4707}
4708
Jamie Madill5b772312018-03-08 20:28:32 -05004709bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004710 GLuint index,
4711 GLint size,
4712 GLenum type,
4713 GLboolean normalized,
4714 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004715 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004716{
Shao80957d92017-02-20 21:25:59 +08004717 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004718 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004719 return false;
4720 }
4721
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004722 if (stride < 0)
4723 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004724 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004725 return false;
4726 }
4727
Shao80957d92017-02-20 21:25:59 +08004728 const Caps &caps = context->getCaps();
4729 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004730 {
Shao80957d92017-02-20 21:25:59 +08004731 if (stride > caps.maxVertexAttribStride)
4732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004733 context->handleError(InvalidValue()
4734 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004735 return false;
4736 }
4737
4738 if (index >= caps.maxVertexAttribBindings)
4739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004740 context->handleError(InvalidValue()
4741 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004742 return false;
4743 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004744 }
4745
4746 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4747 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4748 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4749 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004750 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4751 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004752 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4753 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004754 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004755 context
4756 ->handleError(InvalidOperation()
4757 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004758 return false;
4759 }
4760
4761 if (context->getExtensions().webglCompatibility)
4762 {
4763 // WebGL 1.0 [Section 6.14] Fixed point support
4764 // The WebGL API does not support the GL_FIXED data type.
4765 if (type == GL_FIXED)
4766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004767 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004768 return false;
4769 }
4770
Geoff Lang2d62ab72017-03-23 16:54:40 -04004771 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004772 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004773 return false;
4774 }
4775 }
4776
4777 return true;
4778}
4779
Jamie Madill5b772312018-03-08 20:28:32 -05004780bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004781{
4782 if (context->getExtensions().webglCompatibility && zNear > zFar)
4783 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004784 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004785 return false;
4786 }
4787
4788 return true;
4789}
4790
Jamie Madill5b772312018-03-08 20:28:32 -05004791bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004792 GLenum target,
4793 GLenum internalformat,
4794 GLsizei width,
4795 GLsizei height)
4796{
4797 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4798 height);
4799}
4800
Jamie Madill5b772312018-03-08 20:28:32 -05004801bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004802 GLenum target,
4803 GLsizei samples,
4804 GLenum internalformat,
4805 GLsizei width,
4806 GLsizei height)
4807{
4808 if (!context->getExtensions().framebufferMultisample)
4809 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004810 context->handleError(InvalidOperation()
4811 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004812 return false;
4813 }
4814
4815 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4816 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4817 // generated.
4818 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4819 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004820 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004821 return false;
4822 }
4823
4824 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4825 // the specified storage. This is different than ES 3.0 in which a sample number higher
4826 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4827 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4828 if (context->getClientMajorVersion() >= 3)
4829 {
4830 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4831 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4832 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004833 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004834 return false;
4835 }
4836 }
4837
4838 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4839 width, height);
4840}
4841
Jamie Madill5b772312018-03-08 20:28:32 -05004842bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004843{
Geoff Lange8afa902017-09-27 15:00:43 -04004844 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004845 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004846 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004847 return false;
4848 }
4849
4850 return true;
4851}
4852
Jamie Madill5b772312018-03-08 20:28:32 -05004853bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004854{
4855 return true;
4856}
4857
Jamie Madill5b772312018-03-08 20:28:32 -05004858bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004859{
4860 return true;
4861}
4862
Jamie Madill5b772312018-03-08 20:28:32 -05004863bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004864{
4865 return true;
4866}
4867
Jamie Madill5b772312018-03-08 20:28:32 -05004868bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004869 GLboolean red,
4870 GLboolean green,
4871 GLboolean blue,
4872 GLboolean alpha)
4873{
4874 return true;
4875}
4876
Jamie Madill5b772312018-03-08 20:28:32 -05004877bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004878{
4879 return true;
4880}
4881
Jamie Madill5b772312018-03-08 20:28:32 -05004882bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004883{
4884 return true;
4885}
4886
Jamie Madill5b772312018-03-08 20:28:32 -05004887bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004888{
4889 switch (mode)
4890 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004891 case CullFaceMode::Front:
4892 case CullFaceMode::Back:
4893 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894 break;
4895
4896 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004897 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004898 return false;
4899 }
4900
4901 return true;
4902}
4903
Jamie Madill5b772312018-03-08 20:28:32 -05004904bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004905{
4906 if (program == 0)
4907 {
4908 return false;
4909 }
4910
4911 if (!context->getProgram(program))
4912 {
4913 if (context->getShader(program))
4914 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004915 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004916 return false;
4917 }
4918 else
4919 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004920 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004921 return false;
4922 }
4923 }
4924
4925 return true;
4926}
4927
Jamie Madill5b772312018-03-08 20:28:32 -05004928bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004929{
4930 if (shader == 0)
4931 {
4932 return false;
4933 }
4934
4935 if (!context->getShader(shader))
4936 {
4937 if (context->getProgram(shader))
4938 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004939 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004940 return false;
4941 }
4942 else
4943 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004944 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004945 return false;
4946 }
4947 }
4948
4949 return true;
4950}
4951
Jamie Madill5b772312018-03-08 20:28:32 -05004952bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004953{
4954 switch (func)
4955 {
4956 case GL_NEVER:
4957 case GL_ALWAYS:
4958 case GL_LESS:
4959 case GL_LEQUAL:
4960 case GL_EQUAL:
4961 case GL_GREATER:
4962 case GL_GEQUAL:
4963 case GL_NOTEQUAL:
4964 break;
4965
4966 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004967 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004968 return false;
4969 }
4970
4971 return true;
4972}
4973
Jamie Madill5b772312018-03-08 20:28:32 -05004974bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004975{
4976 return true;
4977}
4978
Jamie Madill5b772312018-03-08 20:28:32 -05004979bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004980{
4981 Program *programObject = GetValidProgram(context, program);
4982 if (!programObject)
4983 {
4984 return false;
4985 }
4986
4987 Shader *shaderObject = GetValidShader(context, shader);
4988 if (!shaderObject)
4989 {
4990 return false;
4991 }
4992
Jiawei Shao385b3e02018-03-21 09:43:28 +08004993 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004994 if (attachedShader != shaderObject)
4995 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004996 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004997 return false;
4998 }
4999
5000 return true;
5001}
5002
Jamie Madill5b772312018-03-08 20:28:32 -05005003bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005004{
5005 if (index >= MAX_VERTEX_ATTRIBS)
5006 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005007 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005008 return false;
5009 }
5010
5011 return true;
5012}
5013
Jamie Madill5b772312018-03-08 20:28:32 -05005014bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005015{
5016 if (index >= MAX_VERTEX_ATTRIBS)
5017 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005018 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005019 return false;
5020 }
5021
5022 return true;
5023}
5024
Jamie Madill5b772312018-03-08 20:28:32 -05005025bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005026{
5027 return true;
5028}
5029
Jamie Madill5b772312018-03-08 20:28:32 -05005030bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005031{
5032 return true;
5033}
5034
Jamie Madill5b772312018-03-08 20:28:32 -05005035bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005036{
5037 switch (mode)
5038 {
5039 case GL_CW:
5040 case GL_CCW:
5041 break;
5042 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005043 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
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 ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005051 GLuint program,
5052 GLuint index,
5053 GLsizei bufsize,
5054 GLsizei *length,
5055 GLint *size,
5056 GLenum *type,
5057 GLchar *name)
5058{
5059 if (bufsize < 0)
5060 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005061 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005062 return false;
5063 }
5064
5065 Program *programObject = GetValidProgram(context, program);
5066
5067 if (!programObject)
5068 {
5069 return false;
5070 }
5071
5072 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5073 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005074 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005075 return false;
5076 }
5077
5078 return true;
5079}
5080
Jamie Madill5b772312018-03-08 20:28:32 -05005081bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005082 GLuint program,
5083 GLuint index,
5084 GLsizei bufsize,
5085 GLsizei *length,
5086 GLint *size,
5087 GLenum *type,
5088 GLchar *name)
5089{
5090 if (bufsize < 0)
5091 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005092 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005093 return false;
5094 }
5095
5096 Program *programObject = GetValidProgram(context, program);
5097
5098 if (!programObject)
5099 {
5100 return false;
5101 }
5102
5103 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5104 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005105 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005106 return false;
5107 }
5108
5109 return true;
5110}
5111
Jamie Madill5b772312018-03-08 20:28:32 -05005112bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005113 GLuint program,
5114 GLsizei maxcount,
5115 GLsizei *count,
5116 GLuint *shaders)
5117{
5118 if (maxcount < 0)
5119 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005120 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005121 return false;
5122 }
5123
5124 Program *programObject = GetValidProgram(context, program);
5125
5126 if (!programObject)
5127 {
5128 return false;
5129 }
5130
5131 return true;
5132}
5133
Jamie Madill5b772312018-03-08 20:28:32 -05005134bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005135{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005136 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5137 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005138 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005139 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005140 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005141 return false;
5142 }
5143
Jamie Madillc1d770e2017-04-13 17:31:24 -04005144 Program *programObject = GetValidProgram(context, program);
5145
5146 if (!programObject)
5147 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005148 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149 return false;
5150 }
5151
5152 if (!programObject->isLinked())
5153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005155 return false;
5156 }
5157
5158 return true;
5159}
5160
Jamie Madill5b772312018-03-08 20:28:32 -05005161bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005162{
5163 GLenum nativeType;
5164 unsigned int numParams = 0;
5165 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5166}
5167
Jamie Madill5b772312018-03-08 20:28:32 -05005168bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005169{
5170 return true;
5171}
5172
Jamie Madill5b772312018-03-08 20:28:32 -05005173bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005174{
5175 GLenum nativeType;
5176 unsigned int numParams = 0;
5177 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5178}
5179
Jamie Madill5b772312018-03-08 20:28:32 -05005180bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005181{
5182 GLenum nativeType;
5183 unsigned int numParams = 0;
5184 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5185}
5186
Jamie Madill5b772312018-03-08 20:28:32 -05005187bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005188 GLuint program,
5189 GLsizei bufsize,
5190 GLsizei *length,
5191 GLchar *infolog)
5192{
5193 if (bufsize < 0)
5194 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005195 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005196 return false;
5197 }
5198
5199 Program *programObject = GetValidProgram(context, program);
5200 if (!programObject)
5201 {
5202 return false;
5203 }
5204
5205 return true;
5206}
5207
Jamie Madill5b772312018-03-08 20:28:32 -05005208bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005209 GLuint shader,
5210 GLsizei bufsize,
5211 GLsizei *length,
5212 GLchar *infolog)
5213{
5214 if (bufsize < 0)
5215 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005216 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005217 return false;
5218 }
5219
5220 Shader *shaderObject = GetValidShader(context, shader);
5221 if (!shaderObject)
5222 {
5223 return false;
5224 }
5225
5226 return true;
5227}
5228
Jamie Madill5b772312018-03-08 20:28:32 -05005229bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005230 GLenum shadertype,
5231 GLenum precisiontype,
5232 GLint *range,
5233 GLint *precision)
5234{
5235 switch (shadertype)
5236 {
5237 case GL_VERTEX_SHADER:
5238 case GL_FRAGMENT_SHADER:
5239 break;
5240 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005241 context->handleError(InvalidOperation()
5242 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005243 return false;
5244 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005245 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005246 return false;
5247 }
5248
5249 switch (precisiontype)
5250 {
5251 case GL_LOW_FLOAT:
5252 case GL_MEDIUM_FLOAT:
5253 case GL_HIGH_FLOAT:
5254 case GL_LOW_INT:
5255 case GL_MEDIUM_INT:
5256 case GL_HIGH_INT:
5257 break;
5258
5259 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005260 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005261 return false;
5262 }
5263
5264 return true;
5265}
5266
Jamie Madill5b772312018-03-08 20:28:32 -05005267bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005268 GLuint shader,
5269 GLsizei bufsize,
5270 GLsizei *length,
5271 GLchar *source)
5272{
5273 if (bufsize < 0)
5274 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005275 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005276 return false;
5277 }
5278
5279 Shader *shaderObject = GetValidShader(context, shader);
5280 if (!shaderObject)
5281 {
5282 return false;
5283 }
5284
5285 return true;
5286}
5287
Jamie Madill5b772312018-03-08 20:28:32 -05005288bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005289{
5290 if (strstr(name, "gl_") == name)
5291 {
5292 return false;
5293 }
5294
Geoff Langfc32e8b2017-05-31 14:16:59 -04005295 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5296 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005297 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005298 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005299 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005300 return false;
5301 }
5302
Jamie Madillc1d770e2017-04-13 17:31:24 -04005303 Program *programObject = GetValidProgram(context, program);
5304
5305 if (!programObject)
5306 {
5307 return false;
5308 }
5309
5310 if (!programObject->isLinked())
5311 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005312 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005313 return false;
5314 }
5315
5316 return true;
5317}
5318
Jamie Madill5b772312018-03-08 20:28:32 -05005319bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005320{
5321 switch (mode)
5322 {
5323 case GL_FASTEST:
5324 case GL_NICEST:
5325 case GL_DONT_CARE:
5326 break;
5327
5328 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005329 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005330 return false;
5331 }
5332
5333 switch (target)
5334 {
5335 case GL_GENERATE_MIPMAP_HINT:
5336 break;
5337
Geoff Lange7bd2182017-06-16 16:13:13 -04005338 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5339 if (context->getClientVersion() < ES_3_0 &&
5340 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005341 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005342 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005343 return false;
5344 }
5345 break;
5346
5347 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005348 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005349 return false;
5350 }
5351
5352 return true;
5353}
5354
Jamie Madill5b772312018-03-08 20:28:32 -05005355bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005356{
5357 return true;
5358}
5359
Jamie Madill5b772312018-03-08 20:28:32 -05005360bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005361{
5362 return true;
5363}
5364
Jamie Madill5b772312018-03-08 20:28:32 -05005365bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005366{
5367 return true;
5368}
5369
Jamie Madill5b772312018-03-08 20:28:32 -05005370bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005371{
5372 return true;
5373}
5374
Jamie Madill5b772312018-03-08 20:28:32 -05005375bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005376{
5377 return true;
5378}
5379
Jamie Madill5b772312018-03-08 20:28:32 -05005380bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005381{
5382 return true;
5383}
5384
Jamie Madill5b772312018-03-08 20:28:32 -05005385bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005386{
5387 if (context->getClientMajorVersion() < 3)
5388 {
5389 switch (pname)
5390 {
5391 case GL_UNPACK_IMAGE_HEIGHT:
5392 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005393 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005394 return false;
5395
5396 case GL_UNPACK_ROW_LENGTH:
5397 case GL_UNPACK_SKIP_ROWS:
5398 case GL_UNPACK_SKIP_PIXELS:
5399 if (!context->getExtensions().unpackSubimage)
5400 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005401 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005402 return false;
5403 }
5404 break;
5405
5406 case GL_PACK_ROW_LENGTH:
5407 case GL_PACK_SKIP_ROWS:
5408 case GL_PACK_SKIP_PIXELS:
5409 if (!context->getExtensions().packSubimage)
5410 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005411 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005412 return false;
5413 }
5414 break;
5415 }
5416 }
5417
5418 if (param < 0)
5419 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005420 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005421 return false;
5422 }
5423
5424 switch (pname)
5425 {
5426 case GL_UNPACK_ALIGNMENT:
5427 if (param != 1 && param != 2 && param != 4 && param != 8)
5428 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005429 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005430 return false;
5431 }
5432 break;
5433
5434 case GL_PACK_ALIGNMENT:
5435 if (param != 1 && param != 2 && param != 4 && param != 8)
5436 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005437 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005438 return false;
5439 }
5440 break;
5441
5442 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005443 if (!context->getExtensions().packReverseRowOrder)
5444 {
5445 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5446 }
5447 break;
5448
Jamie Madillc1d770e2017-04-13 17:31:24 -04005449 case GL_UNPACK_ROW_LENGTH:
5450 case GL_UNPACK_IMAGE_HEIGHT:
5451 case GL_UNPACK_SKIP_IMAGES:
5452 case GL_UNPACK_SKIP_ROWS:
5453 case GL_UNPACK_SKIP_PIXELS:
5454 case GL_PACK_ROW_LENGTH:
5455 case GL_PACK_SKIP_ROWS:
5456 case GL_PACK_SKIP_PIXELS:
5457 break;
5458
5459 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005460 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005461 return false;
5462 }
5463
5464 return true;
5465}
5466
Jamie Madill5b772312018-03-08 20:28:32 -05005467bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005468{
5469 return true;
5470}
5471
Jamie Madill5b772312018-03-08 20:28:32 -05005472bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005473{
5474 return true;
5475}
5476
Jamie Madill5b772312018-03-08 20:28:32 -05005477bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005478{
5479 return true;
5480}
5481
Jamie Madill5b772312018-03-08 20:28:32 -05005482bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005483{
5484 if (width < 0 || height < 0)
5485 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005486 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005487 return false;
5488 }
5489
5490 return true;
5491}
5492
Jamie Madill5b772312018-03-08 20:28:32 -05005493bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494 GLsizei n,
5495 const GLuint *shaders,
5496 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005497 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005498 GLsizei length)
5499{
5500 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5501 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5502 shaderBinaryFormats.end())
5503 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005504 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005505 return false;
5506 }
5507
5508 return true;
5509}
5510
Jamie Madill5b772312018-03-08 20:28:32 -05005511bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005512 GLuint shader,
5513 GLsizei count,
5514 const GLchar *const *string,
5515 const GLint *length)
5516{
5517 if (count < 0)
5518 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005519 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005520 return false;
5521 }
5522
Geoff Langfc32e8b2017-05-31 14:16:59 -04005523 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5524 // shader-related entry points
5525 if (context->getExtensions().webglCompatibility)
5526 {
5527 for (GLsizei i = 0; i < count; i++)
5528 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005529 size_t len =
5530 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005531
5532 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005533 if (!IsValidESSLShaderSourceString(string[i], len,
5534 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005536 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005537 return false;
5538 }
5539 }
5540 }
5541
Jamie Madillc1d770e2017-04-13 17:31:24 -04005542 Shader *shaderObject = GetValidShader(context, shader);
5543 if (!shaderObject)
5544 {
5545 return false;
5546 }
5547
5548 return true;
5549}
5550
Jamie Madill5b772312018-03-08 20:28:32 -05005551bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005552{
5553 if (!IsValidStencilFunc(func))
5554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005555 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556 return false;
5557 }
5558
5559 return true;
5560}
5561
Jamie Madill5b772312018-03-08 20:28:32 -05005562bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005563{
5564 if (!IsValidStencilFace(face))
5565 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005566 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005567 return false;
5568 }
5569
5570 if (!IsValidStencilFunc(func))
5571 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005572 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005573 return false;
5574 }
5575
5576 return true;
5577}
5578
Jamie Madill5b772312018-03-08 20:28:32 -05005579bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580{
5581 return true;
5582}
5583
Jamie Madill5b772312018-03-08 20:28:32 -05005584bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005585{
5586 if (!IsValidStencilFace(face))
5587 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005588 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005589 return false;
5590 }
5591
5592 return true;
5593}
5594
Jamie Madill5b772312018-03-08 20:28:32 -05005595bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596{
5597 if (!IsValidStencilOp(fail))
5598 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005599 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005600 return false;
5601 }
5602
5603 if (!IsValidStencilOp(zfail))
5604 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005605 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005606 return false;
5607 }
5608
5609 if (!IsValidStencilOp(zpass))
5610 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005611 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005612 return false;
5613 }
5614
5615 return true;
5616}
5617
Jamie Madill5b772312018-03-08 20:28:32 -05005618bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005619 GLenum face,
5620 GLenum fail,
5621 GLenum zfail,
5622 GLenum zpass)
5623{
5624 if (!IsValidStencilFace(face))
5625 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005626 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005627 return false;
5628 }
5629
5630 return ValidateStencilOp(context, fail, zfail, zpass);
5631}
5632
Jamie Madill5b772312018-03-08 20:28:32 -05005633bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005634{
5635 return ValidateUniform(context, GL_FLOAT, location, 1);
5636}
5637
Jamie Madill5b772312018-03-08 20:28:32 -05005638bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005639{
5640 return ValidateUniform(context, GL_FLOAT, location, count);
5641}
5642
Jamie Madill5b772312018-03-08 20:28:32 -05005643bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005644{
5645 return ValidateUniform1iv(context, location, 1, &x);
5646}
5647
Jamie Madill5b772312018-03-08 20:28:32 -05005648bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005649{
5650 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5651}
5652
Jamie Madill5b772312018-03-08 20:28:32 -05005653bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005654{
5655 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5656}
5657
Jamie Madill5b772312018-03-08 20:28:32 -05005658bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005659{
5660 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5661}
5662
Jamie Madill5b772312018-03-08 20:28:32 -05005663bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005664{
5665 return ValidateUniform(context, GL_INT_VEC2, location, count);
5666}
5667
Jamie Madill5b772312018-03-08 20:28:32 -05005668bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005669{
5670 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5671}
5672
Jamie Madill5b772312018-03-08 20:28:32 -05005673bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005674{
5675 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5676}
5677
Jamie Madill5b772312018-03-08 20:28:32 -05005678bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005679{
5680 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5681}
5682
Jamie Madill5b772312018-03-08 20:28:32 -05005683bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005684{
5685 return ValidateUniform(context, GL_INT_VEC3, location, count);
5686}
5687
Jamie Madill5b772312018-03-08 20:28:32 -05005688bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005689{
5690 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5691}
5692
Jamie Madill5b772312018-03-08 20:28:32 -05005693bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005694{
5695 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5696}
5697
Jamie Madill5b772312018-03-08 20:28:32 -05005698bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005699{
5700 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5701}
5702
Jamie Madill5b772312018-03-08 20:28:32 -05005703bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005704{
5705 return ValidateUniform(context, GL_INT_VEC4, location, count);
5706}
5707
Jamie Madill5b772312018-03-08 20:28:32 -05005708bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005709 GLint location,
5710 GLsizei count,
5711 GLboolean transpose,
5712 const GLfloat *value)
5713{
5714 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5715}
5716
Jamie Madill5b772312018-03-08 20:28:32 -05005717bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005718 GLint location,
5719 GLsizei count,
5720 GLboolean transpose,
5721 const GLfloat *value)
5722{
5723 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5724}
5725
Jamie Madill5b772312018-03-08 20:28:32 -05005726bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005727 GLint location,
5728 GLsizei count,
5729 GLboolean transpose,
5730 const GLfloat *value)
5731{
5732 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5733}
5734
Jamie Madill5b772312018-03-08 20:28:32 -05005735bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005736{
5737 Program *programObject = GetValidProgram(context, program);
5738
5739 if (!programObject)
5740 {
5741 return false;
5742 }
5743
5744 return true;
5745}
5746
Jamie Madill5b772312018-03-08 20:28:32 -05005747bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005748{
5749 return ValidateVertexAttribIndex(context, index);
5750}
5751
Jamie Madill5b772312018-03-08 20:28:32 -05005752bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005753{
5754 return ValidateVertexAttribIndex(context, index);
5755}
5756
Jamie Madill5b772312018-03-08 20:28:32 -05005757bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005758{
5759 return ValidateVertexAttribIndex(context, index);
5760}
5761
Jamie Madill5b772312018-03-08 20:28:32 -05005762bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005763{
5764 return ValidateVertexAttribIndex(context, index);
5765}
5766
Jamie Madill5b772312018-03-08 20:28:32 -05005767bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005768{
5769 return ValidateVertexAttribIndex(context, index);
5770}
5771
Jamie Madill5b772312018-03-08 20:28:32 -05005772bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005773{
5774 return ValidateVertexAttribIndex(context, index);
5775}
5776
Jamie Madill5b772312018-03-08 20:28:32 -05005777bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005778 GLuint index,
5779 GLfloat x,
5780 GLfloat y,
5781 GLfloat z,
5782 GLfloat w)
5783{
5784 return ValidateVertexAttribIndex(context, index);
5785}
5786
Jamie Madill5b772312018-03-08 20:28:32 -05005787bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005788{
5789 return ValidateVertexAttribIndex(context, index);
5790}
5791
Jamie Madill5b772312018-03-08 20:28:32 -05005792bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005793{
5794 if (width < 0 || height < 0)
5795 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005796 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005797 return false;
5798 }
5799
5800 return true;
5801}
5802
Jamie Madill5b772312018-03-08 20:28:32 -05005803bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005804{
5805 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5806}
5807
Jamie Madill5b772312018-03-08 20:28:32 -05005808bool ValidateDrawElements(Context *context,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005809 GLenum mode,
5810 GLsizei count,
5811 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005812 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005813{
5814 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5815}
5816
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005817bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005818 GLenum target,
5819 GLenum attachment,
5820 GLenum pname,
5821 GLint *params)
5822{
5823 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5824 nullptr);
5825}
5826
Jamie Madill5b772312018-03-08 20:28:32 -05005827bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005828{
5829 return ValidateGetProgramivBase(context, program, pname, nullptr);
5830}
5831
Jamie Madill5b772312018-03-08 20:28:32 -05005832bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005833 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005834 GLint level,
5835 GLenum internalformat,
5836 GLint x,
5837 GLint y,
5838 GLsizei width,
5839 GLsizei height,
5840 GLint border)
5841{
5842 if (context->getClientMajorVersion() < 3)
5843 {
5844 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5845 0, x, y, width, height, border);
5846 }
5847
5848 ASSERT(context->getClientMajorVersion() == 3);
5849 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5850 0, x, y, width, height, border);
5851}
5852
5853bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005854 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005855 GLint level,
5856 GLint xoffset,
5857 GLint yoffset,
5858 GLint x,
5859 GLint y,
5860 GLsizei width,
5861 GLsizei height)
5862{
5863 if (context->getClientMajorVersion() < 3)
5864 {
5865 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5866 yoffset, x, y, width, height, 0);
5867 }
5868
5869 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5870 yoffset, 0, x, y, width, height, 0);
5871}
5872
5873bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5874{
5875 return ValidateGenOrDelete(context, n);
5876}
5877
5878bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5879{
5880 return ValidateGenOrDelete(context, n);
5881}
5882
5883bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5884{
5885 return ValidateGenOrDelete(context, n);
5886}
5887
5888bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5889{
5890 return ValidateGenOrDelete(context, n);
5891}
5892
5893bool ValidateDisable(Context *context, GLenum cap)
5894{
5895 if (!ValidCap(context, cap, false))
5896 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005897 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005898 return false;
5899 }
5900
5901 return true;
5902}
5903
5904bool ValidateEnable(Context *context, GLenum cap)
5905{
5906 if (!ValidCap(context, cap, false))
5907 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005908 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005909 return false;
5910 }
5911
5912 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5913 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5914 {
5915 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005916 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005917
5918 // We also output an error message to the debugger window if tracing is active, so that
5919 // developers can see the error message.
5920 ERR() << errorMessage;
5921 return false;
5922 }
5923
5924 return true;
5925}
5926
5927bool ValidateFramebufferRenderbuffer(Context *context,
5928 GLenum target,
5929 GLenum attachment,
5930 GLenum renderbuffertarget,
5931 GLuint renderbuffer)
5932{
Geoff Lange8afa902017-09-27 15:00:43 -04005933 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005934 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005935 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5936 return false;
5937 }
5938
5939 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5940 {
5941 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005942 return false;
5943 }
5944
5945 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5946 renderbuffertarget, renderbuffer);
5947}
5948
5949bool ValidateFramebufferTexture2D(Context *context,
5950 GLenum target,
5951 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005952 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005953 GLuint texture,
5954 GLint level)
5955{
5956 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5957 // extension
5958 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5959 level != 0)
5960 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005961 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005962 return false;
5963 }
5964
5965 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5966 {
5967 return false;
5968 }
5969
5970 if (texture != 0)
5971 {
5972 gl::Texture *tex = context->getTexture(texture);
5973 ASSERT(tex);
5974
5975 const gl::Caps &caps = context->getCaps();
5976
5977 switch (textarget)
5978 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005979 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005980 {
5981 if (level > gl::log2(caps.max2DTextureSize))
5982 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005983 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005984 return false;
5985 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005986 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005987 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005988 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005989 return false;
5990 }
5991 }
5992 break;
5993
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005994 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005995 {
5996 if (level != 0)
5997 {
5998 context->handleError(InvalidValue());
5999 return false;
6000 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006001 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006002 {
6003 context->handleError(InvalidOperation()
6004 << "Textarget must match the texture target type.");
6005 return false;
6006 }
6007 }
6008 break;
6009
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006010 case TextureTarget::CubeMapNegativeX:
6011 case TextureTarget::CubeMapNegativeY:
6012 case TextureTarget::CubeMapNegativeZ:
6013 case TextureTarget::CubeMapPositiveX:
6014 case TextureTarget::CubeMapPositiveY:
6015 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006016 {
6017 if (level > gl::log2(caps.maxCubeMapTextureSize))
6018 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006019 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006020 return false;
6021 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006022 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006023 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006024 context->handleError(InvalidOperation()
6025 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006026 return false;
6027 }
6028 }
6029 break;
6030
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006031 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006032 {
6033 if (context->getClientVersion() < ES_3_1)
6034 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006035 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006036 return false;
6037 }
6038
6039 if (level != 0)
6040 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006041 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 return false;
6043 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006044 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006046 context->handleError(InvalidOperation()
6047 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006048 return false;
6049 }
6050 }
6051 break;
6052
6053 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006054 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006055 return false;
6056 }
6057
6058 const Format &format = tex->getFormat(textarget, level);
6059 if (format.info->compressed)
6060 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006061 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006062 return false;
6063 }
6064 }
6065
6066 return true;
6067}
6068
6069bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6070{
6071 return ValidateGenOrDelete(context, n);
6072}
6073
6074bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6075{
6076 return ValidateGenOrDelete(context, n);
6077}
6078
6079bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6080{
6081 return ValidateGenOrDelete(context, n);
6082}
6083
6084bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6085{
6086 return ValidateGenOrDelete(context, n);
6087}
6088
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006089bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006090{
6091 if (!ValidTextureTarget(context, target))
6092 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006093 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006094 return false;
6095 }
6096
6097 Texture *texture = context->getTargetTexture(target);
6098
6099 if (texture == nullptr)
6100 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006101 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006102 return false;
6103 }
6104
6105 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6106
6107 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6108 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6109 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6110 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006111 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006112 return false;
6113 }
6114
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006115 TextureTarget baseTarget = (target == TextureType::CubeMap)
6116 ? TextureTarget::CubeMapPositiveX
6117 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006118 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6119 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6120 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006121 {
6122 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6123 return false;
6124 }
6125
Geoff Lang536eca12017-09-13 11:23:35 -04006126 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6127 bool formatUnsized = !format.sized;
6128 bool formatColorRenderableAndFilterable =
6129 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6130 format.renderSupport(context->getClientVersion(), context->getExtensions());
6131 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006132 {
Geoff Lang536eca12017-09-13 11:23:35 -04006133 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006134 return false;
6135 }
6136
Geoff Lang536eca12017-09-13 11:23:35 -04006137 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6138 // generation
6139 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6140 {
6141 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6142 return false;
6143 }
6144
6145 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
Geoff Lange24032a2018-03-28 15:41:46 -04006146 // not. Differentiate the ES3 format from the extension format by checking if the format is
6147 // sized, GL_EXT_sRGB does not add any sized formats.
6148 bool supportsSRGBMipmapGeneration = context->getExtensions().webglCompatibility;
6149 if (!supportsSRGBMipmapGeneration && !format.sized && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006150 {
Geoff Lang536eca12017-09-13 11:23:35 -04006151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006152 return false;
6153 }
6154
6155 // Non-power of 2 ES2 check
6156 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6157 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6158 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6159 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006160 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6161 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006162 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006163 return false;
6164 }
6165
6166 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006167 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006168 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006169 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006170 return false;
6171 }
6172
6173 return true;
6174}
6175
Jamie Madill5b772312018-03-08 20:28:32 -05006176bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006177 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006178 GLenum pname,
6179 GLint *params)
6180{
6181 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6182}
6183
6184bool ValidateGetRenderbufferParameteriv(Context *context,
6185 GLenum target,
6186 GLenum pname,
6187 GLint *params)
6188{
6189 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6190}
6191
6192bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6193{
6194 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6195}
6196
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006197bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006198{
6199 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6200}
6201
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006202bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006203{
6204 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6205}
6206
6207bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6208{
6209 return ValidateGetUniformBase(context, program, location);
6210}
6211
6212bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6213{
6214 return ValidateGetUniformBase(context, program, location);
6215}
6216
6217bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6218{
6219 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6220}
6221
6222bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6223{
6224 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6225}
6226
6227bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6228{
6229 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6230}
6231
6232bool ValidateIsEnabled(Context *context, GLenum cap)
6233{
6234 if (!ValidCap(context, cap, true))
6235 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006236 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006237 return false;
6238 }
6239
6240 return true;
6241}
6242
6243bool ValidateLinkProgram(Context *context, GLuint program)
6244{
6245 if (context->hasActiveTransformFeedback(program))
6246 {
6247 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006248 context->handleError(InvalidOperation() << "Cannot link program while program is "
6249 "associated with an active transform "
6250 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006251 return false;
6252 }
6253
6254 Program *programObject = GetValidProgram(context, program);
6255 if (!programObject)
6256 {
6257 return false;
6258 }
6259
6260 return true;
6261}
6262
Jamie Madill4928b7c2017-06-20 12:57:39 -04006263bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006264 GLint x,
6265 GLint y,
6266 GLsizei width,
6267 GLsizei height,
6268 GLenum format,
6269 GLenum type,
6270 void *pixels)
6271{
6272 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6273 nullptr, pixels);
6274}
6275
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006276bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006277{
6278 return ValidateTexParameterBase(context, target, pname, -1, &param);
6279}
6280
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006281bool ValidateTexParameterfv(Context *context,
6282 TextureType target,
6283 GLenum pname,
6284 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006285{
6286 return ValidateTexParameterBase(context, target, pname, -1, params);
6287}
6288
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006289bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006290{
6291 return ValidateTexParameterBase(context, target, pname, -1, &param);
6292}
6293
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006294bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006295{
6296 return ValidateTexParameterBase(context, target, pname, -1, params);
6297}
6298
6299bool ValidateUseProgram(Context *context, GLuint program)
6300{
6301 if (program != 0)
6302 {
6303 Program *programObject = context->getProgram(program);
6304 if (!programObject)
6305 {
6306 // ES 3.1.0 section 7.3 page 72
6307 if (context->getShader(program))
6308 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006309 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006310 return false;
6311 }
6312 else
6313 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006314 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006315 return false;
6316 }
6317 }
6318 if (!programObject->isLinked())
6319 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006320 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006321 return false;
6322 }
6323 }
6324 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6325 {
6326 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006327 context
6328 ->handleError(InvalidOperation()
6329 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006330 return false;
6331 }
6332
6333 return true;
6334}
6335
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006336bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6337{
6338 if (!context->getExtensions().fence)
6339 {
6340 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6341 return false;
6342 }
6343
6344 if (n < 0)
6345 {
6346 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6347 return false;
6348 }
6349
6350 return true;
6351}
6352
6353bool ValidateFinishFenceNV(Context *context, GLuint fence)
6354{
6355 if (!context->getExtensions().fence)
6356 {
6357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6358 return false;
6359 }
6360
6361 FenceNV *fenceObject = context->getFenceNV(fence);
6362
6363 if (fenceObject == nullptr)
6364 {
6365 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6366 return false;
6367 }
6368
6369 if (!fenceObject->isSet())
6370 {
6371 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6372 return false;
6373 }
6374
6375 return true;
6376}
6377
6378bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6379{
6380 if (!context->getExtensions().fence)
6381 {
6382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6383 return false;
6384 }
6385
6386 if (n < 0)
6387 {
6388 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6389 return false;
6390 }
6391
6392 return true;
6393}
6394
6395bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6396{
6397 if (!context->getExtensions().fence)
6398 {
6399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6400 return false;
6401 }
6402
6403 FenceNV *fenceObject = context->getFenceNV(fence);
6404
6405 if (fenceObject == nullptr)
6406 {
6407 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6408 return false;
6409 }
6410
6411 if (!fenceObject->isSet())
6412 {
6413 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6414 return false;
6415 }
6416
6417 switch (pname)
6418 {
6419 case GL_FENCE_STATUS_NV:
6420 case GL_FENCE_CONDITION_NV:
6421 break;
6422
6423 default:
6424 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6425 return false;
6426 }
6427
6428 return true;
6429}
6430
6431bool ValidateGetGraphicsResetStatusEXT(Context *context)
6432{
6433 if (!context->getExtensions().robustness)
6434 {
6435 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6436 return false;
6437 }
6438
6439 return true;
6440}
6441
6442bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6443 GLuint shader,
6444 GLsizei bufsize,
6445 GLsizei *length,
6446 GLchar *source)
6447{
6448 if (!context->getExtensions().translatedShaderSource)
6449 {
6450 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6451 return false;
6452 }
6453
6454 if (bufsize < 0)
6455 {
6456 context->handleError(InvalidValue());
6457 return false;
6458 }
6459
6460 Shader *shaderObject = context->getShader(shader);
6461
6462 if (!shaderObject)
6463 {
6464 context->handleError(InvalidOperation());
6465 return false;
6466 }
6467
6468 return true;
6469}
6470
6471bool ValidateIsFenceNV(Context *context, GLuint fence)
6472{
6473 if (!context->getExtensions().fence)
6474 {
6475 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6476 return false;
6477 }
6478
6479 return true;
6480}
6481
Jamie Madill007530e2017-12-28 14:27:04 -05006482bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6483{
6484 if (!context->getExtensions().fence)
6485 {
6486 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6487 return false;
6488 }
6489
6490 if (condition != GL_ALL_COMPLETED_NV)
6491 {
6492 context->handleError(InvalidEnum());
6493 return false;
6494 }
6495
6496 FenceNV *fenceObject = context->getFenceNV(fence);
6497
6498 if (fenceObject == nullptr)
6499 {
6500 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6501 return false;
6502 }
6503
6504 return true;
6505}
6506
6507bool ValidateTestFenceNV(Context *context, GLuint fence)
6508{
6509 if (!context->getExtensions().fence)
6510 {
6511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6512 return false;
6513 }
6514
6515 FenceNV *fenceObject = context->getFenceNV(fence);
6516
6517 if (fenceObject == nullptr)
6518 {
6519 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6520 return false;
6521 }
6522
6523 if (fenceObject->isSet() != GL_TRUE)
6524 {
6525 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6526 return false;
6527 }
6528
6529 return true;
6530}
6531
6532bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006533 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006534 GLsizei levels,
6535 GLenum internalformat,
6536 GLsizei width,
6537 GLsizei height)
6538{
6539 if (!context->getExtensions().textureStorage)
6540 {
6541 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6542 return false;
6543 }
6544
6545 if (context->getClientMajorVersion() < 3)
6546 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006547 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006548 height);
6549 }
6550
6551 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006552 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006553 1);
6554}
6555
6556bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6557{
6558 if (!context->getExtensions().instancedArrays)
6559 {
6560 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6561 return false;
6562 }
6563
6564 if (index >= MAX_VERTEX_ATTRIBS)
6565 {
6566 context->handleError(InvalidValue());
6567 return false;
6568 }
6569
6570 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6571 {
6572 if (index == 0 && divisor != 0)
6573 {
6574 const char *errorMessage =
6575 "The current context doesn't support setting a non-zero divisor on the "
6576 "attribute with index zero. "
6577 "Please reorder the attributes in your vertex shader so that attribute zero "
6578 "can have a zero divisor.";
6579 context->handleError(InvalidOperation() << errorMessage);
6580
6581 // We also output an error message to the debugger window if tracing is active, so
6582 // that developers can see the error message.
6583 ERR() << errorMessage;
6584 return false;
6585 }
6586 }
6587
6588 return true;
6589}
6590
6591bool ValidateTexImage3DOES(Context *context,
6592 GLenum target,
6593 GLint level,
6594 GLenum internalformat,
6595 GLsizei width,
6596 GLsizei height,
6597 GLsizei depth,
6598 GLint border,
6599 GLenum format,
6600 GLenum type,
6601 const void *pixels)
6602{
6603 UNIMPLEMENTED(); // FIXME
6604 return false;
6605}
6606
6607bool ValidatePopGroupMarkerEXT(Context *context)
6608{
6609 if (!context->getExtensions().debugMarker)
6610 {
6611 // The debug marker calls should not set error state
6612 // However, it seems reasonable to set an error state if the extension is not enabled
6613 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6614 return false;
6615 }
6616
6617 return true;
6618}
6619
Jamie Madillfa920eb2018-01-04 11:45:50 -05006620bool ValidateTexStorage1DEXT(Context *context,
6621 GLenum target,
6622 GLsizei levels,
6623 GLenum internalformat,
6624 GLsizei width)
6625{
6626 UNIMPLEMENTED();
6627 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6628 return false;
6629}
6630
6631bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006632 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006633 GLsizei levels,
6634 GLenum internalformat,
6635 GLsizei width,
6636 GLsizei height,
6637 GLsizei depth)
6638{
6639 if (!context->getExtensions().textureStorage)
6640 {
6641 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6642 return false;
6643 }
6644
6645 if (context->getClientMajorVersion() < 3)
6646 {
6647 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6648 return false;
6649 }
6650
6651 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6652 depth);
6653}
6654
Jamie Madillc29968b2016-01-20 11:17:23 -05006655} // namespace gl