blob: 8260719d1d6a8e5fb72e32b86a067e01a08bf6cc [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:
797 return context->getClientVersion() < Version(2, 0);
798
Jamie Madillbe849e42017-05-02 15:49:00 -0400799 default:
800 return false;
801 }
802}
803
Geoff Langfc32e8b2017-05-31 14:16:59 -0400804// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
805// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400806bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400807{
808 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400809 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
810 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400811 {
812 return true;
813 }
814
815 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
816 if (c >= 9 && c <= 13)
817 {
818 return true;
819 }
820
821 return false;
822}
823
Geoff Langcab92ee2017-07-19 17:32:07 -0400824bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400825{
Geoff Langa71a98e2017-06-19 15:15:00 -0400826 for (size_t i = 0; i < len; i++)
827 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400828 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400829 {
830 return false;
831 }
832 }
833
834 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400835}
836
Geoff Langcab92ee2017-07-19 17:32:07 -0400837bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
838{
839 enum class ParseState
840 {
841 // Have not seen an ASCII non-whitespace character yet on
842 // this line. Possible that we might see a preprocessor
843 // directive.
844 BEGINING_OF_LINE,
845
846 // Have seen at least one ASCII non-whitespace character
847 // on this line.
848 MIDDLE_OF_LINE,
849
850 // Handling a preprocessor directive. Passes through all
851 // characters up to the end of the line. Disables comment
852 // processing.
853 IN_PREPROCESSOR_DIRECTIVE,
854
855 // Handling a single-line comment. The comment text is
856 // replaced with a single space.
857 IN_SINGLE_LINE_COMMENT,
858
859 // Handling a multi-line comment. Newlines are passed
860 // through to preserve line numbers.
861 IN_MULTI_LINE_COMMENT
862 };
863
864 ParseState state = ParseState::BEGINING_OF_LINE;
865 size_t pos = 0;
866
867 while (pos < len)
868 {
869 char c = str[pos];
870 char next = pos + 1 < len ? str[pos + 1] : 0;
871
872 // Check for newlines
873 if (c == '\n' || c == '\r')
874 {
875 if (state != ParseState::IN_MULTI_LINE_COMMENT)
876 {
877 state = ParseState::BEGINING_OF_LINE;
878 }
879
880 pos++;
881 continue;
882 }
883
884 switch (state)
885 {
886 case ParseState::BEGINING_OF_LINE:
887 if (c == ' ')
888 {
889 // Maintain the BEGINING_OF_LINE state until a non-space is seen
890 pos++;
891 }
892 else if (c == '#')
893 {
894 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
895 pos++;
896 }
897 else
898 {
899 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
900 state = ParseState::MIDDLE_OF_LINE;
901 }
902 break;
903
904 case ParseState::MIDDLE_OF_LINE:
905 if (c == '/' && next == '/')
906 {
907 state = ParseState::IN_SINGLE_LINE_COMMENT;
908 pos++;
909 }
910 else if (c == '/' && next == '*')
911 {
912 state = ParseState::IN_MULTI_LINE_COMMENT;
913 pos++;
914 }
915 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
916 {
917 // Skip line continuation characters
918 }
919 else if (!IsValidESSLCharacter(c))
920 {
921 return false;
922 }
923 pos++;
924 break;
925
926 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700927 // Line-continuation characters may not be permitted.
928 // Otherwise, just pass it through. Do not parse comments in this state.
929 if (!lineContinuationAllowed && c == '\\')
930 {
931 return false;
932 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400933 pos++;
934 break;
935
936 case ParseState::IN_SINGLE_LINE_COMMENT:
937 // Line-continuation characters are processed before comment processing.
938 // Advance string if a new line character is immediately behind
939 // line-continuation character.
940 if (c == '\\' && (next == '\n' || next == '\r'))
941 {
942 pos++;
943 }
944 pos++;
945 break;
946
947 case ParseState::IN_MULTI_LINE_COMMENT:
948 if (c == '*' && next == '/')
949 {
950 state = ParseState::MIDDLE_OF_LINE;
951 pos++;
952 }
953 pos++;
954 break;
955 }
956 }
957
958 return true;
959}
960
Jamie Madill5b772312018-03-08 20:28:32 -0500961bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700962{
963 ASSERT(context->isWebGL());
964
965 // WebGL 1.0 [Section 6.16] GLSL Constructs
966 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
967 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
968 {
969 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
970 return false;
971 }
972
973 return true;
974}
975
Jamie Madill5b772312018-03-08 20:28:32 -0500976bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700977{
978 ASSERT(context->isWebGL());
979
980 if (context->isWebGL1() && length > 256)
981 {
982 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
983 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
984 // locations.
985 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
986
987 return false;
988 }
989 else if (length > 1024)
990 {
991 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
992 // uniform and attribute locations.
993 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
994 return false;
995 }
996
997 return true;
998}
999
Jamie Madill007530e2017-12-28 14:27:04 -05001000bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1001{
1002 if (!context->getExtensions().pathRendering)
1003 {
1004 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1005 return false;
1006 }
1007
1008 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1009 {
1010 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1011 return false;
1012 }
1013 return true;
1014}
Jamie Madillc29968b2016-01-20 11:17:23 -05001015} // anonymous namespace
1016
Geoff Langff5b2d52016-09-07 11:32:23 -04001017bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001018 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001019 GLint level,
1020 GLenum internalformat,
1021 bool isCompressed,
1022 bool isSubImage,
1023 GLint xoffset,
1024 GLint yoffset,
1025 GLsizei width,
1026 GLsizei height,
1027 GLint border,
1028 GLenum format,
1029 GLenum type,
1030 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001031 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001032{
Jamie Madill6f38f822014-06-06 17:12:20 -04001033 if (!ValidTexture2DDestinationTarget(context, target))
1034 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001035 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001036 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001037 }
1038
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001039 TextureType texType = TextureTargetToType(target);
1040 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001042 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001043 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001044 }
1045
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001046 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001047 {
1048 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1049 return false;
1050 }
1051
1052 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001053 std::numeric_limits<GLsizei>::max() - yoffset < height)
1054 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001055 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001056 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001057 }
1058
Geoff Lang6e898aa2017-06-02 11:17:26 -04001059 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1060 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1061 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1062 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1063 // case.
1064 bool nonEqualFormatsAllowed =
1065 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1066 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1067
1068 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001069 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001070 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001071 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001072 }
1073
Geoff Langaae65a42014-05-26 12:43:44 -04001074 const gl::Caps &caps = context->getCaps();
1075
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001076 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001077 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001078 case TextureType::_2D:
1079 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1080 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1081 {
1082 context->handleError(InvalidValue());
1083 return false;
1084 }
1085 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001086
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001087 case TextureType::Rectangle:
1088 ASSERT(level == 0);
1089 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1090 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1091 {
1092 context->handleError(InvalidValue());
1093 return false;
1094 }
1095 if (isCompressed)
1096 {
1097 context->handleError(InvalidEnum()
1098 << "Rectangle texture cannot have a compressed format.");
1099 return false;
1100 }
1101 break;
1102
1103 case TextureType::CubeMap:
1104 if (!isSubImage && width != height)
1105 {
1106 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1107 return false;
1108 }
1109
1110 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1111 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1112 {
1113 context->handleError(InvalidValue());
1114 return false;
1115 }
1116 break;
1117
1118 default:
1119 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001120 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001121 }
1122
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001123 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001124 if (!texture)
1125 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001126 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001127 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001128 }
1129
Geoff Langa9be0dc2014-12-17 12:34:40 -05001130 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001131 {
Geoff Langca271392017-04-05 12:30:00 -04001132 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1133 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001135 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001136 return false;
1137 }
1138
Geoff Langa9be0dc2014-12-17 12:34:40 -05001139 if (format != GL_NONE)
1140 {
Geoff Langca271392017-04-05 12:30:00 -04001141 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1142 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001143 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001145 return false;
1146 }
1147 }
1148
1149 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1150 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1151 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001152 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001153 return false;
1154 }
Geoff Langfb052642017-10-24 13:42:09 -04001155
1156 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001157 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001158 {
1159 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1160 return false;
1161 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001162 }
1163 else
1164 {
Geoff Lang69cce582015-09-17 13:20:36 -04001165 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001166 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001167 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001168 return false;
1169 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001170 }
1171
1172 // Verify zero border
1173 if (border != 0)
1174 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001175 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001176 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001177 }
1178
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001179 if (isCompressed)
1180 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001181 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001182 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1183 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184 switch (actualInternalFormat)
1185 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001186 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1187 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1188 if (!context->getExtensions().textureCompressionDXT1)
1189 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001190 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001191 return false;
1192 }
1193 break;
1194 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001195 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001196 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001197 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001198 return false;
1199 }
1200 break;
1201 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1202 if (!context->getExtensions().textureCompressionDXT5)
1203 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001204 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001205 return false;
1206 }
1207 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001208 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1209 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1210 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1211 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1212 if (!context->getExtensions().textureCompressionS3TCsRGB)
1213 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001214 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001215 return false;
1216 }
1217 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001218 case GL_ETC1_RGB8_OES:
1219 if (!context->getExtensions().compressedETC1RGB8Texture)
1220 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001221 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001222 return false;
1223 }
Geoff Lang86f81162017-10-30 15:10:45 -04001224 if (isSubImage)
1225 {
1226 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1227 return false;
1228 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001229 break;
1230 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001231 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1232 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1233 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1234 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001235 if (!context->getExtensions().lossyETCDecode)
1236 {
Geoff Lang86f81162017-10-30 15:10:45 -04001237 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001238 return false;
1239 }
1240 break;
1241 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001242 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001243 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001244 }
Geoff Lang966c9402017-04-18 12:38:27 -04001245
1246 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001247 {
Geoff Lang966c9402017-04-18 12:38:27 -04001248 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1249 height, texture->getWidth(target, level),
1250 texture->getHeight(target, level)))
1251 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001252 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001253 return false;
1254 }
1255
1256 if (format != actualInternalFormat)
1257 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001258 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001259 return false;
1260 }
1261 }
1262 else
1263 {
1264 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1265 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001266 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001267 return false;
1268 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001269 }
1270 }
1271 else
1272 {
1273 // validate <type> by itself (used as secondary key below)
1274 switch (type)
1275 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001276 case GL_UNSIGNED_BYTE:
1277 case GL_UNSIGNED_SHORT_5_6_5:
1278 case GL_UNSIGNED_SHORT_4_4_4_4:
1279 case GL_UNSIGNED_SHORT_5_5_5_1:
1280 case GL_UNSIGNED_SHORT:
1281 case GL_UNSIGNED_INT:
1282 case GL_UNSIGNED_INT_24_8_OES:
1283 case GL_HALF_FLOAT_OES:
1284 case GL_FLOAT:
1285 break;
1286 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001287 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001288 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001289 }
1290
1291 // validate <format> + <type> combinations
1292 // - invalid <format> -> sets INVALID_ENUM
1293 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1294 switch (format)
1295 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001296 case GL_ALPHA:
1297 case GL_LUMINANCE:
1298 case GL_LUMINANCE_ALPHA:
1299 switch (type)
1300 {
1301 case GL_UNSIGNED_BYTE:
1302 case GL_FLOAT:
1303 case GL_HALF_FLOAT_OES:
1304 break;
1305 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001306 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001307 return false;
1308 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001309 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001310 case GL_RED:
1311 case GL_RG:
1312 if (!context->getExtensions().textureRG)
1313 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001314 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001315 return false;
1316 }
1317 switch (type)
1318 {
1319 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001320 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001321 case GL_FLOAT:
1322 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001323 if (!context->getExtensions().textureFloat)
1324 {
1325 context->handleError(InvalidEnum());
1326 return false;
1327 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001328 break;
1329 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001330 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001331 return false;
1332 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001333 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001334 case GL_RGB:
1335 switch (type)
1336 {
1337 case GL_UNSIGNED_BYTE:
1338 case GL_UNSIGNED_SHORT_5_6_5:
1339 case GL_FLOAT:
1340 case GL_HALF_FLOAT_OES:
1341 break;
1342 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001343 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001344 return false;
1345 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001346 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001347 case GL_RGBA:
1348 switch (type)
1349 {
1350 case GL_UNSIGNED_BYTE:
1351 case GL_UNSIGNED_SHORT_4_4_4_4:
1352 case GL_UNSIGNED_SHORT_5_5_5_1:
1353 case GL_FLOAT:
1354 case GL_HALF_FLOAT_OES:
1355 break;
1356 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001358 return false;
1359 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001360 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001361 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001362 if (!context->getExtensions().textureFormatBGRA8888)
1363 {
1364 context->handleError(InvalidEnum());
1365 return false;
1366 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001367 switch (type)
1368 {
1369 case GL_UNSIGNED_BYTE:
1370 break;
1371 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001372 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001373 return false;
1374 }
1375 break;
1376 case GL_SRGB_EXT:
1377 case GL_SRGB_ALPHA_EXT:
1378 if (!context->getExtensions().sRGB)
1379 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001380 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001381 return false;
1382 }
1383 switch (type)
1384 {
1385 case GL_UNSIGNED_BYTE:
1386 break;
1387 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001389 return false;
1390 }
1391 break;
1392 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1393 // handled below
1394 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1395 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1396 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1397 break;
1398 case GL_DEPTH_COMPONENT:
1399 switch (type)
1400 {
1401 case GL_UNSIGNED_SHORT:
1402 case GL_UNSIGNED_INT:
1403 break;
1404 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001405 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001406 return false;
1407 }
1408 break;
1409 case GL_DEPTH_STENCIL_OES:
1410 switch (type)
1411 {
1412 case GL_UNSIGNED_INT_24_8_OES:
1413 break;
1414 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001415 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001416 return false;
1417 }
1418 break;
1419 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001420 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001421 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001422 }
1423
1424 switch (format)
1425 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001426 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1427 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1428 if (context->getExtensions().textureCompressionDXT1)
1429 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001430 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001431 return false;
1432 }
1433 else
1434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001435 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001436 return false;
1437 }
1438 break;
1439 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1440 if (context->getExtensions().textureCompressionDXT3)
1441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001442 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 else
1446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001447 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001448 return false;
1449 }
1450 break;
1451 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1452 if (context->getExtensions().textureCompressionDXT5)
1453 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001454 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001455 return false;
1456 }
1457 else
1458 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001459 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001460 return false;
1461 }
1462 break;
1463 case GL_ETC1_RGB8_OES:
1464 if (context->getExtensions().compressedETC1RGB8Texture)
1465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001466 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 return false;
1468 }
1469 else
1470 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001471 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001472 return false;
1473 }
1474 break;
1475 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001476 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1477 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1478 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1479 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001480 if (context->getExtensions().lossyETCDecode)
1481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001482 context->handleError(InvalidOperation()
1483 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001484 return false;
1485 }
1486 else
1487 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001488 context->handleError(InvalidEnum()
1489 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001490 return false;
1491 }
1492 break;
1493 case GL_DEPTH_COMPONENT:
1494 case GL_DEPTH_STENCIL_OES:
1495 if (!context->getExtensions().depthTextures)
1496 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001497 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001498 return false;
1499 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001500 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001501 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001502 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001503 return false;
1504 }
1505 // OES_depth_texture supports loading depth data and multiple levels,
1506 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001507 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001508 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001509 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1510 return false;
1511 }
1512 if (level != 0)
1513 {
1514 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001515 return false;
1516 }
1517 break;
1518 default:
1519 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001520 }
1521
Geoff Lang6e898aa2017-06-02 11:17:26 -04001522 if (!isSubImage)
1523 {
1524 switch (internalformat)
1525 {
1526 case GL_RGBA32F:
1527 if (!context->getExtensions().colorBufferFloatRGBA)
1528 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001529 context->handleError(InvalidValue()
1530 << "Sized GL_RGBA32F internal format requires "
1531 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001532 return false;
1533 }
1534 if (type != GL_FLOAT)
1535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001536 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001537 return false;
1538 }
1539 if (format != GL_RGBA)
1540 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001541 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001542 return false;
1543 }
1544 break;
1545
1546 case GL_RGB32F:
1547 if (!context->getExtensions().colorBufferFloatRGB)
1548 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001549 context->handleError(InvalidValue()
1550 << "Sized GL_RGB32F internal format requires "
1551 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001552 return false;
1553 }
1554 if (type != GL_FLOAT)
1555 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001556 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001557 return false;
1558 }
1559 if (format != GL_RGB)
1560 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001561 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001562 return false;
1563 }
1564 break;
1565
1566 default:
1567 break;
1568 }
1569 }
1570
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001571 if (type == GL_FLOAT)
1572 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001573 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001574 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001575 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001576 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001577 }
1578 }
1579 else if (type == GL_HALF_FLOAT_OES)
1580 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001581 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001582 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001583 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001584 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001585 }
1586 }
1587 }
1588
Geoff Langdbcced82017-06-06 15:55:54 -04001589 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001590 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001591 imageSize))
1592 {
1593 return false;
1594 }
1595
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001596 return true;
1597}
1598
He Yunchaoced53ae2016-11-29 15:00:51 +08001599bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001600 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001601 GLsizei levels,
1602 GLenum internalformat,
1603 GLsizei width,
1604 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001605{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001606 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1607 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001608 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001609 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001610 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001611 }
1612
1613 if (width < 1 || height < 1 || levels < 1)
1614 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001615 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001616 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001617 }
1618
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001619 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001620 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001621 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001622 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001623 }
1624
1625 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1626 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001627 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001628 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001629 }
1630
Geoff Langca271392017-04-05 12:30:00 -04001631 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001632 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001634 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001635 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 }
1637
Geoff Langaae65a42014-05-26 12:43:44 -04001638 const gl::Caps &caps = context->getCaps();
1639
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001640 switch (target)
1641 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001642 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001643 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1644 static_cast<GLuint>(height) > caps.max2DTextureSize)
1645 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001646 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001647 return false;
1648 }
1649 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001650 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001651 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1652 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1653 {
1654 context->handleError(InvalidValue());
1655 return false;
1656 }
1657 if (formatInfo.compressed)
1658 {
1659 context->handleError(InvalidEnum()
1660 << "Rectangle texture cannot have a compressed format.");
1661 return false;
1662 }
1663 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001664 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001665 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1666 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1667 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001668 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001669 return false;
1670 }
1671 break;
1672 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001673 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001674 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001675 }
1676
Geoff Langc0b9ef42014-07-02 10:02:37 -04001677 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001678 {
1679 if (!gl::isPow2(width) || !gl::isPow2(height))
1680 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001681 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001682 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001683 }
1684 }
1685
1686 switch (internalformat)
1687 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001688 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1689 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1690 if (!context->getExtensions().textureCompressionDXT1)
1691 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001692 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001693 return false;
1694 }
1695 break;
1696 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1697 if (!context->getExtensions().textureCompressionDXT3)
1698 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001699 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001700 return false;
1701 }
1702 break;
1703 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1704 if (!context->getExtensions().textureCompressionDXT5)
1705 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001706 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001707 return false;
1708 }
1709 break;
1710 case GL_ETC1_RGB8_OES:
1711 if (!context->getExtensions().compressedETC1RGB8Texture)
1712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001713 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001714 return false;
1715 }
1716 break;
1717 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001718 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1719 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1720 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1721 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001722 if (!context->getExtensions().lossyETCDecode)
1723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001724 context->handleError(InvalidEnum()
1725 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001726 return false;
1727 }
1728 break;
1729 case GL_RGBA32F_EXT:
1730 case GL_RGB32F_EXT:
1731 case GL_ALPHA32F_EXT:
1732 case GL_LUMINANCE32F_EXT:
1733 case GL_LUMINANCE_ALPHA32F_EXT:
1734 if (!context->getExtensions().textureFloat)
1735 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001736 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001737 return false;
1738 }
1739 break;
1740 case GL_RGBA16F_EXT:
1741 case GL_RGB16F_EXT:
1742 case GL_ALPHA16F_EXT:
1743 case GL_LUMINANCE16F_EXT:
1744 case GL_LUMINANCE_ALPHA16F_EXT:
1745 if (!context->getExtensions().textureHalfFloat)
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_R8_EXT:
1752 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001753 if (!context->getExtensions().textureRG)
1754 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001755 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001756 return false;
1757 }
1758 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001759 case GL_R16F_EXT:
1760 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001761 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1762 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001763 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001764 return false;
1765 }
1766 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001767 case GL_R32F_EXT:
1768 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001769 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001770 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001771 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001772 return false;
1773 }
1774 break;
1775 case GL_DEPTH_COMPONENT16:
1776 case GL_DEPTH_COMPONENT32_OES:
1777 case GL_DEPTH24_STENCIL8_OES:
1778 if (!context->getExtensions().depthTextures)
1779 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001780 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001781 return false;
1782 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001783 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001785 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001786 return false;
1787 }
1788 // ANGLE_depth_texture only supports 1-level textures
1789 if (levels != 1)
1790 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001791 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001792 return false;
1793 }
1794 break;
1795 default:
1796 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001797 }
1798
Geoff Lang691e58c2014-12-19 17:03:25 -05001799 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001800 if (!texture || texture->id() == 0)
1801 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001802 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001803 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001804 }
1805
Geoff Lang69cce582015-09-17 13:20:36 -04001806 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001807 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001808 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001809 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001810 }
1811
1812 return true;
1813}
1814
He Yunchaoced53ae2016-11-29 15:00:51 +08001815bool ValidateDiscardFramebufferEXT(Context *context,
1816 GLenum target,
1817 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001818 const GLenum *attachments)
1819{
Jamie Madillc29968b2016-01-20 11:17:23 -05001820 if (!context->getExtensions().discardFramebuffer)
1821 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001822 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001823 return false;
1824 }
1825
Austin Kinross08332632015-05-05 13:35:47 -07001826 bool defaultFramebuffer = false;
1827
1828 switch (target)
1829 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001830 case GL_FRAMEBUFFER:
1831 defaultFramebuffer =
1832 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1833 break;
1834 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001835 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001836 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001837 }
1838
He Yunchaoced53ae2016-11-29 15:00:51 +08001839 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1840 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001841}
1842
Austin Kinrossbc781f32015-10-26 09:27:38 -07001843bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1844{
1845 if (!context->getExtensions().vertexArrayObject)
1846 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001847 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001848 return false;
1849 }
1850
1851 return ValidateBindVertexArrayBase(context, array);
1852}
1853
Jamie Madilld7576732017-08-26 18:49:50 -04001854bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001855{
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
Olli Etuaho41997e72016-03-10 13:38:39 +02001862 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001863}
1864
Jamie Madilld7576732017-08-26 18:49:50 -04001865bool ValidateGenVertexArraysOES(Context *context, GLsizei n, 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 ValidateIsVertexArrayOES(Context *context, GLuint array)
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
1884 return true;
1885}
Geoff Langc5629752015-12-07 16:29:04 -05001886
1887bool ValidateProgramBinaryOES(Context *context,
1888 GLuint program,
1889 GLenum binaryFormat,
1890 const void *binary,
1891 GLint length)
1892{
1893 if (!context->getExtensions().getProgramBinary)
1894 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001895 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001896 return false;
1897 }
1898
1899 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1900}
1901
1902bool ValidateGetProgramBinaryOES(Context *context,
1903 GLuint program,
1904 GLsizei bufSize,
1905 GLsizei *length,
1906 GLenum *binaryFormat,
1907 void *binary)
1908{
1909 if (!context->getExtensions().getProgramBinary)
1910 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001911 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001912 return false;
1913 }
1914
1915 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1916}
Geoff Lange102fee2015-12-10 11:23:30 -05001917
Geoff Lang70d0f492015-12-10 17:45:46 -05001918static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1919{
1920 switch (source)
1921 {
1922 case GL_DEBUG_SOURCE_API:
1923 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1924 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1925 case GL_DEBUG_SOURCE_OTHER:
1926 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1927 return !mustBeThirdPartyOrApplication;
1928
1929 case GL_DEBUG_SOURCE_THIRD_PARTY:
1930 case GL_DEBUG_SOURCE_APPLICATION:
1931 return true;
1932
1933 default:
1934 return false;
1935 }
1936}
1937
1938static bool ValidDebugType(GLenum type)
1939{
1940 switch (type)
1941 {
1942 case GL_DEBUG_TYPE_ERROR:
1943 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1944 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1945 case GL_DEBUG_TYPE_PERFORMANCE:
1946 case GL_DEBUG_TYPE_PORTABILITY:
1947 case GL_DEBUG_TYPE_OTHER:
1948 case GL_DEBUG_TYPE_MARKER:
1949 case GL_DEBUG_TYPE_PUSH_GROUP:
1950 case GL_DEBUG_TYPE_POP_GROUP:
1951 return true;
1952
1953 default:
1954 return false;
1955 }
1956}
1957
1958static bool ValidDebugSeverity(GLenum severity)
1959{
1960 switch (severity)
1961 {
1962 case GL_DEBUG_SEVERITY_HIGH:
1963 case GL_DEBUG_SEVERITY_MEDIUM:
1964 case GL_DEBUG_SEVERITY_LOW:
1965 case GL_DEBUG_SEVERITY_NOTIFICATION:
1966 return true;
1967
1968 default:
1969 return false;
1970 }
1971}
1972
Geoff Lange102fee2015-12-10 11:23:30 -05001973bool ValidateDebugMessageControlKHR(Context *context,
1974 GLenum source,
1975 GLenum type,
1976 GLenum severity,
1977 GLsizei count,
1978 const GLuint *ids,
1979 GLboolean enabled)
1980{
1981 if (!context->getExtensions().debug)
1982 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001983 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001984 return false;
1985 }
1986
Geoff Lang70d0f492015-12-10 17:45:46 -05001987 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1988 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001989 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001990 return false;
1991 }
1992
1993 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1994 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001995 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001996 return false;
1997 }
1998
1999 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2000 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002001 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002002 return false;
2003 }
2004
2005 if (count > 0)
2006 {
2007 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2008 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002009 context->handleError(
2010 InvalidOperation()
2011 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002012 return false;
2013 }
2014
2015 if (severity != GL_DONT_CARE)
2016 {
Jamie Madill437fa652016-05-03 15:13:24 -04002017 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002018 InvalidOperation()
2019 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002020 return false;
2021 }
2022 }
2023
Geoff Lange102fee2015-12-10 11:23:30 -05002024 return true;
2025}
2026
2027bool ValidateDebugMessageInsertKHR(Context *context,
2028 GLenum source,
2029 GLenum type,
2030 GLuint id,
2031 GLenum severity,
2032 GLsizei length,
2033 const GLchar *buf)
2034{
2035 if (!context->getExtensions().debug)
2036 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002037 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002038 return false;
2039 }
2040
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002041 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002042 {
2043 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2044 // not generate an error.
2045 return false;
2046 }
2047
2048 if (!ValidDebugSeverity(severity))
2049 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002051 return false;
2052 }
2053
2054 if (!ValidDebugType(type))
2055 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002056 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002057 return false;
2058 }
2059
2060 if (!ValidDebugSource(source, true))
2061 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002062 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002063 return false;
2064 }
2065
2066 size_t messageLength = (length < 0) ? strlen(buf) : length;
2067 if (messageLength > context->getExtensions().maxDebugMessageLength)
2068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002069 context->handleError(InvalidValue()
2070 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002071 return false;
2072 }
2073
Geoff Lange102fee2015-12-10 11:23:30 -05002074 return true;
2075}
2076
2077bool ValidateDebugMessageCallbackKHR(Context *context,
2078 GLDEBUGPROCKHR callback,
2079 const void *userParam)
2080{
2081 if (!context->getExtensions().debug)
2082 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002083 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002084 return false;
2085 }
2086
Geoff Lange102fee2015-12-10 11:23:30 -05002087 return true;
2088}
2089
2090bool ValidateGetDebugMessageLogKHR(Context *context,
2091 GLuint count,
2092 GLsizei bufSize,
2093 GLenum *sources,
2094 GLenum *types,
2095 GLuint *ids,
2096 GLenum *severities,
2097 GLsizei *lengths,
2098 GLchar *messageLog)
2099{
2100 if (!context->getExtensions().debug)
2101 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002102 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002103 return false;
2104 }
2105
Geoff Lang70d0f492015-12-10 17:45:46 -05002106 if (bufSize < 0 && messageLog != nullptr)
2107 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002108 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002109 return false;
2110 }
2111
Geoff Lange102fee2015-12-10 11:23:30 -05002112 return true;
2113}
2114
2115bool ValidatePushDebugGroupKHR(Context *context,
2116 GLenum source,
2117 GLuint id,
2118 GLsizei length,
2119 const GLchar *message)
2120{
2121 if (!context->getExtensions().debug)
2122 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002123 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002124 return false;
2125 }
2126
Geoff Lang70d0f492015-12-10 17:45:46 -05002127 if (!ValidDebugSource(source, true))
2128 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002129 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002130 return false;
2131 }
2132
2133 size_t messageLength = (length < 0) ? strlen(message) : length;
2134 if (messageLength > context->getExtensions().maxDebugMessageLength)
2135 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002136 context->handleError(InvalidValue()
2137 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002138 return false;
2139 }
2140
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002141 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002142 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2143 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002144 context
2145 ->handleError(StackOverflow()
2146 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002147 return false;
2148 }
2149
Geoff Lange102fee2015-12-10 11:23:30 -05002150 return true;
2151}
2152
2153bool ValidatePopDebugGroupKHR(Context *context)
2154{
2155 if (!context->getExtensions().debug)
2156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002158 return false;
2159 }
2160
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002161 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002162 if (currentStackSize <= 1)
2163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002164 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002165 return false;
2166 }
2167
2168 return true;
2169}
2170
2171static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2172{
2173 switch (identifier)
2174 {
2175 case GL_BUFFER:
2176 if (context->getBuffer(name) == nullptr)
2177 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002178 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002179 return false;
2180 }
2181 return true;
2182
2183 case GL_SHADER:
2184 if (context->getShader(name) == nullptr)
2185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002186 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002187 return false;
2188 }
2189 return true;
2190
2191 case GL_PROGRAM:
2192 if (context->getProgram(name) == nullptr)
2193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002194 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002195 return false;
2196 }
2197 return true;
2198
2199 case GL_VERTEX_ARRAY:
2200 if (context->getVertexArray(name) == nullptr)
2201 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002202 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002203 return false;
2204 }
2205 return true;
2206
2207 case GL_QUERY:
2208 if (context->getQuery(name) == nullptr)
2209 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002210 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002211 return false;
2212 }
2213 return true;
2214
2215 case GL_TRANSFORM_FEEDBACK:
2216 if (context->getTransformFeedback(name) == nullptr)
2217 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002218 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002219 return false;
2220 }
2221 return true;
2222
2223 case GL_SAMPLER:
2224 if (context->getSampler(name) == nullptr)
2225 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002226 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002227 return false;
2228 }
2229 return true;
2230
2231 case GL_TEXTURE:
2232 if (context->getTexture(name) == nullptr)
2233 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002234 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002235 return false;
2236 }
2237 return true;
2238
2239 case GL_RENDERBUFFER:
2240 if (context->getRenderbuffer(name) == nullptr)
2241 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002242 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002243 return false;
2244 }
2245 return true;
2246
2247 case GL_FRAMEBUFFER:
2248 if (context->getFramebuffer(name) == nullptr)
2249 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002250 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002251 return false;
2252 }
2253 return true;
2254
2255 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002256 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002257 return false;
2258 }
Geoff Lange102fee2015-12-10 11:23:30 -05002259}
2260
Martin Radev9d901792016-07-15 15:58:58 +03002261static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2262{
2263 size_t labelLength = 0;
2264
2265 if (length < 0)
2266 {
2267 if (label != nullptr)
2268 {
2269 labelLength = strlen(label);
2270 }
2271 }
2272 else
2273 {
2274 labelLength = static_cast<size_t>(length);
2275 }
2276
2277 if (labelLength > context->getExtensions().maxLabelLength)
2278 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002279 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002280 return false;
2281 }
2282
2283 return true;
2284}
2285
Geoff Lange102fee2015-12-10 11:23:30 -05002286bool ValidateObjectLabelKHR(Context *context,
2287 GLenum identifier,
2288 GLuint name,
2289 GLsizei length,
2290 const GLchar *label)
2291{
2292 if (!context->getExtensions().debug)
2293 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002294 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002295 return false;
2296 }
2297
Geoff Lang70d0f492015-12-10 17:45:46 -05002298 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2299 {
2300 return false;
2301 }
2302
Martin Radev9d901792016-07-15 15:58:58 +03002303 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002304 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002305 return false;
2306 }
2307
Geoff Lange102fee2015-12-10 11:23:30 -05002308 return true;
2309}
2310
2311bool ValidateGetObjectLabelKHR(Context *context,
2312 GLenum identifier,
2313 GLuint name,
2314 GLsizei bufSize,
2315 GLsizei *length,
2316 GLchar *label)
2317{
2318 if (!context->getExtensions().debug)
2319 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002320 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002321 return false;
2322 }
2323
Geoff Lang70d0f492015-12-10 17:45:46 -05002324 if (bufSize < 0)
2325 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002326 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002327 return false;
2328 }
2329
2330 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2331 {
2332 return false;
2333 }
2334
Martin Radev9d901792016-07-15 15:58:58 +03002335 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002336}
2337
2338static bool ValidateObjectPtrName(Context *context, const void *ptr)
2339{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002340 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002341 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002342 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002343 return false;
2344 }
2345
Geoff Lange102fee2015-12-10 11:23:30 -05002346 return true;
2347}
2348
2349bool ValidateObjectPtrLabelKHR(Context *context,
2350 const void *ptr,
2351 GLsizei length,
2352 const GLchar *label)
2353{
2354 if (!context->getExtensions().debug)
2355 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002356 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002357 return false;
2358 }
2359
Geoff Lang70d0f492015-12-10 17:45:46 -05002360 if (!ValidateObjectPtrName(context, ptr))
2361 {
2362 return false;
2363 }
2364
Martin Radev9d901792016-07-15 15:58:58 +03002365 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002366 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002367 return false;
2368 }
2369
Geoff Lange102fee2015-12-10 11:23:30 -05002370 return true;
2371}
2372
2373bool ValidateGetObjectPtrLabelKHR(Context *context,
2374 const void *ptr,
2375 GLsizei bufSize,
2376 GLsizei *length,
2377 GLchar *label)
2378{
2379 if (!context->getExtensions().debug)
2380 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002382 return false;
2383 }
2384
Geoff Lang70d0f492015-12-10 17:45:46 -05002385 if (bufSize < 0)
2386 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002387 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002388 return false;
2389 }
2390
2391 if (!ValidateObjectPtrName(context, ptr))
2392 {
2393 return false;
2394 }
2395
Martin Radev9d901792016-07-15 15:58:58 +03002396 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002397}
2398
2399bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2400{
2401 if (!context->getExtensions().debug)
2402 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002403 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002404 return false;
2405 }
2406
Geoff Lang70d0f492015-12-10 17:45:46 -05002407 // TODO: represent this in Context::getQueryParameterInfo.
2408 switch (pname)
2409 {
2410 case GL_DEBUG_CALLBACK_FUNCTION:
2411 case GL_DEBUG_CALLBACK_USER_PARAM:
2412 break;
2413
2414 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002415 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002416 return false;
2417 }
2418
Geoff Lange102fee2015-12-10 11:23:30 -05002419 return true;
2420}
Jamie Madillc29968b2016-01-20 11:17:23 -05002421
2422bool ValidateBlitFramebufferANGLE(Context *context,
2423 GLint srcX0,
2424 GLint srcY0,
2425 GLint srcX1,
2426 GLint srcY1,
2427 GLint dstX0,
2428 GLint dstY0,
2429 GLint dstX1,
2430 GLint dstY1,
2431 GLbitfield mask,
2432 GLenum filter)
2433{
2434 if (!context->getExtensions().framebufferBlit)
2435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002436 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002437 return false;
2438 }
2439
2440 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2441 {
2442 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002443 context->handleError(InvalidOperation() << "Scaling and flipping in "
2444 "BlitFramebufferANGLE not supported by this "
2445 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002446 return false;
2447 }
2448
2449 if (filter == GL_LINEAR)
2450 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002451 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002452 return false;
2453 }
2454
Jamie Madill51f40ec2016-06-15 14:06:00 -04002455 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2456 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002457
2458 if (mask & GL_COLOR_BUFFER_BIT)
2459 {
2460 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2461 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2462
2463 if (readColorAttachment && drawColorAttachment)
2464 {
2465 if (!(readColorAttachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002466 readColorAttachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002467 readColorAttachment->type() != GL_RENDERBUFFER &&
2468 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002470 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002471 return false;
2472 }
2473
Geoff Langa15472a2015-08-11 11:48:03 -04002474 for (size_t drawbufferIdx = 0;
2475 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002476 {
Geoff Langa15472a2015-08-11 11:48:03 -04002477 const FramebufferAttachment *attachment =
2478 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2479 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002480 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002481 if (!(attachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002482 attachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 attachment->type() != GL_RENDERBUFFER &&
2484 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2485 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002486 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002487 return false;
2488 }
2489
2490 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002491 if (!Format::EquivalentForBlit(attachment->getFormat(),
2492 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002493 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002494 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002495 return false;
2496 }
2497 }
2498 }
2499
Jamie Madille98b1b52018-03-08 09:47:23 -05002500 GLint samples = 0;
2501 ANGLE_VALIDATION_TRY(readFramebuffer->getSamples(context, &samples));
2502 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002503 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2504 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2505 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002506 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002507 return false;
2508 }
2509 }
2510 }
2511
2512 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2513 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2514 for (size_t i = 0; i < 2; i++)
2515 {
2516 if (mask & masks[i])
2517 {
2518 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002519 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002520 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002521 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002522
2523 if (readBuffer && drawBuffer)
2524 {
2525 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2526 dstX0, dstY0, dstX1, dstY1))
2527 {
2528 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002529 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2530 "stencil blits are supported by "
2531 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002532 return false;
2533 }
2534
2535 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2536 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002537 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 return false;
2539 }
2540 }
2541 }
2542 }
2543
2544 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2545 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002546}
Jamie Madillc29968b2016-01-20 11:17:23 -05002547
Jamie Madill5b772312018-03-08 20:28:32 -05002548bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002549{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002550 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002551
2552 if (!ValidateFramebufferComplete(context, fbo, true))
Jamie Madillc29968b2016-01-20 11:17:23 -05002553 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002554 return false;
2555 }
2556
2557 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2558 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002559 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002560 return false;
2561 }
2562
Geoff Lang76e65652017-03-27 14:58:02 -04002563 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2564 {
2565 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2566 GL_SIGNED_NORMALIZED};
2567
Corentin Wallez59c41592017-07-11 13:19:54 -04002568 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002569 drawBufferIdx++)
2570 {
2571 if (!ValidateWebGLFramebufferAttachmentClearType(
2572 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2573 {
2574 return false;
2575 }
2576 }
2577 }
2578
Jamie Madillc29968b2016-01-20 11:17:23 -05002579 return true;
2580}
2581
Jamie Madill5b772312018-03-08 20:28:32 -05002582bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002583{
2584 if (!context->getExtensions().drawBuffers)
2585 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002586 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002587 return false;
2588 }
2589
2590 return ValidateDrawBuffersBase(context, n, bufs);
2591}
2592
Jamie Madill73a84962016-02-12 09:27:23 -05002593bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002594 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002595 GLint level,
2596 GLint internalformat,
2597 GLsizei width,
2598 GLsizei height,
2599 GLint border,
2600 GLenum format,
2601 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002602 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002603{
Martin Radev1be913c2016-07-11 17:59:16 +03002604 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002605 {
2606 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002607 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002608 }
2609
Martin Radev1be913c2016-07-11 17:59:16 +03002610 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002611 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002612 0, 0, width, height, 1, border, format, type, -1,
2613 pixels);
2614}
2615
2616bool ValidateTexImage2DRobust(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002617 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04002618 GLint level,
2619 GLint internalformat,
2620 GLsizei width,
2621 GLsizei height,
2622 GLint border,
2623 GLenum format,
2624 GLenum type,
2625 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002626 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002627{
2628 if (!ValidateRobustEntryPoint(context, bufSize))
2629 {
2630 return false;
2631 }
2632
2633 if (context->getClientMajorVersion() < 3)
2634 {
2635 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2636 0, 0, width, height, border, format, type, bufSize,
2637 pixels);
2638 }
2639
2640 ASSERT(context->getClientMajorVersion() >= 3);
2641 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2642 0, 0, width, height, 1, border, format, type, bufSize,
2643 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002644}
2645
2646bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002647 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002648 GLint level,
2649 GLint xoffset,
2650 GLint yoffset,
2651 GLsizei width,
2652 GLsizei height,
2653 GLenum format,
2654 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002655 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002656{
2657
Martin Radev1be913c2016-07-11 17:59:16 +03002658 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002659 {
2660 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002661 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002662 }
2663
Martin Radev1be913c2016-07-11 17:59:16 +03002664 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002665 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002666 yoffset, 0, width, height, 1, 0, format, type, -1,
2667 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002668}
2669
Geoff Langc52f6f12016-10-14 10:18:00 -04002670bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002671 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002672 GLint level,
2673 GLint xoffset,
2674 GLint yoffset,
2675 GLsizei width,
2676 GLsizei height,
2677 GLenum format,
2678 GLenum type,
2679 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002680 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002681{
2682 if (!ValidateRobustEntryPoint(context, bufSize))
2683 {
2684 return false;
2685 }
2686
2687 if (context->getClientMajorVersion() < 3)
2688 {
2689 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2690 yoffset, width, height, 0, format, type, bufSize,
2691 pixels);
2692 }
2693
2694 ASSERT(context->getClientMajorVersion() >= 3);
2695 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2696 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2697 pixels);
2698}
2699
Jamie Madill73a84962016-02-12 09:27:23 -05002700bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002701 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002702 GLint level,
2703 GLenum internalformat,
2704 GLsizei width,
2705 GLsizei height,
2706 GLint border,
2707 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002708 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002709{
Martin Radev1be913c2016-07-11 17:59:16 +03002710 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002711 {
2712 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002713 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002714 {
2715 return false;
2716 }
2717 }
2718 else
2719 {
Martin Radev1be913c2016-07-11 17:59:16 +03002720 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002721 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002722 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002723 data))
2724 {
2725 return false;
2726 }
2727 }
2728
Geoff Langca271392017-04-05 12:30:00 -04002729 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002730 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002731 if (blockSizeOrErr.isError())
2732 {
2733 context->handleError(blockSizeOrErr.getError());
2734 return false;
2735 }
2736
2737 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002738 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002739 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002740 return false;
2741 }
2742
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002743 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002744 {
2745 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2746 return false;
2747 }
2748
Jamie Madill73a84962016-02-12 09:27:23 -05002749 return true;
2750}
2751
Corentin Wallezb2931602017-04-11 15:58:57 -04002752bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002753 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002754 GLint level,
2755 GLenum internalformat,
2756 GLsizei width,
2757 GLsizei height,
2758 GLint border,
2759 GLsizei imageSize,
2760 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002761 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002762{
2763 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2764 {
2765 return false;
2766 }
2767
2768 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2769 border, imageSize, data);
2770}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002771
Corentin Wallezb2931602017-04-11 15:58:57 -04002772bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002773 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002774 GLint level,
2775 GLint xoffset,
2776 GLint yoffset,
2777 GLsizei width,
2778 GLsizei height,
2779 GLenum format,
2780 GLsizei imageSize,
2781 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002782 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002783{
2784 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2785 {
2786 return false;
2787 }
2788
2789 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2790 format, imageSize, data);
2791}
2792
Jamie Madill73a84962016-02-12 09:27:23 -05002793bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002794 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002795 GLint level,
2796 GLint xoffset,
2797 GLint yoffset,
2798 GLsizei width,
2799 GLsizei height,
2800 GLenum format,
2801 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002802 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002803{
Martin Radev1be913c2016-07-11 17:59:16 +03002804 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002805 {
2806 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002807 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002808 {
2809 return false;
2810 }
2811 }
2812 else
2813 {
Martin Radev1be913c2016-07-11 17:59:16 +03002814 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002815 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002816 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002817 data))
2818 {
2819 return false;
2820 }
2821 }
2822
Geoff Langca271392017-04-05 12:30:00 -04002823 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002824 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002825 if (blockSizeOrErr.isError())
2826 {
2827 context->handleError(blockSizeOrErr.getError());
2828 return false;
2829 }
2830
2831 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002832 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002833 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002834 return false;
2835 }
2836
2837 return true;
2838}
2839
Corentin Wallez336129f2017-10-17 15:55:40 -04002840bool ValidateGetBufferPointervOES(Context *context,
2841 BufferBinding target,
2842 GLenum pname,
2843 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002844{
Geoff Lang496c02d2016-10-20 11:38:11 -07002845 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002846}
2847
Corentin Wallez336129f2017-10-17 15:55:40 -04002848bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002849{
2850 if (!context->getExtensions().mapBuffer)
2851 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002852 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002853 return false;
2854 }
2855
Corentin Walleze4477002017-12-01 14:39:58 -05002856 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002857 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002858 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002859 return false;
2860 }
2861
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002862 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002863
2864 if (buffer == nullptr)
2865 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002866 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002867 return false;
2868 }
2869
2870 if (access != GL_WRITE_ONLY_OES)
2871 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002872 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002873 return false;
2874 }
2875
2876 if (buffer->isMapped())
2877 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002878 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002879 return false;
2880 }
2881
Geoff Lang79f71042017-08-14 16:43:43 -04002882 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002883}
2884
Corentin Wallez336129f2017-10-17 15:55:40 -04002885bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002886{
2887 if (!context->getExtensions().mapBuffer)
2888 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002889 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002890 return false;
2891 }
2892
2893 return ValidateUnmapBufferBase(context, target);
2894}
2895
2896bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002897 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002898 GLintptr offset,
2899 GLsizeiptr length,
2900 GLbitfield access)
2901{
2902 if (!context->getExtensions().mapBufferRange)
2903 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002904 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002905 return false;
2906 }
2907
2908 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2909}
2910
Corentin Wallez336129f2017-10-17 15:55:40 -04002911bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002912{
2913 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2914 ASSERT(buffer != nullptr);
2915
2916 // Check if this buffer is currently being used as a transform feedback output buffer
2917 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2918 if (transformFeedback != nullptr && transformFeedback->isActive())
2919 {
2920 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2921 {
2922 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2923 if (transformFeedbackBuffer.get() == buffer)
2924 {
2925 context->handleError(InvalidOperation()
2926 << "Buffer is currently bound for transform feedback.");
2927 return false;
2928 }
2929 }
2930 }
2931
James Darpiniane8a93c62018-01-04 18:02:24 -08002932 if (context->getExtensions().webglCompatibility &&
2933 buffer->isBoundForTransformFeedbackAndOtherUse())
2934 {
2935 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2936 return false;
2937 }
2938
Geoff Lang79f71042017-08-14 16:43:43 -04002939 return true;
2940}
2941
Olli Etuaho4f667482016-03-30 15:56:35 +03002942bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002943 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002944 GLintptr offset,
2945 GLsizeiptr length)
2946{
2947 if (!context->getExtensions().mapBufferRange)
2948 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002949 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002950 return false;
2951 }
2952
2953 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2954}
2955
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002956bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002957{
2958 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002959 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002960 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002961 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002962 return false;
2963 }
2964
Geoff Langf41a7152016-09-19 15:11:17 -04002965 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2966 !context->isTextureGenerated(texture))
2967 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002968 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002969 return false;
2970 }
2971
Ian Ewell54f87462016-03-10 13:47:21 -05002972 switch (target)
2973 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002974 case TextureType::_2D:
2975 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002976 break;
2977
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002978 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002979 if (!context->getExtensions().textureRectangle)
2980 {
2981 context->handleError(InvalidEnum()
2982 << "Context does not support GL_ANGLE_texture_rectangle");
2983 return false;
2984 }
2985 break;
2986
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002987 case TextureType::_3D:
2988 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002989 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002990 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002991 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002992 return false;
2993 }
2994 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002995
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002996 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04002997 if (context->getClientVersion() < Version(3, 1))
2998 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002999 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003000 return false;
3001 }
Geoff Lang3b573612016-10-31 14:08:10 -04003002 break;
3003
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003004 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003005 if (!context->getExtensions().eglImageExternal &&
3006 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003008 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003009 return false;
3010 }
3011 break;
3012 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003013 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003014 return false;
3015 }
3016
3017 return true;
3018}
3019
Geoff Langd8605522016-04-13 10:19:12 -04003020bool ValidateBindUniformLocationCHROMIUM(Context *context,
3021 GLuint program,
3022 GLint location,
3023 const GLchar *name)
3024{
3025 if (!context->getExtensions().bindUniformLocation)
3026 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003027 context->handleError(InvalidOperation()
3028 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003029 return false;
3030 }
3031
3032 Program *programObject = GetValidProgram(context, program);
3033 if (!programObject)
3034 {
3035 return false;
3036 }
3037
3038 if (location < 0)
3039 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003040 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003041 return false;
3042 }
3043
3044 const Caps &caps = context->getCaps();
3045 if (static_cast<size_t>(location) >=
3046 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3047 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003048 context->handleError(InvalidValue() << "Location must be less than "
3049 "(MAX_VERTEX_UNIFORM_VECTORS + "
3050 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003051 return false;
3052 }
3053
Geoff Langfc32e8b2017-05-31 14:16:59 -04003054 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3055 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003056 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003058 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003059 return false;
3060 }
3061
Geoff Langd8605522016-04-13 10:19:12 -04003062 if (strncmp(name, "gl_", 3) == 0)
3063 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003064 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003065 return false;
3066 }
3067
3068 return true;
3069}
3070
Jamie Madille2e406c2016-06-02 13:04:10 -04003071bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003072{
3073 if (!context->getExtensions().framebufferMixedSamples)
3074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003075 context->handleError(InvalidOperation()
3076 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003077 return false;
3078 }
3079 switch (components)
3080 {
3081 case GL_RGB:
3082 case GL_RGBA:
3083 case GL_ALPHA:
3084 case GL_NONE:
3085 break;
3086 default:
3087 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003088 InvalidEnum()
3089 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003090 return false;
3091 }
3092
3093 return true;
3094}
3095
Sami Väisänene45e53b2016-05-25 10:36:04 +03003096// CHROMIUM_path_rendering
3097
Jamie Madill007530e2017-12-28 14:27:04 -05003098bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003099{
Jamie Madill007530e2017-12-28 14:27:04 -05003100 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003101 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003102 return false;
3103 }
Jamie Madill007530e2017-12-28 14:27:04 -05003104
Sami Väisänene45e53b2016-05-25 10:36:04 +03003105 if (matrix == nullptr)
3106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003107 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003108 return false;
3109 }
Jamie Madill007530e2017-12-28 14:27:04 -05003110
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111 return true;
3112}
3113
Jamie Madill007530e2017-12-28 14:27:04 -05003114bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003115{
Jamie Madill007530e2017-12-28 14:27:04 -05003116 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003117}
3118
Jamie Madill007530e2017-12-28 14:27:04 -05003119bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003120{
3121 if (!context->getExtensions().pathRendering)
3122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003123 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003124 return false;
3125 }
3126
3127 // range = 0 is undefined in NV_path_rendering.
3128 // we add stricter semantic check here and require a non zero positive range.
3129 if (range <= 0)
3130 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003131 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003132 return false;
3133 }
3134
3135 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003137 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003138 return false;
3139 }
3140
3141 return true;
3142}
3143
Jamie Madill007530e2017-12-28 14:27:04 -05003144bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003145{
3146 if (!context->getExtensions().pathRendering)
3147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003148 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003149 return false;
3150 }
3151
3152 // range = 0 is undefined in NV_path_rendering.
3153 // we add stricter semantic check here and require a non zero positive range.
3154 if (range <= 0)
3155 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003156 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003157 return false;
3158 }
3159
3160 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3161 checkedRange += range;
3162
3163 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003166 return false;
3167 }
3168 return true;
3169}
3170
Jamie Madill007530e2017-12-28 14:27:04 -05003171bool ValidatePathCommandsCHROMIUM(Context *context,
3172 GLuint path,
3173 GLsizei numCommands,
3174 const GLubyte *commands,
3175 GLsizei numCoords,
3176 GLenum coordType,
3177 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003178{
3179 if (!context->getExtensions().pathRendering)
3180 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003181 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003182 return false;
3183 }
Brandon Jones59770802018-04-02 13:18:42 -07003184 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003185 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003186 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003187 return false;
3188 }
3189
3190 if (numCommands < 0)
3191 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003192 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003193 return false;
3194 }
3195 else if (numCommands > 0)
3196 {
3197 if (!commands)
3198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003199 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003200 return false;
3201 }
3202 }
3203
3204 if (numCoords < 0)
3205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003206 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003207 return false;
3208 }
3209 else if (numCoords > 0)
3210 {
3211 if (!coords)
3212 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003213 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003214 return false;
3215 }
3216 }
3217
3218 std::uint32_t coordTypeSize = 0;
3219 switch (coordType)
3220 {
3221 case GL_BYTE:
3222 coordTypeSize = sizeof(GLbyte);
3223 break;
3224
3225 case GL_UNSIGNED_BYTE:
3226 coordTypeSize = sizeof(GLubyte);
3227 break;
3228
3229 case GL_SHORT:
3230 coordTypeSize = sizeof(GLshort);
3231 break;
3232
3233 case GL_UNSIGNED_SHORT:
3234 coordTypeSize = sizeof(GLushort);
3235 break;
3236
3237 case GL_FLOAT:
3238 coordTypeSize = sizeof(GLfloat);
3239 break;
3240
3241 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003242 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003243 return false;
3244 }
3245
3246 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3247 checkedSize += (coordTypeSize * numCoords);
3248 if (!checkedSize.IsValid())
3249 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003250 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003251 return false;
3252 }
3253
3254 // early return skips command data validation when it doesn't exist.
3255 if (!commands)
3256 return true;
3257
3258 GLsizei expectedNumCoords = 0;
3259 for (GLsizei i = 0; i < numCommands; ++i)
3260 {
3261 switch (commands[i])
3262 {
3263 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3264 break;
3265 case GL_MOVE_TO_CHROMIUM:
3266 case GL_LINE_TO_CHROMIUM:
3267 expectedNumCoords += 2;
3268 break;
3269 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3270 expectedNumCoords += 4;
3271 break;
3272 case GL_CUBIC_CURVE_TO_CHROMIUM:
3273 expectedNumCoords += 6;
3274 break;
3275 case GL_CONIC_CURVE_TO_CHROMIUM:
3276 expectedNumCoords += 5;
3277 break;
3278 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003279 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280 return false;
3281 }
3282 }
3283 if (expectedNumCoords != numCoords)
3284 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003285 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003286 return false;
3287 }
3288
3289 return true;
3290}
3291
Jamie Madill007530e2017-12-28 14:27:04 -05003292bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003293{
3294 if (!context->getExtensions().pathRendering)
3295 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003296 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003297 return false;
3298 }
Brandon Jones59770802018-04-02 13:18:42 -07003299 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003300 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003301 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003302 return false;
3303 }
3304
3305 switch (pname)
3306 {
3307 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3308 if (value < 0.0f)
3309 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003310 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003311 return false;
3312 }
3313 break;
3314 case GL_PATH_END_CAPS_CHROMIUM:
3315 switch (static_cast<GLenum>(value))
3316 {
3317 case GL_FLAT_CHROMIUM:
3318 case GL_SQUARE_CHROMIUM:
3319 case GL_ROUND_CHROMIUM:
3320 break;
3321 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003322 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003323 return false;
3324 }
3325 break;
3326 case GL_PATH_JOIN_STYLE_CHROMIUM:
3327 switch (static_cast<GLenum>(value))
3328 {
3329 case GL_MITER_REVERT_CHROMIUM:
3330 case GL_BEVEL_CHROMIUM:
3331 case GL_ROUND_CHROMIUM:
3332 break;
3333 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003334 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003335 return false;
3336 }
Nico Weber41b072b2018-02-09 10:01:32 -05003337 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003338 case GL_PATH_MITER_LIMIT_CHROMIUM:
3339 if (value < 0.0f)
3340 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003341 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003342 return false;
3343 }
3344 break;
3345
3346 case GL_PATH_STROKE_BOUND_CHROMIUM:
3347 // no errors, only clamping.
3348 break;
3349
3350 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003351 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003352 return false;
3353 }
3354 return true;
3355}
3356
Jamie Madill007530e2017-12-28 14:27:04 -05003357bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3358{
3359 // TODO(jmadill): Use proper clamping cast.
3360 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3361}
3362
3363bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003364{
3365 if (!context->getExtensions().pathRendering)
3366 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003367 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003368 return false;
3369 }
3370
Brandon Jones59770802018-04-02 13:18:42 -07003371 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003372 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003373 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003374 return false;
3375 }
3376 if (!value)
3377 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003378 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003379 return false;
3380 }
3381
3382 switch (pname)
3383 {
3384 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3385 case GL_PATH_END_CAPS_CHROMIUM:
3386 case GL_PATH_JOIN_STYLE_CHROMIUM:
3387 case GL_PATH_MITER_LIMIT_CHROMIUM:
3388 case GL_PATH_STROKE_BOUND_CHROMIUM:
3389 break;
3390
3391 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003392 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003393 return false;
3394 }
3395
3396 return true;
3397}
3398
Jamie Madill007530e2017-12-28 14:27:04 -05003399bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3400{
3401 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3402 reinterpret_cast<GLfloat *>(value));
3403}
3404
3405bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003406{
3407 if (!context->getExtensions().pathRendering)
3408 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003409 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003410 return false;
3411 }
3412
3413 switch (func)
3414 {
3415 case GL_NEVER:
3416 case GL_ALWAYS:
3417 case GL_LESS:
3418 case GL_LEQUAL:
3419 case GL_EQUAL:
3420 case GL_GEQUAL:
3421 case GL_GREATER:
3422 case GL_NOTEQUAL:
3423 break;
3424 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003425 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003426 return false;
3427 }
3428
3429 return true;
3430}
3431
3432// Note that the spec specifies that for the path drawing commands
3433// if the path object is not an existing path object the command
3434// does nothing and no error is generated.
3435// However if the path object exists but has not been specified any
3436// commands then an error is generated.
3437
Jamie Madill007530e2017-12-28 14:27:04 -05003438bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003439{
3440 if (!context->getExtensions().pathRendering)
3441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003442 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003443 return false;
3444 }
Brandon Jones59770802018-04-02 13:18:42 -07003445 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003446 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003447 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003448 return false;
3449 }
3450
3451 switch (fillMode)
3452 {
3453 case GL_COUNT_UP_CHROMIUM:
3454 case GL_COUNT_DOWN_CHROMIUM:
3455 break;
3456 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003457 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458 return false;
3459 }
3460
3461 if (!isPow2(mask + 1))
3462 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003463 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003464 return false;
3465 }
3466
3467 return true;
3468}
3469
Jamie Madill007530e2017-12-28 14:27:04 -05003470bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471{
3472 if (!context->getExtensions().pathRendering)
3473 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003474 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003475 return false;
3476 }
Brandon Jones59770802018-04-02 13:18:42 -07003477 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003478 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003479 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003480 return false;
3481 }
3482
3483 return true;
3484}
3485
Brandon Jonesd1049182018-03-28 10:02:20 -07003486bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3487{
3488 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3489}
3490
3491bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3492{
3493 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3494}
3495
Jamie Madill007530e2017-12-28 14:27:04 -05003496bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003497{
3498 if (!context->getExtensions().pathRendering)
3499 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003500 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003501 return false;
3502 }
Brandon Jones59770802018-04-02 13:18:42 -07003503 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003504 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003506 return false;
3507 }
3508
3509 switch (coverMode)
3510 {
3511 case GL_CONVEX_HULL_CHROMIUM:
3512 case GL_BOUNDING_BOX_CHROMIUM:
3513 break;
3514 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003515 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003516 return false;
3517 }
3518 return true;
3519}
3520
Jamie Madill007530e2017-12-28 14:27:04 -05003521bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3522 GLuint path,
3523 GLenum fillMode,
3524 GLuint mask,
3525 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003526{
Jamie Madill007530e2017-12-28 14:27:04 -05003527 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3528 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003529}
3530
Jamie Madill007530e2017-12-28 14:27:04 -05003531bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3532 GLuint path,
3533 GLint reference,
3534 GLuint mask,
3535 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003536{
Jamie Madill007530e2017-12-28 14:27:04 -05003537 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3538 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003539}
3540
Brandon Jonesd1049182018-03-28 10:02:20 -07003541bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542{
3543 if (!context->getExtensions().pathRendering)
3544 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003545 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546 return false;
3547 }
3548 return true;
3549}
3550
Jamie Madill007530e2017-12-28 14:27:04 -05003551bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3552 GLsizei numPaths,
3553 GLenum pathNameType,
3554 const void *paths,
3555 GLuint pathBase,
3556 GLenum coverMode,
3557 GLenum transformType,
3558 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003559{
3560 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3561 transformType, transformValues))
3562 return false;
3563
3564 switch (coverMode)
3565 {
3566 case GL_CONVEX_HULL_CHROMIUM:
3567 case GL_BOUNDING_BOX_CHROMIUM:
3568 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3569 break;
3570 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003571 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003572 return false;
3573 }
3574
3575 return true;
3576}
3577
Jamie Madill007530e2017-12-28 14:27:04 -05003578bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3579 GLsizei numPaths,
3580 GLenum pathNameType,
3581 const void *paths,
3582 GLuint pathBase,
3583 GLenum coverMode,
3584 GLenum transformType,
3585 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003586{
3587 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3588 transformType, transformValues))
3589 return false;
3590
3591 switch (coverMode)
3592 {
3593 case GL_CONVEX_HULL_CHROMIUM:
3594 case GL_BOUNDING_BOX_CHROMIUM:
3595 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3596 break;
3597 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003598 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003599 return false;
3600 }
3601
3602 return true;
3603}
3604
Jamie Madill007530e2017-12-28 14:27:04 -05003605bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3606 GLsizei numPaths,
3607 GLenum pathNameType,
3608 const void *paths,
3609 GLuint pathBase,
3610 GLenum fillMode,
3611 GLuint mask,
3612 GLenum transformType,
3613 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003614{
3615
3616 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3617 transformType, transformValues))
3618 return false;
3619
3620 switch (fillMode)
3621 {
3622 case GL_COUNT_UP_CHROMIUM:
3623 case GL_COUNT_DOWN_CHROMIUM:
3624 break;
3625 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003626 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003627 return false;
3628 }
3629 if (!isPow2(mask + 1))
3630 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003631 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003632 return false;
3633 }
3634 return true;
3635}
3636
Jamie Madill007530e2017-12-28 14:27:04 -05003637bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3638 GLsizei numPaths,
3639 GLenum pathNameType,
3640 const void *paths,
3641 GLuint pathBase,
3642 GLint reference,
3643 GLuint mask,
3644 GLenum transformType,
3645 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003646{
3647 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3648 transformType, transformValues))
3649 return false;
3650
3651 // no more validation here.
3652
3653 return true;
3654}
3655
Jamie Madill007530e2017-12-28 14:27:04 -05003656bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3657 GLsizei numPaths,
3658 GLenum pathNameType,
3659 const void *paths,
3660 GLuint pathBase,
3661 GLenum fillMode,
3662 GLuint mask,
3663 GLenum coverMode,
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 switch (coverMode)
3672 {
3673 case GL_CONVEX_HULL_CHROMIUM:
3674 case GL_BOUNDING_BOX_CHROMIUM:
3675 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3676 break;
3677 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003678 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003679 return false;
3680 }
3681
3682 switch (fillMode)
3683 {
3684 case GL_COUNT_UP_CHROMIUM:
3685 case GL_COUNT_DOWN_CHROMIUM:
3686 break;
3687 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003688 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003689 return false;
3690 }
3691 if (!isPow2(mask + 1))
3692 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003693 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003694 return false;
3695 }
3696
3697 return true;
3698}
3699
Jamie Madill007530e2017-12-28 14:27:04 -05003700bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3701 GLsizei numPaths,
3702 GLenum pathNameType,
3703 const void *paths,
3704 GLuint pathBase,
3705 GLint reference,
3706 GLuint mask,
3707 GLenum coverMode,
3708 GLenum transformType,
3709 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003710{
3711 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3712 transformType, transformValues))
3713 return false;
3714
3715 switch (coverMode)
3716 {
3717 case GL_CONVEX_HULL_CHROMIUM:
3718 case GL_BOUNDING_BOX_CHROMIUM:
3719 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3720 break;
3721 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003722 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003723 return false;
3724 }
3725
3726 return true;
3727}
3728
Jamie Madill007530e2017-12-28 14:27:04 -05003729bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3730 GLuint program,
3731 GLint location,
3732 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003733{
3734 if (!context->getExtensions().pathRendering)
3735 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003736 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003737 return false;
3738 }
3739
3740 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3741 if (location >= MaxLocation)
3742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003743 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003744 return false;
3745 }
3746
3747 const auto *programObject = context->getProgram(program);
3748 if (!programObject)
3749 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003750 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003751 return false;
3752 }
3753
3754 if (!name)
3755 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003756 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003757 return false;
3758 }
3759
3760 if (angle::BeginsWith(name, "gl_"))
3761 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003762 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003763 return false;
3764 }
3765
3766 return true;
3767}
3768
Jamie Madill007530e2017-12-28 14:27:04 -05003769bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3770 GLuint program,
3771 GLint location,
3772 GLenum genMode,
3773 GLint components,
3774 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003775{
3776 if (!context->getExtensions().pathRendering)
3777 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003778 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003779 return false;
3780 }
3781
3782 const auto *programObject = context->getProgram(program);
3783 if (!programObject || programObject->isFlaggedForDeletion())
3784 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003785 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003786 return false;
3787 }
3788
3789 if (!programObject->isLinked())
3790 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003791 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003792 return false;
3793 }
3794
3795 switch (genMode)
3796 {
3797 case GL_NONE:
3798 if (components != 0)
3799 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003800 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003801 return false;
3802 }
3803 break;
3804
3805 case GL_OBJECT_LINEAR_CHROMIUM:
3806 case GL_EYE_LINEAR_CHROMIUM:
3807 case GL_CONSTANT_CHROMIUM:
3808 if (components < 1 || components > 4)
3809 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003810 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003811 return false;
3812 }
3813 if (!coeffs)
3814 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003815 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003816 return false;
3817 }
3818 break;
3819
3820 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003821 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003822 return false;
3823 }
3824
3825 // If the location is -1 then the command is silently ignored
3826 // and no further validation is needed.
3827 if (location == -1)
3828 return true;
3829
Jamie Madillbd044ed2017-06-05 12:59:21 -04003830 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003831
3832 if (!binding.valid)
3833 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003834 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003835 return false;
3836 }
3837
3838 if (binding.type != GL_NONE)
3839 {
3840 GLint expectedComponents = 0;
3841 switch (binding.type)
3842 {
3843 case GL_FLOAT:
3844 expectedComponents = 1;
3845 break;
3846 case GL_FLOAT_VEC2:
3847 expectedComponents = 2;
3848 break;
3849 case GL_FLOAT_VEC3:
3850 expectedComponents = 3;
3851 break;
3852 case GL_FLOAT_VEC4:
3853 expectedComponents = 4;
3854 break;
3855 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003856 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003857 InvalidOperation()
3858 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003859 return false;
3860 }
3861 if (expectedComponents != components && genMode != GL_NONE)
3862 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003863 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003864 return false;
3865 }
3866 }
3867 return true;
3868}
3869
Geoff Lang97073d12016-04-20 10:42:34 -07003870bool ValidateCopyTextureCHROMIUM(Context *context,
3871 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003872 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003873 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003874 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003875 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003876 GLint internalFormat,
3877 GLenum destType,
3878 GLboolean unpackFlipY,
3879 GLboolean unpackPremultiplyAlpha,
3880 GLboolean unpackUnmultiplyAlpha)
3881{
3882 if (!context->getExtensions().copyTexture)
3883 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003884 context->handleError(InvalidOperation()
3885 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003886 return false;
3887 }
3888
Geoff Lang4f0e0032017-05-01 16:04:35 -04003889 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003890 if (source == nullptr)
3891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003892 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003893 return false;
3894 }
3895
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003896 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003898 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003899 return false;
3900 }
3901
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003902 TextureType sourceType = source->getType();
3903 ASSERT(sourceType != TextureType::CubeMap);
3904 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003905
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003906 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003907 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003908 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003909 return false;
3910 }
3911
Geoff Lang4f0e0032017-05-01 16:04:35 -04003912 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3913 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3914 if (sourceWidth == 0 || sourceHeight == 0)
3915 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003916 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003917 return false;
3918 }
3919
3920 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3921 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003922 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003923 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003924 return false;
3925 }
3926
Geoff Lang63458a32017-10-30 15:16:53 -04003927 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3928 {
3929 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3930 return false;
3931 }
3932
Geoff Lang4f0e0032017-05-01 16:04:35 -04003933 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003934 if (dest == nullptr)
3935 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003936 context->handleError(InvalidValue()
3937 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003938 return false;
3939 }
3940
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003941 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003942 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003943 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003944 return false;
3945 }
3946
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003947 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003948 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003949 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003950 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003951 return false;
3952 }
3953
Geoff Lang97073d12016-04-20 10:42:34 -07003954 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3955 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003956 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003957 return false;
3958 }
3959
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003960 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003961 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003962 context->handleError(
3963 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003964 return false;
3965 }
3966
Geoff Lang97073d12016-04-20 10:42:34 -07003967 if (dest->getImmutableFormat())
3968 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003969 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003970 return false;
3971 }
3972
3973 return true;
3974}
3975
3976bool ValidateCopySubTextureCHROMIUM(Context *context,
3977 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003978 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003979 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003980 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003981 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003982 GLint xoffset,
3983 GLint yoffset,
3984 GLint x,
3985 GLint y,
3986 GLsizei width,
3987 GLsizei height,
3988 GLboolean unpackFlipY,
3989 GLboolean unpackPremultiplyAlpha,
3990 GLboolean unpackUnmultiplyAlpha)
3991{
3992 if (!context->getExtensions().copyTexture)
3993 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003994 context->handleError(InvalidOperation()
3995 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003996 return false;
3997 }
3998
Geoff Lang4f0e0032017-05-01 16:04:35 -04003999 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004000 if (source == nullptr)
4001 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004002 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004003 return false;
4004 }
4005
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004006 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004008 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004009 return false;
4010 }
4011
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004012 TextureType sourceType = source->getType();
4013 ASSERT(sourceType != TextureType::CubeMap);
4014 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004015
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004016 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004017 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004018 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004019 return false;
4020 }
4021
4022 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4023 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004024 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004025 context->handleError(InvalidValue()
4026 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004027 return false;
4028 }
4029
4030 if (x < 0 || y < 0)
4031 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004032 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004033 return false;
4034 }
4035
4036 if (width < 0 || height < 0)
4037 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004038 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004039 return false;
4040 }
4041
Geoff Lang4f0e0032017-05-01 16:04:35 -04004042 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4043 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004044 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004045 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004046 return false;
4047 }
4048
Geoff Lang4f0e0032017-05-01 16:04:35 -04004049 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4050 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004051 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004052 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004053 return false;
4054 }
4055
Geoff Lang63458a32017-10-30 15:16:53 -04004056 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4057 {
4058 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4059 return false;
4060 }
4061
Geoff Lang4f0e0032017-05-01 16:04:35 -04004062 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004063 if (dest == nullptr)
4064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004065 context->handleError(InvalidValue()
4066 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004067 return false;
4068 }
4069
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004070 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004072 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004073 return false;
4074 }
4075
Brandon Jones28783792018-03-05 09:37:32 -08004076 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4077 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004078 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004079 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004080 return false;
4081 }
4082
Geoff Lang4f0e0032017-05-01 16:04:35 -04004083 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4084 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004085 context
4086 ->handleError(InvalidOperation()
4087 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004088 return false;
4089 }
4090
4091 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4092 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004093 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004094 context->handleError(InvalidOperation()
4095 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004096 return false;
4097 }
4098
4099 if (xoffset < 0 || yoffset < 0)
4100 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004101 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004102 return false;
4103 }
4104
Geoff Lang4f0e0032017-05-01 16:04:35 -04004105 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4106 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004107 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004108 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004109 return false;
4110 }
4111
4112 return true;
4113}
4114
Geoff Lang47110bf2016-04-20 11:13:22 -07004115bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4116{
4117 if (!context->getExtensions().copyCompressedTexture)
4118 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004119 context->handleError(InvalidOperation()
4120 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004121 return false;
4122 }
4123
4124 const gl::Texture *source = context->getTexture(sourceId);
4125 if (source == nullptr)
4126 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004127 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004128 return false;
4129 }
4130
Corentin Wallez99d492c2018-02-27 15:17:10 -05004131 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004133 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004134 return false;
4135 }
4136
Corentin Wallez99d492c2018-02-27 15:17:10 -05004137 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4138 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004140 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004141 return false;
4142 }
4143
Corentin Wallez99d492c2018-02-27 15:17:10 -05004144 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004145 if (!sourceFormat.info->compressed)
4146 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004147 context->handleError(InvalidOperation()
4148 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004149 return false;
4150 }
4151
4152 const gl::Texture *dest = context->getTexture(destId);
4153 if (dest == nullptr)
4154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004155 context->handleError(InvalidValue()
4156 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004157 return false;
4158 }
4159
Corentin Wallez99d492c2018-02-27 15:17:10 -05004160 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004161 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004162 context->handleError(InvalidValue()
4163 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004164 return false;
4165 }
4166
4167 if (dest->getImmutableFormat())
4168 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004169 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004170 return false;
4171 }
4172
4173 return true;
4174}
4175
Jiawei Shao385b3e02018-03-21 09:43:28 +08004176bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004177{
4178 switch (type)
4179 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004180 case ShaderType::Vertex:
4181 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004182 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004183
Jiawei Shao385b3e02018-03-21 09:43:28 +08004184 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004185 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004186 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004187 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004188 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004189 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004190 break;
4191
Jiawei Shao385b3e02018-03-21 09:43:28 +08004192 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004193 if (!context->getExtensions().geometryShader)
4194 {
4195 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4196 return false;
4197 }
4198 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004199 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004201 return false;
4202 }
Jamie Madill29639852016-09-02 15:00:09 -04004203
4204 return true;
4205}
4206
Jamie Madill5b772312018-03-08 20:28:32 -05004207bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004208 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004209 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004210 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004211 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004212{
4213 if (size < 0)
4214 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004215 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004216 return false;
4217 }
4218
4219 switch (usage)
4220 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004221 case BufferUsage::StreamDraw:
4222 case BufferUsage::StaticDraw:
4223 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004224 break;
4225
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004226 case BufferUsage::StreamRead:
4227 case BufferUsage::StaticRead:
4228 case BufferUsage::DynamicRead:
4229 case BufferUsage::StreamCopy:
4230 case BufferUsage::StaticCopy:
4231 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004232 if (context->getClientMajorVersion() < 3)
4233 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004234 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004235 return false;
4236 }
4237 break;
4238
4239 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004240 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004241 return false;
4242 }
4243
Corentin Walleze4477002017-12-01 14:39:58 -05004244 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004246 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004247 return false;
4248 }
4249
4250 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4251
4252 if (!buffer)
4253 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004254 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004255 return false;
4256 }
4257
James Darpiniane8a93c62018-01-04 18:02:24 -08004258 if (context->getExtensions().webglCompatibility &&
4259 buffer->isBoundForTransformFeedbackAndOtherUse())
4260 {
4261 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4262 return false;
4263 }
4264
Jamie Madill29639852016-09-02 15:00:09 -04004265 return true;
4266}
4267
Jamie Madill5b772312018-03-08 20:28:32 -05004268bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004269 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004270 GLintptr offset,
4271 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004272 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004273{
Brandon Jones6cad5662017-06-14 13:25:13 -07004274 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004275 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004276 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4277 return false;
4278 }
4279
4280 if (offset < 0)
4281 {
4282 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004283 return false;
4284 }
4285
Corentin Walleze4477002017-12-01 14:39:58 -05004286 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004287 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004288 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004289 return false;
4290 }
4291
4292 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4293
4294 if (!buffer)
4295 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004296 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004297 return false;
4298 }
4299
4300 if (buffer->isMapped())
4301 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004302 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004303 return false;
4304 }
4305
James Darpiniane8a93c62018-01-04 18:02:24 -08004306 if (context->getExtensions().webglCompatibility &&
4307 buffer->isBoundForTransformFeedbackAndOtherUse())
4308 {
4309 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4310 return false;
4311 }
4312
Jamie Madill29639852016-09-02 15:00:09 -04004313 // Check for possible overflow of size + offset
4314 angle::CheckedNumeric<size_t> checkedSize(size);
4315 checkedSize += offset;
4316 if (!checkedSize.IsValid())
4317 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004318 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004319 return false;
4320 }
4321
4322 if (size + offset > buffer->getSize())
4323 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004324 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004325 return false;
4326 }
4327
Martin Radev4c4c8e72016-08-04 12:25:34 +03004328 return true;
4329}
4330
Geoff Lang111a99e2017-10-17 10:58:41 -04004331bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004332{
Geoff Langc339c4e2016-11-29 10:37:36 -05004333 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004334 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004335 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004336 return false;
4337 }
4338
Geoff Lang111a99e2017-10-17 10:58:41 -04004339 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004340 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004341 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004342 return false;
4343 }
4344
4345 return true;
4346}
4347
Jamie Madill5b772312018-03-08 20:28:32 -05004348bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004349{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004350 if (context->getClientMajorVersion() < 2)
4351 {
4352 return ValidateMultitextureUnit(context, texture);
4353 }
4354
Jamie Madillef300b12016-10-07 15:12:09 -04004355 if (texture < GL_TEXTURE0 ||
4356 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4357 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004358 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004359 return false;
4360 }
4361
4362 return true;
4363}
4364
Jamie Madill5b772312018-03-08 20:28:32 -05004365bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004366{
4367 Program *programObject = GetValidProgram(context, program);
4368 if (!programObject)
4369 {
4370 return false;
4371 }
4372
4373 Shader *shaderObject = GetValidShader(context, shader);
4374 if (!shaderObject)
4375 {
4376 return false;
4377 }
4378
Jiawei Shao385b3e02018-03-21 09:43:28 +08004379 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004380 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4382 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004383 }
4384
4385 return true;
4386}
4387
Jamie Madill5b772312018-03-08 20:28:32 -05004388bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004389{
4390 if (index >= MAX_VERTEX_ATTRIBS)
4391 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004392 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004393 return false;
4394 }
4395
4396 if (strncmp(name, "gl_", 3) == 0)
4397 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004398 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004399 return false;
4400 }
4401
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004402 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004403 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004404 const size_t length = strlen(name);
4405
4406 if (!IsValidESSLString(name, length))
4407 {
4408 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4409 // for shader-related entry points
4410 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4411 return false;
4412 }
4413
4414 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4415 {
4416 return false;
4417 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004418 }
4419
Jamie Madill01a80ee2016-11-07 12:06:18 -05004420 return GetValidProgram(context, program) != nullptr;
4421}
4422
Jamie Madill5b772312018-03-08 20:28:32 -05004423bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004424{
Corentin Walleze4477002017-12-01 14:39:58 -05004425 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004426 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004427 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004428 return false;
4429 }
4430
4431 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4432 !context->isBufferGenerated(buffer))
4433 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004434 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004435 return false;
4436 }
4437
4438 return true;
4439}
4440
Jamie Madill5b772312018-03-08 20:28:32 -05004441bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004442{
Geoff Lange8afa902017-09-27 15:00:43 -04004443 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004445 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004446 return false;
4447 }
4448
4449 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4450 !context->isFramebufferGenerated(framebuffer))
4451 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004452 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004453 return false;
4454 }
4455
4456 return true;
4457}
4458
Jamie Madill5b772312018-03-08 20:28:32 -05004459bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004460{
4461 if (target != GL_RENDERBUFFER)
4462 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004463 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004464 return false;
4465 }
4466
4467 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4468 !context->isRenderbufferGenerated(renderbuffer))
4469 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004470 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004471 return false;
4472 }
4473
4474 return true;
4475}
4476
Jamie Madill5b772312018-03-08 20:28:32 -05004477static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004478{
4479 switch (mode)
4480 {
4481 case GL_FUNC_ADD:
4482 case GL_FUNC_SUBTRACT:
4483 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004484 return true;
4485
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004486 case GL_MIN:
4487 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004488 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004489
4490 default:
4491 return false;
4492 }
4493}
4494
Jamie Madill5b772312018-03-08 20:28:32 -05004495bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004496{
4497 return true;
4498}
4499
Jamie Madill5b772312018-03-08 20:28:32 -05004500bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004501{
Geoff Lang50cac572017-09-26 17:37:43 -04004502 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004503 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004504 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004505 return false;
4506 }
4507
4508 return true;
4509}
4510
Jamie Madill5b772312018-03-08 20:28:32 -05004511bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004512{
Geoff Lang50cac572017-09-26 17:37:43 -04004513 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004514 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004515 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004516 return false;
4517 }
4518
Geoff Lang50cac572017-09-26 17:37:43 -04004519 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004520 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004521 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004522 return false;
4523 }
4524
4525 return true;
4526}
4527
Jamie Madill5b772312018-03-08 20:28:32 -05004528bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004529{
4530 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4531}
4532
4533static bool ValidSrcBlendFunc(GLenum srcBlend)
4534{
4535 switch (srcBlend)
4536 {
4537 case GL_ZERO:
4538 case GL_ONE:
4539 case GL_SRC_COLOR:
4540 case GL_ONE_MINUS_SRC_COLOR:
4541 case GL_DST_COLOR:
4542 case GL_ONE_MINUS_DST_COLOR:
4543 case GL_SRC_ALPHA:
4544 case GL_ONE_MINUS_SRC_ALPHA:
4545 case GL_DST_ALPHA:
4546 case GL_ONE_MINUS_DST_ALPHA:
4547 case GL_CONSTANT_COLOR:
4548 case GL_ONE_MINUS_CONSTANT_COLOR:
4549 case GL_CONSTANT_ALPHA:
4550 case GL_ONE_MINUS_CONSTANT_ALPHA:
4551 case GL_SRC_ALPHA_SATURATE:
4552 return true;
4553
4554 default:
4555 return false;
4556 }
4557}
4558
4559static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4560{
4561 switch (dstBlend)
4562 {
4563 case GL_ZERO:
4564 case GL_ONE:
4565 case GL_SRC_COLOR:
4566 case GL_ONE_MINUS_SRC_COLOR:
4567 case GL_DST_COLOR:
4568 case GL_ONE_MINUS_DST_COLOR:
4569 case GL_SRC_ALPHA:
4570 case GL_ONE_MINUS_SRC_ALPHA:
4571 case GL_DST_ALPHA:
4572 case GL_ONE_MINUS_DST_ALPHA:
4573 case GL_CONSTANT_COLOR:
4574 case GL_ONE_MINUS_CONSTANT_COLOR:
4575 case GL_CONSTANT_ALPHA:
4576 case GL_ONE_MINUS_CONSTANT_ALPHA:
4577 return true;
4578
4579 case GL_SRC_ALPHA_SATURATE:
4580 return (contextMajorVersion >= 3);
4581
4582 default:
4583 return false;
4584 }
4585}
4586
Jamie Madill5b772312018-03-08 20:28:32 -05004587bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004588 GLenum srcRGB,
4589 GLenum dstRGB,
4590 GLenum srcAlpha,
4591 GLenum dstAlpha)
4592{
4593 if (!ValidSrcBlendFunc(srcRGB))
4594 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004595 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004596 return false;
4597 }
4598
4599 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4600 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004602 return false;
4603 }
4604
4605 if (!ValidSrcBlendFunc(srcAlpha))
4606 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004607 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004608 return false;
4609 }
4610
4611 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4612 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004613 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004614 return false;
4615 }
4616
Frank Henigman146e8a12017-03-02 23:22:37 -05004617 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4618 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004619 {
4620 bool constantColorUsed =
4621 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4622 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4623
4624 bool constantAlphaUsed =
4625 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4626 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4627
4628 if (constantColorUsed && constantAlphaUsed)
4629 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004630 const char *msg;
4631 if (context->getExtensions().webglCompatibility)
4632 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004633 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004634 }
4635 else
4636 {
4637 msg =
4638 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4639 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4640 "implementation.";
4641 ERR() << msg;
4642 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004643 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004644 return false;
4645 }
4646 }
4647
4648 return true;
4649}
4650
Geoff Langc339c4e2016-11-29 10:37:36 -05004651bool ValidateGetString(Context *context, GLenum name)
4652{
4653 switch (name)
4654 {
4655 case GL_VENDOR:
4656 case GL_RENDERER:
4657 case GL_VERSION:
4658 case GL_SHADING_LANGUAGE_VERSION:
4659 case GL_EXTENSIONS:
4660 break;
4661
4662 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4663 if (!context->getExtensions().requestExtension)
4664 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004665 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004666 return false;
4667 }
4668 break;
4669
4670 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004671 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004672 return false;
4673 }
4674
4675 return true;
4676}
4677
Jamie Madill5b772312018-03-08 20:28:32 -05004678bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004679{
4680 if (width <= 0.0f || isNaN(width))
4681 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004682 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004683 return false;
4684 }
4685
4686 return true;
4687}
4688
Jamie Madill5b772312018-03-08 20:28:32 -05004689bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004690 GLuint index,
4691 GLint size,
4692 GLenum type,
4693 GLboolean normalized,
4694 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004695 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004696{
Shao80957d92017-02-20 21:25:59 +08004697 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004698 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004699 return false;
4700 }
4701
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004702 if (stride < 0)
4703 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004704 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004705 return false;
4706 }
4707
Shao80957d92017-02-20 21:25:59 +08004708 const Caps &caps = context->getCaps();
4709 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004710 {
Shao80957d92017-02-20 21:25:59 +08004711 if (stride > caps.maxVertexAttribStride)
4712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004713 context->handleError(InvalidValue()
4714 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004715 return false;
4716 }
4717
4718 if (index >= caps.maxVertexAttribBindings)
4719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004720 context->handleError(InvalidValue()
4721 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004722 return false;
4723 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004724 }
4725
4726 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4727 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4728 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4729 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004730 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4731 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004732 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4733 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004734 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004735 context
4736 ->handleError(InvalidOperation()
4737 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004738 return false;
4739 }
4740
4741 if (context->getExtensions().webglCompatibility)
4742 {
4743 // WebGL 1.0 [Section 6.14] Fixed point support
4744 // The WebGL API does not support the GL_FIXED data type.
4745 if (type == GL_FIXED)
4746 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004747 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004748 return false;
4749 }
4750
Geoff Lang2d62ab72017-03-23 16:54:40 -04004751 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004752 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004753 return false;
4754 }
4755 }
4756
4757 return true;
4758}
4759
Jamie Madill5b772312018-03-08 20:28:32 -05004760bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004761{
4762 if (context->getExtensions().webglCompatibility && zNear > zFar)
4763 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004764 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004765 return false;
4766 }
4767
4768 return true;
4769}
4770
Jamie Madill5b772312018-03-08 20:28:32 -05004771bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004772 GLenum target,
4773 GLenum internalformat,
4774 GLsizei width,
4775 GLsizei height)
4776{
4777 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4778 height);
4779}
4780
Jamie Madill5b772312018-03-08 20:28:32 -05004781bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004782 GLenum target,
4783 GLsizei samples,
4784 GLenum internalformat,
4785 GLsizei width,
4786 GLsizei height)
4787{
4788 if (!context->getExtensions().framebufferMultisample)
4789 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004790 context->handleError(InvalidOperation()
4791 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004792 return false;
4793 }
4794
4795 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4796 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4797 // generated.
4798 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4799 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004800 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004801 return false;
4802 }
4803
4804 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4805 // the specified storage. This is different than ES 3.0 in which a sample number higher
4806 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4807 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4808 if (context->getClientMajorVersion() >= 3)
4809 {
4810 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4811 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4812 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004813 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004814 return false;
4815 }
4816 }
4817
4818 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4819 width, height);
4820}
4821
Jamie Madill5b772312018-03-08 20:28:32 -05004822bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004823{
Geoff Lange8afa902017-09-27 15:00:43 -04004824 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004825 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004826 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004827 return false;
4828 }
4829
4830 return true;
4831}
4832
Jamie Madill5b772312018-03-08 20:28:32 -05004833bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004834{
4835 return true;
4836}
4837
Jamie Madill5b772312018-03-08 20:28:32 -05004838bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004839{
4840 return true;
4841}
4842
Jamie Madill5b772312018-03-08 20:28:32 -05004843bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004844{
4845 return true;
4846}
4847
Jamie Madill5b772312018-03-08 20:28:32 -05004848bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004849 GLboolean red,
4850 GLboolean green,
4851 GLboolean blue,
4852 GLboolean alpha)
4853{
4854 return true;
4855}
4856
Jamie Madill5b772312018-03-08 20:28:32 -05004857bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004858{
4859 return true;
4860}
4861
Jamie Madill5b772312018-03-08 20:28:32 -05004862bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004863{
4864 return true;
4865}
4866
Jamie Madill5b772312018-03-08 20:28:32 -05004867bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004868{
4869 switch (mode)
4870 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004871 case CullFaceMode::Front:
4872 case CullFaceMode::Back:
4873 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004874 break;
4875
4876 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004877 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004878 return false;
4879 }
4880
4881 return true;
4882}
4883
Jamie Madill5b772312018-03-08 20:28:32 -05004884bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004885{
4886 if (program == 0)
4887 {
4888 return false;
4889 }
4890
4891 if (!context->getProgram(program))
4892 {
4893 if (context->getShader(program))
4894 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004895 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004896 return false;
4897 }
4898 else
4899 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004900 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004901 return false;
4902 }
4903 }
4904
4905 return true;
4906}
4907
Jamie Madill5b772312018-03-08 20:28:32 -05004908bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004909{
4910 if (shader == 0)
4911 {
4912 return false;
4913 }
4914
4915 if (!context->getShader(shader))
4916 {
4917 if (context->getProgram(shader))
4918 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004919 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004920 return false;
4921 }
4922 else
4923 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004924 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004925 return false;
4926 }
4927 }
4928
4929 return true;
4930}
4931
Jamie Madill5b772312018-03-08 20:28:32 -05004932bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004933{
4934 switch (func)
4935 {
4936 case GL_NEVER:
4937 case GL_ALWAYS:
4938 case GL_LESS:
4939 case GL_LEQUAL:
4940 case GL_EQUAL:
4941 case GL_GREATER:
4942 case GL_GEQUAL:
4943 case GL_NOTEQUAL:
4944 break;
4945
4946 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004947 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004948 return false;
4949 }
4950
4951 return true;
4952}
4953
Jamie Madill5b772312018-03-08 20:28:32 -05004954bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004955{
4956 return true;
4957}
4958
Jamie Madill5b772312018-03-08 20:28:32 -05004959bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004960{
4961 Program *programObject = GetValidProgram(context, program);
4962 if (!programObject)
4963 {
4964 return false;
4965 }
4966
4967 Shader *shaderObject = GetValidShader(context, shader);
4968 if (!shaderObject)
4969 {
4970 return false;
4971 }
4972
Jiawei Shao385b3e02018-03-21 09:43:28 +08004973 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004974 if (attachedShader != shaderObject)
4975 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004976 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004977 return false;
4978 }
4979
4980 return true;
4981}
4982
Jamie Madill5b772312018-03-08 20:28:32 -05004983bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004984{
4985 if (index >= MAX_VERTEX_ATTRIBS)
4986 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004987 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004988 return false;
4989 }
4990
4991 return true;
4992}
4993
Jamie Madill5b772312018-03-08 20:28:32 -05004994bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004995{
4996 if (index >= MAX_VERTEX_ATTRIBS)
4997 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004998 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004999 return false;
5000 }
5001
5002 return true;
5003}
5004
Jamie Madill5b772312018-03-08 20:28:32 -05005005bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005006{
5007 return true;
5008}
5009
Jamie Madill5b772312018-03-08 20:28:32 -05005010bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005011{
5012 return true;
5013}
5014
Jamie Madill5b772312018-03-08 20:28:32 -05005015bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005016{
5017 switch (mode)
5018 {
5019 case GL_CW:
5020 case GL_CCW:
5021 break;
5022 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005023 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005024 return false;
5025 }
5026
5027 return true;
5028}
5029
Jamie Madill5b772312018-03-08 20:28:32 -05005030bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005031 GLuint program,
5032 GLuint index,
5033 GLsizei bufsize,
5034 GLsizei *length,
5035 GLint *size,
5036 GLenum *type,
5037 GLchar *name)
5038{
5039 if (bufsize < 0)
5040 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005041 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005042 return false;
5043 }
5044
5045 Program *programObject = GetValidProgram(context, program);
5046
5047 if (!programObject)
5048 {
5049 return false;
5050 }
5051
5052 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5053 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005054 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005055 return false;
5056 }
5057
5058 return true;
5059}
5060
Jamie Madill5b772312018-03-08 20:28:32 -05005061bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005062 GLuint program,
5063 GLuint index,
5064 GLsizei bufsize,
5065 GLsizei *length,
5066 GLint *size,
5067 GLenum *type,
5068 GLchar *name)
5069{
5070 if (bufsize < 0)
5071 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005072 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005073 return false;
5074 }
5075
5076 Program *programObject = GetValidProgram(context, program);
5077
5078 if (!programObject)
5079 {
5080 return false;
5081 }
5082
5083 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5084 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005085 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005086 return false;
5087 }
5088
5089 return true;
5090}
5091
Jamie Madill5b772312018-03-08 20:28:32 -05005092bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005093 GLuint program,
5094 GLsizei maxcount,
5095 GLsizei *count,
5096 GLuint *shaders)
5097{
5098 if (maxcount < 0)
5099 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005100 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005101 return false;
5102 }
5103
5104 Program *programObject = GetValidProgram(context, program);
5105
5106 if (!programObject)
5107 {
5108 return false;
5109 }
5110
5111 return true;
5112}
5113
Jamie Madill5b772312018-03-08 20:28:32 -05005114bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005115{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005116 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5117 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005118 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005119 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005120 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005121 return false;
5122 }
5123
Jamie Madillc1d770e2017-04-13 17:31:24 -04005124 Program *programObject = GetValidProgram(context, program);
5125
5126 if (!programObject)
5127 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005128 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005129 return false;
5130 }
5131
5132 if (!programObject->isLinked())
5133 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005134 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005135 return false;
5136 }
5137
5138 return true;
5139}
5140
Jamie Madill5b772312018-03-08 20:28:32 -05005141bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005142{
5143 GLenum nativeType;
5144 unsigned int numParams = 0;
5145 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5146}
5147
Jamie Madill5b772312018-03-08 20:28:32 -05005148bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149{
5150 return true;
5151}
5152
Jamie Madill5b772312018-03-08 20:28:32 -05005153bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005154{
5155 GLenum nativeType;
5156 unsigned int numParams = 0;
5157 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5158}
5159
Jamie Madill5b772312018-03-08 20:28:32 -05005160bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161{
5162 GLenum nativeType;
5163 unsigned int numParams = 0;
5164 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5165}
5166
Jamie Madill5b772312018-03-08 20:28:32 -05005167bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005168 GLuint program,
5169 GLsizei bufsize,
5170 GLsizei *length,
5171 GLchar *infolog)
5172{
5173 if (bufsize < 0)
5174 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005175 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005176 return false;
5177 }
5178
5179 Program *programObject = GetValidProgram(context, program);
5180 if (!programObject)
5181 {
5182 return false;
5183 }
5184
5185 return true;
5186}
5187
Jamie Madill5b772312018-03-08 20:28:32 -05005188bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005189 GLuint shader,
5190 GLsizei bufsize,
5191 GLsizei *length,
5192 GLchar *infolog)
5193{
5194 if (bufsize < 0)
5195 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005196 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005197 return false;
5198 }
5199
5200 Shader *shaderObject = GetValidShader(context, shader);
5201 if (!shaderObject)
5202 {
5203 return false;
5204 }
5205
5206 return true;
5207}
5208
Jamie Madill5b772312018-03-08 20:28:32 -05005209bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005210 GLenum shadertype,
5211 GLenum precisiontype,
5212 GLint *range,
5213 GLint *precision)
5214{
5215 switch (shadertype)
5216 {
5217 case GL_VERTEX_SHADER:
5218 case GL_FRAGMENT_SHADER:
5219 break;
5220 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005221 context->handleError(InvalidOperation()
5222 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005223 return false;
5224 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005225 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005226 return false;
5227 }
5228
5229 switch (precisiontype)
5230 {
5231 case GL_LOW_FLOAT:
5232 case GL_MEDIUM_FLOAT:
5233 case GL_HIGH_FLOAT:
5234 case GL_LOW_INT:
5235 case GL_MEDIUM_INT:
5236 case GL_HIGH_INT:
5237 break;
5238
5239 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005240 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005241 return false;
5242 }
5243
5244 return true;
5245}
5246
Jamie Madill5b772312018-03-08 20:28:32 -05005247bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005248 GLuint shader,
5249 GLsizei bufsize,
5250 GLsizei *length,
5251 GLchar *source)
5252{
5253 if (bufsize < 0)
5254 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005255 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005256 return false;
5257 }
5258
5259 Shader *shaderObject = GetValidShader(context, shader);
5260 if (!shaderObject)
5261 {
5262 return false;
5263 }
5264
5265 return true;
5266}
5267
Jamie Madill5b772312018-03-08 20:28:32 -05005268bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005269{
5270 if (strstr(name, "gl_") == name)
5271 {
5272 return false;
5273 }
5274
Geoff Langfc32e8b2017-05-31 14:16:59 -04005275 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5276 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005277 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005278 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005279 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005280 return false;
5281 }
5282
Jamie Madillc1d770e2017-04-13 17:31:24 -04005283 Program *programObject = GetValidProgram(context, program);
5284
5285 if (!programObject)
5286 {
5287 return false;
5288 }
5289
5290 if (!programObject->isLinked())
5291 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005292 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293 return false;
5294 }
5295
5296 return true;
5297}
5298
Jamie Madill5b772312018-03-08 20:28:32 -05005299bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005300{
5301 switch (mode)
5302 {
5303 case GL_FASTEST:
5304 case GL_NICEST:
5305 case GL_DONT_CARE:
5306 break;
5307
5308 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005309 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005310 return false;
5311 }
5312
5313 switch (target)
5314 {
5315 case GL_GENERATE_MIPMAP_HINT:
5316 break;
5317
Geoff Lange7bd2182017-06-16 16:13:13 -04005318 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5319 if (context->getClientVersion() < ES_3_0 &&
5320 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005321 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005322 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005323 return false;
5324 }
5325 break;
5326
5327 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005328 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005329 return false;
5330 }
5331
5332 return true;
5333}
5334
Jamie Madill5b772312018-03-08 20:28:32 -05005335bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005336{
5337 return true;
5338}
5339
Jamie Madill5b772312018-03-08 20:28:32 -05005340bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005341{
5342 return true;
5343}
5344
Jamie Madill5b772312018-03-08 20:28:32 -05005345bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005346{
5347 return true;
5348}
5349
Jamie Madill5b772312018-03-08 20:28:32 -05005350bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005351{
5352 return true;
5353}
5354
Jamie Madill5b772312018-03-08 20:28:32 -05005355bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005356{
5357 return true;
5358}
5359
Jamie Madill5b772312018-03-08 20:28:32 -05005360bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005361{
5362 return true;
5363}
5364
Jamie Madill5b772312018-03-08 20:28:32 -05005365bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005366{
5367 if (context->getClientMajorVersion() < 3)
5368 {
5369 switch (pname)
5370 {
5371 case GL_UNPACK_IMAGE_HEIGHT:
5372 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005373 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005374 return false;
5375
5376 case GL_UNPACK_ROW_LENGTH:
5377 case GL_UNPACK_SKIP_ROWS:
5378 case GL_UNPACK_SKIP_PIXELS:
5379 if (!context->getExtensions().unpackSubimage)
5380 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005381 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005382 return false;
5383 }
5384 break;
5385
5386 case GL_PACK_ROW_LENGTH:
5387 case GL_PACK_SKIP_ROWS:
5388 case GL_PACK_SKIP_PIXELS:
5389 if (!context->getExtensions().packSubimage)
5390 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005391 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005392 return false;
5393 }
5394 break;
5395 }
5396 }
5397
5398 if (param < 0)
5399 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005400 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005401 return false;
5402 }
5403
5404 switch (pname)
5405 {
5406 case GL_UNPACK_ALIGNMENT:
5407 if (param != 1 && param != 2 && param != 4 && param != 8)
5408 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005409 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005410 return false;
5411 }
5412 break;
5413
5414 case GL_PACK_ALIGNMENT:
5415 if (param != 1 && param != 2 && param != 4 && param != 8)
5416 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005417 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005418 return false;
5419 }
5420 break;
5421
5422 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005423 if (!context->getExtensions().packReverseRowOrder)
5424 {
5425 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5426 }
5427 break;
5428
Jamie Madillc1d770e2017-04-13 17:31:24 -04005429 case GL_UNPACK_ROW_LENGTH:
5430 case GL_UNPACK_IMAGE_HEIGHT:
5431 case GL_UNPACK_SKIP_IMAGES:
5432 case GL_UNPACK_SKIP_ROWS:
5433 case GL_UNPACK_SKIP_PIXELS:
5434 case GL_PACK_ROW_LENGTH:
5435 case GL_PACK_SKIP_ROWS:
5436 case GL_PACK_SKIP_PIXELS:
5437 break;
5438
5439 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005440 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005441 return false;
5442 }
5443
5444 return true;
5445}
5446
Jamie Madill5b772312018-03-08 20:28:32 -05005447bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005448{
5449 return true;
5450}
5451
Jamie Madill5b772312018-03-08 20:28:32 -05005452bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005453{
5454 return true;
5455}
5456
Jamie Madill5b772312018-03-08 20:28:32 -05005457bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005458{
5459 return true;
5460}
5461
Jamie Madill5b772312018-03-08 20:28:32 -05005462bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005463{
5464 if (width < 0 || height < 0)
5465 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005466 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005467 return false;
5468 }
5469
5470 return true;
5471}
5472
Jamie Madill5b772312018-03-08 20:28:32 -05005473bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005474 GLsizei n,
5475 const GLuint *shaders,
5476 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005477 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005478 GLsizei length)
5479{
5480 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5481 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5482 shaderBinaryFormats.end())
5483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005484 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485 return false;
5486 }
5487
5488 return true;
5489}
5490
Jamie Madill5b772312018-03-08 20:28:32 -05005491bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005492 GLuint shader,
5493 GLsizei count,
5494 const GLchar *const *string,
5495 const GLint *length)
5496{
5497 if (count < 0)
5498 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005499 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005500 return false;
5501 }
5502
Geoff Langfc32e8b2017-05-31 14:16:59 -04005503 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5504 // shader-related entry points
5505 if (context->getExtensions().webglCompatibility)
5506 {
5507 for (GLsizei i = 0; i < count; i++)
5508 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005509 size_t len =
5510 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005511
5512 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005513 if (!IsValidESSLShaderSourceString(string[i], len,
5514 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005515 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005516 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005517 return false;
5518 }
5519 }
5520 }
5521
Jamie Madillc1d770e2017-04-13 17:31:24 -04005522 Shader *shaderObject = GetValidShader(context, shader);
5523 if (!shaderObject)
5524 {
5525 return false;
5526 }
5527
5528 return true;
5529}
5530
Jamie Madill5b772312018-03-08 20:28:32 -05005531bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005532{
5533 if (!IsValidStencilFunc(func))
5534 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005535 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005536 return false;
5537 }
5538
5539 return true;
5540}
5541
Jamie Madill5b772312018-03-08 20:28:32 -05005542bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005543{
5544 if (!IsValidStencilFace(face))
5545 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005546 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005547 return false;
5548 }
5549
5550 if (!IsValidStencilFunc(func))
5551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005552 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005553 return false;
5554 }
5555
5556 return true;
5557}
5558
Jamie Madill5b772312018-03-08 20:28:32 -05005559bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005560{
5561 return true;
5562}
5563
Jamie Madill5b772312018-03-08 20:28:32 -05005564bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005565{
5566 if (!IsValidStencilFace(face))
5567 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005568 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005569 return false;
5570 }
5571
5572 return true;
5573}
5574
Jamie Madill5b772312018-03-08 20:28:32 -05005575bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005576{
5577 if (!IsValidStencilOp(fail))
5578 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005579 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580 return false;
5581 }
5582
5583 if (!IsValidStencilOp(zfail))
5584 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005585 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005586 return false;
5587 }
5588
5589 if (!IsValidStencilOp(zpass))
5590 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005591 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005592 return false;
5593 }
5594
5595 return true;
5596}
5597
Jamie Madill5b772312018-03-08 20:28:32 -05005598bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005599 GLenum face,
5600 GLenum fail,
5601 GLenum zfail,
5602 GLenum zpass)
5603{
5604 if (!IsValidStencilFace(face))
5605 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005606 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005607 return false;
5608 }
5609
5610 return ValidateStencilOp(context, fail, zfail, zpass);
5611}
5612
Jamie Madill5b772312018-03-08 20:28:32 -05005613bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005614{
5615 return ValidateUniform(context, GL_FLOAT, location, 1);
5616}
5617
Jamie Madill5b772312018-03-08 20:28:32 -05005618bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005619{
5620 return ValidateUniform(context, GL_FLOAT, location, count);
5621}
5622
Jamie Madill5b772312018-03-08 20:28:32 -05005623bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005624{
5625 return ValidateUniform1iv(context, location, 1, &x);
5626}
5627
Jamie Madill5b772312018-03-08 20:28:32 -05005628bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629{
5630 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5631}
5632
Jamie Madill5b772312018-03-08 20:28:32 -05005633bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005634{
5635 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5636}
5637
Jamie Madill5b772312018-03-08 20:28:32 -05005638bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005639{
5640 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5641}
5642
Jamie Madill5b772312018-03-08 20:28:32 -05005643bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005644{
5645 return ValidateUniform(context, GL_INT_VEC2, location, count);
5646}
5647
Jamie Madill5b772312018-03-08 20:28:32 -05005648bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005649{
5650 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5651}
5652
Jamie Madill5b772312018-03-08 20:28:32 -05005653bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005654{
5655 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5656}
5657
Jamie Madill5b772312018-03-08 20:28:32 -05005658bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005659{
5660 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5661}
5662
Jamie Madill5b772312018-03-08 20:28:32 -05005663bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005664{
5665 return ValidateUniform(context, GL_INT_VEC3, location, count);
5666}
5667
Jamie Madill5b772312018-03-08 20:28:32 -05005668bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005669{
5670 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5671}
5672
Jamie Madill5b772312018-03-08 20:28:32 -05005673bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005674{
5675 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5676}
5677
Jamie Madill5b772312018-03-08 20:28:32 -05005678bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005679{
5680 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5681}
5682
Jamie Madill5b772312018-03-08 20:28:32 -05005683bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005684{
5685 return ValidateUniform(context, GL_INT_VEC4, location, count);
5686}
5687
Jamie Madill5b772312018-03-08 20:28:32 -05005688bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005689 GLint location,
5690 GLsizei count,
5691 GLboolean transpose,
5692 const GLfloat *value)
5693{
5694 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5695}
5696
Jamie Madill5b772312018-03-08 20:28:32 -05005697bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005698 GLint location,
5699 GLsizei count,
5700 GLboolean transpose,
5701 const GLfloat *value)
5702{
5703 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5704}
5705
Jamie Madill5b772312018-03-08 20:28:32 -05005706bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005707 GLint location,
5708 GLsizei count,
5709 GLboolean transpose,
5710 const GLfloat *value)
5711{
5712 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5713}
5714
Jamie Madill5b772312018-03-08 20:28:32 -05005715bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005716{
5717 Program *programObject = GetValidProgram(context, program);
5718
5719 if (!programObject)
5720 {
5721 return false;
5722 }
5723
5724 return true;
5725}
5726
Jamie Madill5b772312018-03-08 20:28:32 -05005727bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005728{
5729 return ValidateVertexAttribIndex(context, index);
5730}
5731
Jamie Madill5b772312018-03-08 20:28:32 -05005732bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005733{
5734 return ValidateVertexAttribIndex(context, index);
5735}
5736
Jamie Madill5b772312018-03-08 20:28:32 -05005737bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005738{
5739 return ValidateVertexAttribIndex(context, index);
5740}
5741
Jamie Madill5b772312018-03-08 20:28:32 -05005742bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005743{
5744 return ValidateVertexAttribIndex(context, index);
5745}
5746
Jamie Madill5b772312018-03-08 20:28:32 -05005747bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005748{
5749 return ValidateVertexAttribIndex(context, index);
5750}
5751
Jamie Madill5b772312018-03-08 20:28:32 -05005752bool ValidateVertexAttrib3fv(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 ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005758 GLuint index,
5759 GLfloat x,
5760 GLfloat y,
5761 GLfloat z,
5762 GLfloat w)
5763{
5764 return ValidateVertexAttribIndex(context, index);
5765}
5766
Jamie Madill5b772312018-03-08 20:28:32 -05005767bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005768{
5769 return ValidateVertexAttribIndex(context, index);
5770}
5771
Jamie Madill5b772312018-03-08 20:28:32 -05005772bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005773{
5774 if (width < 0 || height < 0)
5775 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005776 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005777 return false;
5778 }
5779
5780 return true;
5781}
5782
Jamie Madill5b772312018-03-08 20:28:32 -05005783bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005784{
5785 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5786}
5787
Jamie Madill5b772312018-03-08 20:28:32 -05005788bool ValidateDrawElements(Context *context,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005789 GLenum mode,
5790 GLsizei count,
5791 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005792 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005793{
5794 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5795}
5796
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005797bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005798 GLenum target,
5799 GLenum attachment,
5800 GLenum pname,
5801 GLint *params)
5802{
5803 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5804 nullptr);
5805}
5806
Jamie Madill5b772312018-03-08 20:28:32 -05005807bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005808{
5809 return ValidateGetProgramivBase(context, program, pname, nullptr);
5810}
5811
Jamie Madill5b772312018-03-08 20:28:32 -05005812bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005813 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005814 GLint level,
5815 GLenum internalformat,
5816 GLint x,
5817 GLint y,
5818 GLsizei width,
5819 GLsizei height,
5820 GLint border)
5821{
5822 if (context->getClientMajorVersion() < 3)
5823 {
5824 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5825 0, x, y, width, height, border);
5826 }
5827
5828 ASSERT(context->getClientMajorVersion() == 3);
5829 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5830 0, x, y, width, height, border);
5831}
5832
5833bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005834 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005835 GLint level,
5836 GLint xoffset,
5837 GLint yoffset,
5838 GLint x,
5839 GLint y,
5840 GLsizei width,
5841 GLsizei height)
5842{
5843 if (context->getClientMajorVersion() < 3)
5844 {
5845 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5846 yoffset, x, y, width, height, 0);
5847 }
5848
5849 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5850 yoffset, 0, x, y, width, height, 0);
5851}
5852
5853bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5854{
5855 return ValidateGenOrDelete(context, n);
5856}
5857
5858bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5859{
5860 return ValidateGenOrDelete(context, n);
5861}
5862
5863bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5864{
5865 return ValidateGenOrDelete(context, n);
5866}
5867
5868bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5869{
5870 return ValidateGenOrDelete(context, n);
5871}
5872
5873bool ValidateDisable(Context *context, GLenum cap)
5874{
5875 if (!ValidCap(context, cap, false))
5876 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005877 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005878 return false;
5879 }
5880
5881 return true;
5882}
5883
5884bool ValidateEnable(Context *context, GLenum cap)
5885{
5886 if (!ValidCap(context, cap, false))
5887 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005888 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005889 return false;
5890 }
5891
5892 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5893 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5894 {
5895 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005896 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005897
5898 // We also output an error message to the debugger window if tracing is active, so that
5899 // developers can see the error message.
5900 ERR() << errorMessage;
5901 return false;
5902 }
5903
5904 return true;
5905}
5906
5907bool ValidateFramebufferRenderbuffer(Context *context,
5908 GLenum target,
5909 GLenum attachment,
5910 GLenum renderbuffertarget,
5911 GLuint renderbuffer)
5912{
Geoff Lange8afa902017-09-27 15:00:43 -04005913 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005914 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005915 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5916 return false;
5917 }
5918
5919 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5920 {
5921 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005922 return false;
5923 }
5924
5925 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5926 renderbuffertarget, renderbuffer);
5927}
5928
5929bool ValidateFramebufferTexture2D(Context *context,
5930 GLenum target,
5931 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005932 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005933 GLuint texture,
5934 GLint level)
5935{
5936 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5937 // extension
5938 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5939 level != 0)
5940 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005941 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005942 return false;
5943 }
5944
5945 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5946 {
5947 return false;
5948 }
5949
5950 if (texture != 0)
5951 {
5952 gl::Texture *tex = context->getTexture(texture);
5953 ASSERT(tex);
5954
5955 const gl::Caps &caps = context->getCaps();
5956
5957 switch (textarget)
5958 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005959 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005960 {
5961 if (level > gl::log2(caps.max2DTextureSize))
5962 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005963 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005964 return false;
5965 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005966 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005967 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005968 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005969 return false;
5970 }
5971 }
5972 break;
5973
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005974 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005975 {
5976 if (level != 0)
5977 {
5978 context->handleError(InvalidValue());
5979 return false;
5980 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005981 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005982 {
5983 context->handleError(InvalidOperation()
5984 << "Textarget must match the texture target type.");
5985 return false;
5986 }
5987 }
5988 break;
5989
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005990 case TextureTarget::CubeMapNegativeX:
5991 case TextureTarget::CubeMapNegativeY:
5992 case TextureTarget::CubeMapNegativeZ:
5993 case TextureTarget::CubeMapPositiveX:
5994 case TextureTarget::CubeMapPositiveY:
5995 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04005996 {
5997 if (level > gl::log2(caps.maxCubeMapTextureSize))
5998 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005999 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006000 return false;
6001 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006002 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006003 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006004 context->handleError(InvalidOperation()
6005 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 return false;
6007 }
6008 }
6009 break;
6010
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006011 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 {
6013 if (context->getClientVersion() < ES_3_1)
6014 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006015 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006016 return false;
6017 }
6018
6019 if (level != 0)
6020 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006021 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006022 return false;
6023 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006024 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006025 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006026 context->handleError(InvalidOperation()
6027 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006028 return false;
6029 }
6030 }
6031 break;
6032
6033 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006034 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006035 return false;
6036 }
6037
6038 const Format &format = tex->getFormat(textarget, level);
6039 if (format.info->compressed)
6040 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006041 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 return false;
6043 }
6044 }
6045
6046 return true;
6047}
6048
6049bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6050{
6051 return ValidateGenOrDelete(context, n);
6052}
6053
6054bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6055{
6056 return ValidateGenOrDelete(context, n);
6057}
6058
6059bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6060{
6061 return ValidateGenOrDelete(context, n);
6062}
6063
6064bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6065{
6066 return ValidateGenOrDelete(context, n);
6067}
6068
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006069bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006070{
6071 if (!ValidTextureTarget(context, target))
6072 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006073 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006074 return false;
6075 }
6076
6077 Texture *texture = context->getTargetTexture(target);
6078
6079 if (texture == nullptr)
6080 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006081 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006082 return false;
6083 }
6084
6085 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6086
6087 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6088 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6089 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6090 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006091 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006092 return false;
6093 }
6094
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006095 TextureTarget baseTarget = (target == TextureType::CubeMap)
6096 ? TextureTarget::CubeMapPositiveX
6097 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006098 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6099 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6100 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006101 {
6102 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6103 return false;
6104 }
6105
Geoff Lang536eca12017-09-13 11:23:35 -04006106 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6107 bool formatUnsized = !format.sized;
6108 bool formatColorRenderableAndFilterable =
6109 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6110 format.renderSupport(context->getClientVersion(), context->getExtensions());
6111 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006112 {
Geoff Lang536eca12017-09-13 11:23:35 -04006113 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006114 return false;
6115 }
6116
Geoff Lang536eca12017-09-13 11:23:35 -04006117 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6118 // generation
6119 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6120 {
6121 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6122 return false;
6123 }
6124
6125 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6126 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006127 bool supportsSRGBMipmapGeneration =
6128 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006129 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006130 {
Geoff Lang536eca12017-09-13 11:23:35 -04006131 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006132 return false;
6133 }
6134
6135 // Non-power of 2 ES2 check
6136 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6137 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6138 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6139 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006140 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6141 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006142 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006143 return false;
6144 }
6145
6146 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006147 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006148 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006149 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006150 return false;
6151 }
6152
6153 return true;
6154}
6155
Jamie Madill5b772312018-03-08 20:28:32 -05006156bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006157 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006158 GLenum pname,
6159 GLint *params)
6160{
6161 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6162}
6163
6164bool ValidateGetRenderbufferParameteriv(Context *context,
6165 GLenum target,
6166 GLenum pname,
6167 GLint *params)
6168{
6169 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6170}
6171
6172bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6173{
6174 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6175}
6176
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006177bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006178{
6179 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6180}
6181
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006182bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006183{
6184 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6185}
6186
6187bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6188{
6189 return ValidateGetUniformBase(context, program, location);
6190}
6191
6192bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6193{
6194 return ValidateGetUniformBase(context, program, location);
6195}
6196
6197bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6198{
6199 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6200}
6201
6202bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6203{
6204 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6205}
6206
6207bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6208{
6209 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6210}
6211
6212bool ValidateIsEnabled(Context *context, GLenum cap)
6213{
6214 if (!ValidCap(context, cap, true))
6215 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006216 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006217 return false;
6218 }
6219
6220 return true;
6221}
6222
6223bool ValidateLinkProgram(Context *context, GLuint program)
6224{
6225 if (context->hasActiveTransformFeedback(program))
6226 {
6227 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006228 context->handleError(InvalidOperation() << "Cannot link program while program is "
6229 "associated with an active transform "
6230 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006231 return false;
6232 }
6233
6234 Program *programObject = GetValidProgram(context, program);
6235 if (!programObject)
6236 {
6237 return false;
6238 }
6239
6240 return true;
6241}
6242
Jamie Madill4928b7c2017-06-20 12:57:39 -04006243bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006244 GLint x,
6245 GLint y,
6246 GLsizei width,
6247 GLsizei height,
6248 GLenum format,
6249 GLenum type,
6250 void *pixels)
6251{
6252 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6253 nullptr, pixels);
6254}
6255
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006256bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006257{
6258 return ValidateTexParameterBase(context, target, pname, -1, &param);
6259}
6260
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006261bool ValidateTexParameterfv(Context *context,
6262 TextureType target,
6263 GLenum pname,
6264 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006265{
6266 return ValidateTexParameterBase(context, target, pname, -1, params);
6267}
6268
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006269bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006270{
6271 return ValidateTexParameterBase(context, target, pname, -1, &param);
6272}
6273
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006274bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006275{
6276 return ValidateTexParameterBase(context, target, pname, -1, params);
6277}
6278
6279bool ValidateUseProgram(Context *context, GLuint program)
6280{
6281 if (program != 0)
6282 {
6283 Program *programObject = context->getProgram(program);
6284 if (!programObject)
6285 {
6286 // ES 3.1.0 section 7.3 page 72
6287 if (context->getShader(program))
6288 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006289 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006290 return false;
6291 }
6292 else
6293 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006294 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006295 return false;
6296 }
6297 }
6298 if (!programObject->isLinked())
6299 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006300 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006301 return false;
6302 }
6303 }
6304 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6305 {
6306 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006307 context
6308 ->handleError(InvalidOperation()
6309 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006310 return false;
6311 }
6312
6313 return true;
6314}
6315
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006316bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6317{
6318 if (!context->getExtensions().fence)
6319 {
6320 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6321 return false;
6322 }
6323
6324 if (n < 0)
6325 {
6326 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6327 return false;
6328 }
6329
6330 return true;
6331}
6332
6333bool ValidateFinishFenceNV(Context *context, GLuint fence)
6334{
6335 if (!context->getExtensions().fence)
6336 {
6337 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6338 return false;
6339 }
6340
6341 FenceNV *fenceObject = context->getFenceNV(fence);
6342
6343 if (fenceObject == nullptr)
6344 {
6345 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6346 return false;
6347 }
6348
6349 if (!fenceObject->isSet())
6350 {
6351 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6352 return false;
6353 }
6354
6355 return true;
6356}
6357
6358bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6359{
6360 if (!context->getExtensions().fence)
6361 {
6362 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6363 return false;
6364 }
6365
6366 if (n < 0)
6367 {
6368 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6369 return false;
6370 }
6371
6372 return true;
6373}
6374
6375bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6376{
6377 if (!context->getExtensions().fence)
6378 {
6379 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6380 return false;
6381 }
6382
6383 FenceNV *fenceObject = context->getFenceNV(fence);
6384
6385 if (fenceObject == nullptr)
6386 {
6387 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6388 return false;
6389 }
6390
6391 if (!fenceObject->isSet())
6392 {
6393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6394 return false;
6395 }
6396
6397 switch (pname)
6398 {
6399 case GL_FENCE_STATUS_NV:
6400 case GL_FENCE_CONDITION_NV:
6401 break;
6402
6403 default:
6404 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6405 return false;
6406 }
6407
6408 return true;
6409}
6410
6411bool ValidateGetGraphicsResetStatusEXT(Context *context)
6412{
6413 if (!context->getExtensions().robustness)
6414 {
6415 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6416 return false;
6417 }
6418
6419 return true;
6420}
6421
6422bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6423 GLuint shader,
6424 GLsizei bufsize,
6425 GLsizei *length,
6426 GLchar *source)
6427{
6428 if (!context->getExtensions().translatedShaderSource)
6429 {
6430 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6431 return false;
6432 }
6433
6434 if (bufsize < 0)
6435 {
6436 context->handleError(InvalidValue());
6437 return false;
6438 }
6439
6440 Shader *shaderObject = context->getShader(shader);
6441
6442 if (!shaderObject)
6443 {
6444 context->handleError(InvalidOperation());
6445 return false;
6446 }
6447
6448 return true;
6449}
6450
6451bool ValidateIsFenceNV(Context *context, GLuint fence)
6452{
6453 if (!context->getExtensions().fence)
6454 {
6455 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6456 return false;
6457 }
6458
6459 return true;
6460}
6461
Jamie Madill007530e2017-12-28 14:27:04 -05006462bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6463{
6464 if (!context->getExtensions().fence)
6465 {
6466 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6467 return false;
6468 }
6469
6470 if (condition != GL_ALL_COMPLETED_NV)
6471 {
6472 context->handleError(InvalidEnum());
6473 return false;
6474 }
6475
6476 FenceNV *fenceObject = context->getFenceNV(fence);
6477
6478 if (fenceObject == nullptr)
6479 {
6480 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6481 return false;
6482 }
6483
6484 return true;
6485}
6486
6487bool ValidateTestFenceNV(Context *context, GLuint fence)
6488{
6489 if (!context->getExtensions().fence)
6490 {
6491 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6492 return false;
6493 }
6494
6495 FenceNV *fenceObject = context->getFenceNV(fence);
6496
6497 if (fenceObject == nullptr)
6498 {
6499 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6500 return false;
6501 }
6502
6503 if (fenceObject->isSet() != GL_TRUE)
6504 {
6505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6506 return false;
6507 }
6508
6509 return true;
6510}
6511
6512bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006513 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006514 GLsizei levels,
6515 GLenum internalformat,
6516 GLsizei width,
6517 GLsizei height)
6518{
6519 if (!context->getExtensions().textureStorage)
6520 {
6521 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6522 return false;
6523 }
6524
6525 if (context->getClientMajorVersion() < 3)
6526 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006527 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006528 height);
6529 }
6530
6531 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006532 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006533 1);
6534}
6535
6536bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6537{
6538 if (!context->getExtensions().instancedArrays)
6539 {
6540 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6541 return false;
6542 }
6543
6544 if (index >= MAX_VERTEX_ATTRIBS)
6545 {
6546 context->handleError(InvalidValue());
6547 return false;
6548 }
6549
6550 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6551 {
6552 if (index == 0 && divisor != 0)
6553 {
6554 const char *errorMessage =
6555 "The current context doesn't support setting a non-zero divisor on the "
6556 "attribute with index zero. "
6557 "Please reorder the attributes in your vertex shader so that attribute zero "
6558 "can have a zero divisor.";
6559 context->handleError(InvalidOperation() << errorMessage);
6560
6561 // We also output an error message to the debugger window if tracing is active, so
6562 // that developers can see the error message.
6563 ERR() << errorMessage;
6564 return false;
6565 }
6566 }
6567
6568 return true;
6569}
6570
6571bool ValidateTexImage3DOES(Context *context,
6572 GLenum target,
6573 GLint level,
6574 GLenum internalformat,
6575 GLsizei width,
6576 GLsizei height,
6577 GLsizei depth,
6578 GLint border,
6579 GLenum format,
6580 GLenum type,
6581 const void *pixels)
6582{
6583 UNIMPLEMENTED(); // FIXME
6584 return false;
6585}
6586
6587bool ValidatePopGroupMarkerEXT(Context *context)
6588{
6589 if (!context->getExtensions().debugMarker)
6590 {
6591 // The debug marker calls should not set error state
6592 // However, it seems reasonable to set an error state if the extension is not enabled
6593 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6594 return false;
6595 }
6596
6597 return true;
6598}
6599
Jamie Madillfa920eb2018-01-04 11:45:50 -05006600bool ValidateTexStorage1DEXT(Context *context,
6601 GLenum target,
6602 GLsizei levels,
6603 GLenum internalformat,
6604 GLsizei width)
6605{
6606 UNIMPLEMENTED();
6607 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6608 return false;
6609}
6610
6611bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006612 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006613 GLsizei levels,
6614 GLenum internalformat,
6615 GLsizei width,
6616 GLsizei height,
6617 GLsizei depth)
6618{
6619 if (!context->getExtensions().textureStorage)
6620 {
6621 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6622 return false;
6623 }
6624
6625 if (context->getClientMajorVersion() < 3)
6626 {
6627 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6628 return false;
6629 }
6630
6631 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6632 depth);
6633}
6634
Jamie Madillc29968b2016-01-20 11:17:23 -05006635} // namespace gl