blob: 364de0cffd5addae633114d542860f7b7adacd82 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070078 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030079 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madill5b772312018-03-08 20:28:32 -0500458bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700795 // GLES1 emulation: GLES1-specific caps
796 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700797 case GL_VERTEX_ARRAY:
798 case GL_NORMAL_ARRAY:
799 case GL_COLOR_ARRAY:
800 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700801 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700802 case GL_POINT_SIZE_ARRAY_OES:
803 return context->getClientVersion() < Version(2, 0) &&
804 context->getExtensions().pointSizeArray;
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700805
Jamie Madillbe849e42017-05-02 15:49:00 -0400806 default:
807 return false;
808 }
809}
810
Geoff Langfc32e8b2017-05-31 14:16:59 -0400811// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
812// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400813bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400814{
815 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400816 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
817 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400818 {
819 return true;
820 }
821
822 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
823 if (c >= 9 && c <= 13)
824 {
825 return true;
826 }
827
828 return false;
829}
830
Geoff Langcab92ee2017-07-19 17:32:07 -0400831bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400832{
Geoff Langa71a98e2017-06-19 15:15:00 -0400833 for (size_t i = 0; i < len; i++)
834 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400835 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400836 {
837 return false;
838 }
839 }
840
841 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400842}
843
Geoff Langcab92ee2017-07-19 17:32:07 -0400844bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
845{
846 enum class ParseState
847 {
848 // Have not seen an ASCII non-whitespace character yet on
849 // this line. Possible that we might see a preprocessor
850 // directive.
851 BEGINING_OF_LINE,
852
853 // Have seen at least one ASCII non-whitespace character
854 // on this line.
855 MIDDLE_OF_LINE,
856
857 // Handling a preprocessor directive. Passes through all
858 // characters up to the end of the line. Disables comment
859 // processing.
860 IN_PREPROCESSOR_DIRECTIVE,
861
862 // Handling a single-line comment. The comment text is
863 // replaced with a single space.
864 IN_SINGLE_LINE_COMMENT,
865
866 // Handling a multi-line comment. Newlines are passed
867 // through to preserve line numbers.
868 IN_MULTI_LINE_COMMENT
869 };
870
871 ParseState state = ParseState::BEGINING_OF_LINE;
872 size_t pos = 0;
873
874 while (pos < len)
875 {
876 char c = str[pos];
877 char next = pos + 1 < len ? str[pos + 1] : 0;
878
879 // Check for newlines
880 if (c == '\n' || c == '\r')
881 {
882 if (state != ParseState::IN_MULTI_LINE_COMMENT)
883 {
884 state = ParseState::BEGINING_OF_LINE;
885 }
886
887 pos++;
888 continue;
889 }
890
891 switch (state)
892 {
893 case ParseState::BEGINING_OF_LINE:
894 if (c == ' ')
895 {
896 // Maintain the BEGINING_OF_LINE state until a non-space is seen
897 pos++;
898 }
899 else if (c == '#')
900 {
901 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
902 pos++;
903 }
904 else
905 {
906 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
907 state = ParseState::MIDDLE_OF_LINE;
908 }
909 break;
910
911 case ParseState::MIDDLE_OF_LINE:
912 if (c == '/' && next == '/')
913 {
914 state = ParseState::IN_SINGLE_LINE_COMMENT;
915 pos++;
916 }
917 else if (c == '/' && next == '*')
918 {
919 state = ParseState::IN_MULTI_LINE_COMMENT;
920 pos++;
921 }
922 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
923 {
924 // Skip line continuation characters
925 }
926 else if (!IsValidESSLCharacter(c))
927 {
928 return false;
929 }
930 pos++;
931 break;
932
933 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700934 // Line-continuation characters may not be permitted.
935 // Otherwise, just pass it through. Do not parse comments in this state.
936 if (!lineContinuationAllowed && c == '\\')
937 {
938 return false;
939 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400940 pos++;
941 break;
942
943 case ParseState::IN_SINGLE_LINE_COMMENT:
944 // Line-continuation characters are processed before comment processing.
945 // Advance string if a new line character is immediately behind
946 // line-continuation character.
947 if (c == '\\' && (next == '\n' || next == '\r'))
948 {
949 pos++;
950 }
951 pos++;
952 break;
953
954 case ParseState::IN_MULTI_LINE_COMMENT:
955 if (c == '*' && next == '/')
956 {
957 state = ParseState::MIDDLE_OF_LINE;
958 pos++;
959 }
960 pos++;
961 break;
962 }
963 }
964
965 return true;
966}
967
Jamie Madill5b772312018-03-08 20:28:32 -0500968bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700969{
970 ASSERT(context->isWebGL());
971
972 // WebGL 1.0 [Section 6.16] GLSL Constructs
973 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
974 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
975 {
976 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
977 return false;
978 }
979
980 return true;
981}
982
Jamie Madill5b772312018-03-08 20:28:32 -0500983bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700984{
985 ASSERT(context->isWebGL());
986
987 if (context->isWebGL1() && length > 256)
988 {
989 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
990 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
991 // locations.
992 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
993
994 return false;
995 }
996 else if (length > 1024)
997 {
998 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
999 // uniform and attribute locations.
1000 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1001 return false;
1002 }
1003
1004 return true;
1005}
1006
Jamie Madill007530e2017-12-28 14:27:04 -05001007bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1008{
1009 if (!context->getExtensions().pathRendering)
1010 {
1011 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1012 return false;
1013 }
1014
1015 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1016 {
1017 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1018 return false;
1019 }
1020 return true;
1021}
Jamie Madillc29968b2016-01-20 11:17:23 -05001022} // anonymous namespace
1023
Geoff Langff5b2d52016-09-07 11:32:23 -04001024bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001025 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001026 GLint level,
1027 GLenum internalformat,
1028 bool isCompressed,
1029 bool isSubImage,
1030 GLint xoffset,
1031 GLint yoffset,
1032 GLsizei width,
1033 GLsizei height,
1034 GLint border,
1035 GLenum format,
1036 GLenum type,
1037 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001038 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001039{
Jamie Madill6f38f822014-06-06 17:12:20 -04001040 if (!ValidTexture2DDestinationTarget(context, target))
1041 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001042 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001043 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001044 }
1045
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001046 TextureType texType = TextureTargetToType(target);
1047 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001049 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001050 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001051 }
1052
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001053 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001054 {
1055 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1056 return false;
1057 }
1058
1059 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001060 std::numeric_limits<GLsizei>::max() - yoffset < height)
1061 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001062 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001063 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001064 }
1065
Geoff Lang6e898aa2017-06-02 11:17:26 -04001066 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1067 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1068 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1069 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1070 // case.
1071 bool nonEqualFormatsAllowed =
1072 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1073 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1074
1075 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001076 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001077 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001078 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001079 }
1080
Geoff Langaae65a42014-05-26 12:43:44 -04001081 const gl::Caps &caps = context->getCaps();
1082
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001083 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001084 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001085 case TextureType::_2D:
1086 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1087 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1088 {
1089 context->handleError(InvalidValue());
1090 return false;
1091 }
1092 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001093
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001094 case TextureType::Rectangle:
1095 ASSERT(level == 0);
1096 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1097 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1098 {
1099 context->handleError(InvalidValue());
1100 return false;
1101 }
1102 if (isCompressed)
1103 {
1104 context->handleError(InvalidEnum()
1105 << "Rectangle texture cannot have a compressed format.");
1106 return false;
1107 }
1108 break;
1109
1110 case TextureType::CubeMap:
1111 if (!isSubImage && width != height)
1112 {
1113 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1114 return false;
1115 }
1116
1117 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1118 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1119 {
1120 context->handleError(InvalidValue());
1121 return false;
1122 }
1123 break;
1124
1125 default:
1126 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001127 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001128 }
1129
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001130 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001131 if (!texture)
1132 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001133 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001134 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001135 }
1136
Geoff Langa9be0dc2014-12-17 12:34:40 -05001137 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001138 {
Geoff Langca271392017-04-05 12:30:00 -04001139 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1140 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001141 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001142 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001143 return false;
1144 }
1145
Geoff Langa9be0dc2014-12-17 12:34:40 -05001146 if (format != GL_NONE)
1147 {
Geoff Langca271392017-04-05 12:30:00 -04001148 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1149 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001150 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001152 return false;
1153 }
1154 }
1155
1156 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1157 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1158 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001159 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001160 return false;
1161 }
Geoff Langfb052642017-10-24 13:42:09 -04001162
1163 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001164 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001165 {
1166 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1167 return false;
1168 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001169 }
1170 else
1171 {
Geoff Lang69cce582015-09-17 13:20:36 -04001172 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001174 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001175 return false;
1176 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001177 }
1178
1179 // Verify zero border
1180 if (border != 0)
1181 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001182 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001183 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184 }
1185
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001186 if (isCompressed)
1187 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001188 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001189 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1190 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001191 switch (actualInternalFormat)
1192 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001193 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1194 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1195 if (!context->getExtensions().textureCompressionDXT1)
1196 {
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_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001202 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001203 {
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;
1208 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1209 if (!context->getExtensions().textureCompressionDXT5)
1210 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001211 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001212 return false;
1213 }
1214 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001215 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1216 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1217 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1218 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1219 if (!context->getExtensions().textureCompressionS3TCsRGB)
1220 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001221 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001222 return false;
1223 }
1224 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001225 case GL_ETC1_RGB8_OES:
1226 if (!context->getExtensions().compressedETC1RGB8Texture)
1227 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001228 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001229 return false;
1230 }
Geoff Lang86f81162017-10-30 15:10:45 -04001231 if (isSubImage)
1232 {
1233 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1234 return false;
1235 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001236 break;
1237 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001238 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1239 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1240 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1241 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001242 if (!context->getExtensions().lossyETCDecode)
1243 {
Geoff Lang86f81162017-10-30 15:10:45 -04001244 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001245 return false;
1246 }
1247 break;
1248 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001249 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001250 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001251 }
Geoff Lang966c9402017-04-18 12:38:27 -04001252
1253 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001254 {
Geoff Lang966c9402017-04-18 12:38:27 -04001255 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1256 height, texture->getWidth(target, level),
1257 texture->getHeight(target, level)))
1258 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001259 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001260 return false;
1261 }
1262
1263 if (format != actualInternalFormat)
1264 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001265 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001266 return false;
1267 }
1268 }
1269 else
1270 {
1271 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1272 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001273 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001274 return false;
1275 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001276 }
1277 }
1278 else
1279 {
1280 // validate <type> by itself (used as secondary key below)
1281 switch (type)
1282 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001283 case GL_UNSIGNED_BYTE:
1284 case GL_UNSIGNED_SHORT_5_6_5:
1285 case GL_UNSIGNED_SHORT_4_4_4_4:
1286 case GL_UNSIGNED_SHORT_5_5_5_1:
1287 case GL_UNSIGNED_SHORT:
1288 case GL_UNSIGNED_INT:
1289 case GL_UNSIGNED_INT_24_8_OES:
1290 case GL_HALF_FLOAT_OES:
1291 case GL_FLOAT:
1292 break;
1293 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001294 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001295 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001296 }
1297
1298 // validate <format> + <type> combinations
1299 // - invalid <format> -> sets INVALID_ENUM
1300 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1301 switch (format)
1302 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 case GL_ALPHA:
1304 case GL_LUMINANCE:
1305 case GL_LUMINANCE_ALPHA:
1306 switch (type)
1307 {
1308 case GL_UNSIGNED_BYTE:
1309 case GL_FLOAT:
1310 case GL_HALF_FLOAT_OES:
1311 break;
1312 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001313 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001314 return false;
1315 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001316 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001317 case GL_RED:
1318 case GL_RG:
1319 if (!context->getExtensions().textureRG)
1320 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001321 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001322 return false;
1323 }
1324 switch (type)
1325 {
1326 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001327 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001328 case GL_FLOAT:
1329 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001330 if (!context->getExtensions().textureFloat)
1331 {
1332 context->handleError(InvalidEnum());
1333 return false;
1334 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001335 break;
1336 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001337 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001338 return false;
1339 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001340 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001341 case GL_RGB:
1342 switch (type)
1343 {
1344 case GL_UNSIGNED_BYTE:
1345 case GL_UNSIGNED_SHORT_5_6_5:
1346 case GL_FLOAT:
1347 case GL_HALF_FLOAT_OES:
1348 break;
1349 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001351 return false;
1352 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001353 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001354 case GL_RGBA:
1355 switch (type)
1356 {
1357 case GL_UNSIGNED_BYTE:
1358 case GL_UNSIGNED_SHORT_4_4_4_4:
1359 case GL_UNSIGNED_SHORT_5_5_5_1:
1360 case GL_FLOAT:
1361 case GL_HALF_FLOAT_OES:
1362 break;
1363 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001365 return false;
1366 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001367 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001368 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001369 if (!context->getExtensions().textureFormatBGRA8888)
1370 {
1371 context->handleError(InvalidEnum());
1372 return false;
1373 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001374 switch (type)
1375 {
1376 case GL_UNSIGNED_BYTE:
1377 break;
1378 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001379 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001380 return false;
1381 }
1382 break;
1383 case GL_SRGB_EXT:
1384 case GL_SRGB_ALPHA_EXT:
1385 if (!context->getExtensions().sRGB)
1386 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001387 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001388 return false;
1389 }
1390 switch (type)
1391 {
1392 case GL_UNSIGNED_BYTE:
1393 break;
1394 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001396 return false;
1397 }
1398 break;
1399 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1400 // handled below
1401 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1402 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1403 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1404 break;
1405 case GL_DEPTH_COMPONENT:
1406 switch (type)
1407 {
1408 case GL_UNSIGNED_SHORT:
1409 case GL_UNSIGNED_INT:
1410 break;
1411 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001412 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001413 return false;
1414 }
1415 break;
1416 case GL_DEPTH_STENCIL_OES:
1417 switch (type)
1418 {
1419 case GL_UNSIGNED_INT_24_8_OES:
1420 break;
1421 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001422 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001423 return false;
1424 }
1425 break;
1426 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001427 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001428 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001429 }
1430
1431 switch (format)
1432 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1434 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1435 if (context->getExtensions().textureCompressionDXT1)
1436 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001437 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001438 return false;
1439 }
1440 else
1441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001442 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 break;
1446 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1447 if (context->getExtensions().textureCompressionDXT3)
1448 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001449 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001450 return false;
1451 }
1452 else
1453 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001454 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001455 return false;
1456 }
1457 break;
1458 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1459 if (context->getExtensions().textureCompressionDXT5)
1460 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001461 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001462 return false;
1463 }
1464 else
1465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001466 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 return false;
1468 }
1469 break;
1470 case GL_ETC1_RGB8_OES:
1471 if (context->getExtensions().compressedETC1RGB8Texture)
1472 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001473 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001474 return false;
1475 }
1476 else
1477 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001478 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001479 return false;
1480 }
1481 break;
1482 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001483 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1484 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1485 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1486 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 if (context->getExtensions().lossyETCDecode)
1488 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001489 context->handleError(InvalidOperation()
1490 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001491 return false;
1492 }
1493 else
1494 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001495 context->handleError(InvalidEnum()
1496 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 return false;
1498 }
1499 break;
1500 case GL_DEPTH_COMPONENT:
1501 case GL_DEPTH_STENCIL_OES:
1502 if (!context->getExtensions().depthTextures)
1503 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001504 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001505 return false;
1506 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001507 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001508 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001509 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001510 return false;
1511 }
1512 // OES_depth_texture supports loading depth data and multiple levels,
1513 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001514 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001515 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001516 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1517 return false;
1518 }
1519 if (level != 0)
1520 {
1521 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001522 return false;
1523 }
1524 break;
1525 default:
1526 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001527 }
1528
Geoff Lang6e898aa2017-06-02 11:17:26 -04001529 if (!isSubImage)
1530 {
1531 switch (internalformat)
1532 {
1533 case GL_RGBA32F:
1534 if (!context->getExtensions().colorBufferFloatRGBA)
1535 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001536 context->handleError(InvalidValue()
1537 << "Sized GL_RGBA32F internal format requires "
1538 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001539 return false;
1540 }
1541 if (type != GL_FLOAT)
1542 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001544 return false;
1545 }
1546 if (format != GL_RGBA)
1547 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001548 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001549 return false;
1550 }
1551 break;
1552
1553 case GL_RGB32F:
1554 if (!context->getExtensions().colorBufferFloatRGB)
1555 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001556 context->handleError(InvalidValue()
1557 << "Sized GL_RGB32F internal format requires "
1558 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001559 return false;
1560 }
1561 if (type != GL_FLOAT)
1562 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001563 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001564 return false;
1565 }
1566 if (format != GL_RGB)
1567 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001568 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001569 return false;
1570 }
1571 break;
1572
1573 default:
1574 break;
1575 }
1576 }
1577
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001578 if (type == GL_FLOAT)
1579 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001580 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001581 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001582 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001583 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001584 }
1585 }
1586 else if (type == GL_HALF_FLOAT_OES)
1587 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001588 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001589 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001590 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001591 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001592 }
1593 }
1594 }
1595
Geoff Langdbcced82017-06-06 15:55:54 -04001596 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001597 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001598 imageSize))
1599 {
1600 return false;
1601 }
1602
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001603 return true;
1604}
1605
He Yunchaoced53ae2016-11-29 15:00:51 +08001606bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001607 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001608 GLsizei levels,
1609 GLenum internalformat,
1610 GLsizei width,
1611 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001612{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001613 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1614 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001615 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001616 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001617 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001618 }
1619
1620 if (width < 1 || height < 1 || levels < 1)
1621 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001622 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001623 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001624 }
1625
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001626 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001627 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001628 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001629 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001630 }
1631
1632 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1633 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001634 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001635 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 }
1637
Geoff Langca271392017-04-05 12:30:00 -04001638 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001639 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001640 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001641 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001642 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001643 }
1644
Geoff Langaae65a42014-05-26 12:43:44 -04001645 const gl::Caps &caps = context->getCaps();
1646
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001647 switch (target)
1648 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001649 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001650 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1651 static_cast<GLuint>(height) > caps.max2DTextureSize)
1652 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001653 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001654 return false;
1655 }
1656 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001657 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001658 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1659 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1660 {
1661 context->handleError(InvalidValue());
1662 return false;
1663 }
1664 if (formatInfo.compressed)
1665 {
1666 context->handleError(InvalidEnum()
1667 << "Rectangle texture cannot have a compressed format.");
1668 return false;
1669 }
1670 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001671 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001672 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1673 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1674 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001675 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001676 return false;
1677 }
1678 break;
1679 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001680 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001681 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001682 }
1683
Geoff Langc0b9ef42014-07-02 10:02:37 -04001684 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001685 {
1686 if (!gl::isPow2(width) || !gl::isPow2(height))
1687 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001688 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001689 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001690 }
1691 }
1692
1693 switch (internalformat)
1694 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001695 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1696 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1697 if (!context->getExtensions().textureCompressionDXT1)
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_DXT3_ANGLE:
1704 if (!context->getExtensions().textureCompressionDXT3)
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_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1711 if (!context->getExtensions().textureCompressionDXT5)
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_OES:
1718 if (!context->getExtensions().compressedETC1RGB8Texture)
1719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001720 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001721 return false;
1722 }
1723 break;
1724 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001725 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1726 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1727 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1728 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001729 if (!context->getExtensions().lossyETCDecode)
1730 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001731 context->handleError(InvalidEnum()
1732 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001733 return false;
1734 }
1735 break;
1736 case GL_RGBA32F_EXT:
1737 case GL_RGB32F_EXT:
1738 case GL_ALPHA32F_EXT:
1739 case GL_LUMINANCE32F_EXT:
1740 case GL_LUMINANCE_ALPHA32F_EXT:
1741 if (!context->getExtensions().textureFloat)
1742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001743 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001744 return false;
1745 }
1746 break;
1747 case GL_RGBA16F_EXT:
1748 case GL_RGB16F_EXT:
1749 case GL_ALPHA16F_EXT:
1750 case GL_LUMINANCE16F_EXT:
1751 case GL_LUMINANCE_ALPHA16F_EXT:
1752 if (!context->getExtensions().textureHalfFloat)
1753 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001754 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001755 return false;
1756 }
1757 break;
1758 case GL_R8_EXT:
1759 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001760 if (!context->getExtensions().textureRG)
1761 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001762 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001763 return false;
1764 }
1765 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001766 case GL_R16F_EXT:
1767 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001768 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1769 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001770 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001771 return false;
1772 }
1773 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001774 case GL_R32F_EXT:
1775 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001776 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001777 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001778 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001779 return false;
1780 }
1781 break;
1782 case GL_DEPTH_COMPONENT16:
1783 case GL_DEPTH_COMPONENT32_OES:
1784 case GL_DEPTH24_STENCIL8_OES:
1785 if (!context->getExtensions().depthTextures)
1786 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001787 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001788 return false;
1789 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001790 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001791 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001792 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001793 return false;
1794 }
1795 // ANGLE_depth_texture only supports 1-level textures
1796 if (levels != 1)
1797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001798 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001799 return false;
1800 }
1801 break;
1802 default:
1803 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001804 }
1805
Geoff Lang691e58c2014-12-19 17:03:25 -05001806 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001807 if (!texture || texture->id() == 0)
1808 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001809 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001810 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001811 }
1812
Geoff Lang69cce582015-09-17 13:20:36 -04001813 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001814 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001815 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001816 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001817 }
1818
1819 return true;
1820}
1821
He Yunchaoced53ae2016-11-29 15:00:51 +08001822bool ValidateDiscardFramebufferEXT(Context *context,
1823 GLenum target,
1824 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001825 const GLenum *attachments)
1826{
Jamie Madillc29968b2016-01-20 11:17:23 -05001827 if (!context->getExtensions().discardFramebuffer)
1828 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001829 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001830 return false;
1831 }
1832
Austin Kinross08332632015-05-05 13:35:47 -07001833 bool defaultFramebuffer = false;
1834
1835 switch (target)
1836 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001837 case GL_FRAMEBUFFER:
1838 defaultFramebuffer =
1839 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1840 break;
1841 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001842 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001843 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001844 }
1845
He Yunchaoced53ae2016-11-29 15:00:51 +08001846 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1847 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001848}
1849
Austin Kinrossbc781f32015-10-26 09:27:38 -07001850bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1851{
1852 if (!context->getExtensions().vertexArrayObject)
1853 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001854 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001855 return false;
1856 }
1857
1858 return ValidateBindVertexArrayBase(context, array);
1859}
1860
Jamie Madilld7576732017-08-26 18:49:50 -04001861bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001862{
1863 if (!context->getExtensions().vertexArrayObject)
1864 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001865 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001866 return false;
1867 }
1868
Olli Etuaho41997e72016-03-10 13:38:39 +02001869 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870}
1871
Jamie Madilld7576732017-08-26 18:49:50 -04001872bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001873{
1874 if (!context->getExtensions().vertexArrayObject)
1875 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001876 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001877 return false;
1878 }
1879
Olli Etuaho41997e72016-03-10 13:38:39 +02001880 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001881}
1882
Jamie Madilld7576732017-08-26 18:49:50 -04001883bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001884{
1885 if (!context->getExtensions().vertexArrayObject)
1886 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001887 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001888 return false;
1889 }
1890
1891 return true;
1892}
Geoff Langc5629752015-12-07 16:29:04 -05001893
1894bool ValidateProgramBinaryOES(Context *context,
1895 GLuint program,
1896 GLenum binaryFormat,
1897 const void *binary,
1898 GLint length)
1899{
1900 if (!context->getExtensions().getProgramBinary)
1901 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001902 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001903 return false;
1904 }
1905
1906 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1907}
1908
1909bool ValidateGetProgramBinaryOES(Context *context,
1910 GLuint program,
1911 GLsizei bufSize,
1912 GLsizei *length,
1913 GLenum *binaryFormat,
1914 void *binary)
1915{
1916 if (!context->getExtensions().getProgramBinary)
1917 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001918 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001919 return false;
1920 }
1921
1922 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1923}
Geoff Lange102fee2015-12-10 11:23:30 -05001924
Geoff Lang70d0f492015-12-10 17:45:46 -05001925static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1926{
1927 switch (source)
1928 {
1929 case GL_DEBUG_SOURCE_API:
1930 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1931 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1932 case GL_DEBUG_SOURCE_OTHER:
1933 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1934 return !mustBeThirdPartyOrApplication;
1935
1936 case GL_DEBUG_SOURCE_THIRD_PARTY:
1937 case GL_DEBUG_SOURCE_APPLICATION:
1938 return true;
1939
1940 default:
1941 return false;
1942 }
1943}
1944
1945static bool ValidDebugType(GLenum type)
1946{
1947 switch (type)
1948 {
1949 case GL_DEBUG_TYPE_ERROR:
1950 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1951 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1952 case GL_DEBUG_TYPE_PERFORMANCE:
1953 case GL_DEBUG_TYPE_PORTABILITY:
1954 case GL_DEBUG_TYPE_OTHER:
1955 case GL_DEBUG_TYPE_MARKER:
1956 case GL_DEBUG_TYPE_PUSH_GROUP:
1957 case GL_DEBUG_TYPE_POP_GROUP:
1958 return true;
1959
1960 default:
1961 return false;
1962 }
1963}
1964
1965static bool ValidDebugSeverity(GLenum severity)
1966{
1967 switch (severity)
1968 {
1969 case GL_DEBUG_SEVERITY_HIGH:
1970 case GL_DEBUG_SEVERITY_MEDIUM:
1971 case GL_DEBUG_SEVERITY_LOW:
1972 case GL_DEBUG_SEVERITY_NOTIFICATION:
1973 return true;
1974
1975 default:
1976 return false;
1977 }
1978}
1979
Geoff Lange102fee2015-12-10 11:23:30 -05001980bool ValidateDebugMessageControlKHR(Context *context,
1981 GLenum source,
1982 GLenum type,
1983 GLenum severity,
1984 GLsizei count,
1985 const GLuint *ids,
1986 GLboolean enabled)
1987{
1988 if (!context->getExtensions().debug)
1989 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001990 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001991 return false;
1992 }
1993
Geoff Lang70d0f492015-12-10 17:45:46 -05001994 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1995 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001996 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001997 return false;
1998 }
1999
2000 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2001 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002002 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002003 return false;
2004 }
2005
2006 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2007 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002008 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002009 return false;
2010 }
2011
2012 if (count > 0)
2013 {
2014 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2015 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002016 context->handleError(
2017 InvalidOperation()
2018 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002019 return false;
2020 }
2021
2022 if (severity != GL_DONT_CARE)
2023 {
Jamie Madill437fa652016-05-03 15:13:24 -04002024 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002025 InvalidOperation()
2026 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002027 return false;
2028 }
2029 }
2030
Geoff Lange102fee2015-12-10 11:23:30 -05002031 return true;
2032}
2033
2034bool ValidateDebugMessageInsertKHR(Context *context,
2035 GLenum source,
2036 GLenum type,
2037 GLuint id,
2038 GLenum severity,
2039 GLsizei length,
2040 const GLchar *buf)
2041{
2042 if (!context->getExtensions().debug)
2043 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002044 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002045 return false;
2046 }
2047
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002048 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002049 {
2050 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2051 // not generate an error.
2052 return false;
2053 }
2054
2055 if (!ValidDebugSeverity(severity))
2056 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002057 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002058 return false;
2059 }
2060
2061 if (!ValidDebugType(type))
2062 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002063 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002064 return false;
2065 }
2066
2067 if (!ValidDebugSource(source, true))
2068 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002069 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002070 return false;
2071 }
2072
2073 size_t messageLength = (length < 0) ? strlen(buf) : length;
2074 if (messageLength > context->getExtensions().maxDebugMessageLength)
2075 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002076 context->handleError(InvalidValue()
2077 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002078 return false;
2079 }
2080
Geoff Lange102fee2015-12-10 11:23:30 -05002081 return true;
2082}
2083
2084bool ValidateDebugMessageCallbackKHR(Context *context,
2085 GLDEBUGPROCKHR callback,
2086 const void *userParam)
2087{
2088 if (!context->getExtensions().debug)
2089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002090 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002091 return false;
2092 }
2093
Geoff Lange102fee2015-12-10 11:23:30 -05002094 return true;
2095}
2096
2097bool ValidateGetDebugMessageLogKHR(Context *context,
2098 GLuint count,
2099 GLsizei bufSize,
2100 GLenum *sources,
2101 GLenum *types,
2102 GLuint *ids,
2103 GLenum *severities,
2104 GLsizei *lengths,
2105 GLchar *messageLog)
2106{
2107 if (!context->getExtensions().debug)
2108 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002109 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002110 return false;
2111 }
2112
Geoff Lang70d0f492015-12-10 17:45:46 -05002113 if (bufSize < 0 && messageLog != nullptr)
2114 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002115 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002116 return false;
2117 }
2118
Geoff Lange102fee2015-12-10 11:23:30 -05002119 return true;
2120}
2121
2122bool ValidatePushDebugGroupKHR(Context *context,
2123 GLenum source,
2124 GLuint id,
2125 GLsizei length,
2126 const GLchar *message)
2127{
2128 if (!context->getExtensions().debug)
2129 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002130 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002131 return false;
2132 }
2133
Geoff Lang70d0f492015-12-10 17:45:46 -05002134 if (!ValidDebugSource(source, true))
2135 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002136 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002137 return false;
2138 }
2139
2140 size_t messageLength = (length < 0) ? strlen(message) : length;
2141 if (messageLength > context->getExtensions().maxDebugMessageLength)
2142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002143 context->handleError(InvalidValue()
2144 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002145 return false;
2146 }
2147
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002148 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002149 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2150 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002151 context
2152 ->handleError(StackOverflow()
2153 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002154 return false;
2155 }
2156
Geoff Lange102fee2015-12-10 11:23:30 -05002157 return true;
2158}
2159
2160bool ValidatePopDebugGroupKHR(Context *context)
2161{
2162 if (!context->getExtensions().debug)
2163 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002164 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002165 return false;
2166 }
2167
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002168 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002169 if (currentStackSize <= 1)
2170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002171 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002172 return false;
2173 }
2174
2175 return true;
2176}
2177
2178static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2179{
2180 switch (identifier)
2181 {
2182 case GL_BUFFER:
2183 if (context->getBuffer(name) == nullptr)
2184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002185 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002186 return false;
2187 }
2188 return true;
2189
2190 case GL_SHADER:
2191 if (context->getShader(name) == nullptr)
2192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002193 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002194 return false;
2195 }
2196 return true;
2197
2198 case GL_PROGRAM:
2199 if (context->getProgram(name) == nullptr)
2200 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002201 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002202 return false;
2203 }
2204 return true;
2205
2206 case GL_VERTEX_ARRAY:
2207 if (context->getVertexArray(name) == nullptr)
2208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002209 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002210 return false;
2211 }
2212 return true;
2213
2214 case GL_QUERY:
2215 if (context->getQuery(name) == nullptr)
2216 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002217 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002218 return false;
2219 }
2220 return true;
2221
2222 case GL_TRANSFORM_FEEDBACK:
2223 if (context->getTransformFeedback(name) == nullptr)
2224 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002225 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002226 return false;
2227 }
2228 return true;
2229
2230 case GL_SAMPLER:
2231 if (context->getSampler(name) == nullptr)
2232 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002233 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002234 return false;
2235 }
2236 return true;
2237
2238 case GL_TEXTURE:
2239 if (context->getTexture(name) == nullptr)
2240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002241 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002242 return false;
2243 }
2244 return true;
2245
2246 case GL_RENDERBUFFER:
2247 if (context->getRenderbuffer(name) == nullptr)
2248 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002249 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002250 return false;
2251 }
2252 return true;
2253
2254 case GL_FRAMEBUFFER:
2255 if (context->getFramebuffer(name) == nullptr)
2256 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002257 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002258 return false;
2259 }
2260 return true;
2261
2262 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002263 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002264 return false;
2265 }
Geoff Lange102fee2015-12-10 11:23:30 -05002266}
2267
Martin Radev9d901792016-07-15 15:58:58 +03002268static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2269{
2270 size_t labelLength = 0;
2271
2272 if (length < 0)
2273 {
2274 if (label != nullptr)
2275 {
2276 labelLength = strlen(label);
2277 }
2278 }
2279 else
2280 {
2281 labelLength = static_cast<size_t>(length);
2282 }
2283
2284 if (labelLength > context->getExtensions().maxLabelLength)
2285 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002286 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002287 return false;
2288 }
2289
2290 return true;
2291}
2292
Geoff Lange102fee2015-12-10 11:23:30 -05002293bool ValidateObjectLabelKHR(Context *context,
2294 GLenum identifier,
2295 GLuint name,
2296 GLsizei length,
2297 const GLchar *label)
2298{
2299 if (!context->getExtensions().debug)
2300 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002301 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002302 return false;
2303 }
2304
Geoff Lang70d0f492015-12-10 17:45:46 -05002305 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2306 {
2307 return false;
2308 }
2309
Martin Radev9d901792016-07-15 15:58:58 +03002310 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002311 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002312 return false;
2313 }
2314
Geoff Lange102fee2015-12-10 11:23:30 -05002315 return true;
2316}
2317
2318bool ValidateGetObjectLabelKHR(Context *context,
2319 GLenum identifier,
2320 GLuint name,
2321 GLsizei bufSize,
2322 GLsizei *length,
2323 GLchar *label)
2324{
2325 if (!context->getExtensions().debug)
2326 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002327 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002328 return false;
2329 }
2330
Geoff Lang70d0f492015-12-10 17:45:46 -05002331 if (bufSize < 0)
2332 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002333 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002334 return false;
2335 }
2336
2337 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2338 {
2339 return false;
2340 }
2341
Martin Radev9d901792016-07-15 15:58:58 +03002342 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002343}
2344
2345static bool ValidateObjectPtrName(Context *context, const void *ptr)
2346{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002347 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002348 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002349 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002350 return false;
2351 }
2352
Geoff Lange102fee2015-12-10 11:23:30 -05002353 return true;
2354}
2355
2356bool ValidateObjectPtrLabelKHR(Context *context,
2357 const void *ptr,
2358 GLsizei length,
2359 const GLchar *label)
2360{
2361 if (!context->getExtensions().debug)
2362 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002363 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002364 return false;
2365 }
2366
Geoff Lang70d0f492015-12-10 17:45:46 -05002367 if (!ValidateObjectPtrName(context, ptr))
2368 {
2369 return false;
2370 }
2371
Martin Radev9d901792016-07-15 15:58:58 +03002372 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002373 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002374 return false;
2375 }
2376
Geoff Lange102fee2015-12-10 11:23:30 -05002377 return true;
2378}
2379
2380bool ValidateGetObjectPtrLabelKHR(Context *context,
2381 const void *ptr,
2382 GLsizei bufSize,
2383 GLsizei *length,
2384 GLchar *label)
2385{
2386 if (!context->getExtensions().debug)
2387 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002389 return false;
2390 }
2391
Geoff Lang70d0f492015-12-10 17:45:46 -05002392 if (bufSize < 0)
2393 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002394 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002395 return false;
2396 }
2397
2398 if (!ValidateObjectPtrName(context, ptr))
2399 {
2400 return false;
2401 }
2402
Martin Radev9d901792016-07-15 15:58:58 +03002403 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002404}
2405
2406bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2407{
2408 if (!context->getExtensions().debug)
2409 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002410 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002411 return false;
2412 }
2413
Geoff Lang70d0f492015-12-10 17:45:46 -05002414 // TODO: represent this in Context::getQueryParameterInfo.
2415 switch (pname)
2416 {
2417 case GL_DEBUG_CALLBACK_FUNCTION:
2418 case GL_DEBUG_CALLBACK_USER_PARAM:
2419 break;
2420
2421 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002422 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002423 return false;
2424 }
2425
Geoff Lange102fee2015-12-10 11:23:30 -05002426 return true;
2427}
Jamie Madillc29968b2016-01-20 11:17:23 -05002428
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002429bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2430 GLenum pname,
2431 GLsizei bufSize,
2432 GLsizei *length,
2433 void **params)
2434{
2435 UNIMPLEMENTED();
2436 return false;
2437}
2438
Jamie Madillc29968b2016-01-20 11:17:23 -05002439bool ValidateBlitFramebufferANGLE(Context *context,
2440 GLint srcX0,
2441 GLint srcY0,
2442 GLint srcX1,
2443 GLint srcY1,
2444 GLint dstX0,
2445 GLint dstY0,
2446 GLint dstX1,
2447 GLint dstY1,
2448 GLbitfield mask,
2449 GLenum filter)
2450{
2451 if (!context->getExtensions().framebufferBlit)
2452 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002453 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002454 return false;
2455 }
2456
2457 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2458 {
2459 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002460 context->handleError(InvalidOperation() << "Scaling and flipping in "
2461 "BlitFramebufferANGLE not supported by this "
2462 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002463 return false;
2464 }
2465
2466 if (filter == GL_LINEAR)
2467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002468 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002469 return false;
2470 }
2471
Jamie Madill51f40ec2016-06-15 14:06:00 -04002472 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2473 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002474
2475 if (mask & GL_COLOR_BUFFER_BIT)
2476 {
2477 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2478 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2479
2480 if (readColorAttachment && drawColorAttachment)
2481 {
2482 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002483 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002484 readColorAttachment->type() != GL_RENDERBUFFER &&
2485 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2486 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002487 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002488 return false;
2489 }
2490
Geoff Langa15472a2015-08-11 11:48:03 -04002491 for (size_t drawbufferIdx = 0;
2492 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002493 {
Geoff Langa15472a2015-08-11 11:48:03 -04002494 const FramebufferAttachment *attachment =
2495 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2496 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002497 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002498 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002499 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002500 attachment->type() != GL_RENDERBUFFER &&
2501 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2502 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002503 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002504 return false;
2505 }
2506
2507 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002508 if (!Format::EquivalentForBlit(attachment->getFormat(),
2509 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002510 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002511 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002512 return false;
2513 }
2514 }
2515 }
2516
Jamie Madill427064d2018-04-13 16:20:34 -04002517 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002518 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002519 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2520 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2521 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002522 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002523 return false;
2524 }
2525 }
2526 }
2527
2528 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2529 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2530 for (size_t i = 0; i < 2; i++)
2531 {
2532 if (mask & masks[i])
2533 {
2534 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002535 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002536 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002537 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002538
2539 if (readBuffer && drawBuffer)
2540 {
2541 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2542 dstX0, dstY0, dstX1, dstY1))
2543 {
2544 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002545 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2546 "stencil blits are supported by "
2547 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002548 return false;
2549 }
2550
2551 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2552 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002553 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002554 return false;
2555 }
2556 }
2557 }
2558 }
2559
2560 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2561 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002562}
Jamie Madillc29968b2016-01-20 11:17:23 -05002563
Jamie Madill5b772312018-03-08 20:28:32 -05002564bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002565{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002566 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002567
Jamie Madill427064d2018-04-13 16:20:34 -04002568 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002569 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002570 return false;
2571 }
2572
2573 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2574 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002575 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002576 return false;
2577 }
2578
Geoff Lang76e65652017-03-27 14:58:02 -04002579 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2580 {
2581 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2582 GL_SIGNED_NORMALIZED};
2583
Corentin Wallez59c41592017-07-11 13:19:54 -04002584 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002585 drawBufferIdx++)
2586 {
2587 if (!ValidateWebGLFramebufferAttachmentClearType(
2588 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2589 {
2590 return false;
2591 }
2592 }
2593 }
2594
Jamie Madillc29968b2016-01-20 11:17:23 -05002595 return true;
2596}
2597
Jamie Madill5b772312018-03-08 20:28:32 -05002598bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002599{
2600 if (!context->getExtensions().drawBuffers)
2601 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002602 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002603 return false;
2604 }
2605
2606 return ValidateDrawBuffersBase(context, n, bufs);
2607}
2608
Jamie Madill73a84962016-02-12 09:27:23 -05002609bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002610 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002611 GLint level,
2612 GLint internalformat,
2613 GLsizei width,
2614 GLsizei height,
2615 GLint border,
2616 GLenum format,
2617 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002618 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002619{
Martin Radev1be913c2016-07-11 17:59:16 +03002620 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002621 {
2622 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002623 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002624 }
2625
Martin Radev1be913c2016-07-11 17:59:16 +03002626 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002627 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002628 0, 0, width, height, 1, border, format, type, -1,
2629 pixels);
2630}
2631
Brandon Jones416aaf92018-04-10 08:10:16 -07002632bool ValidateTexImage2DRobustANGLE(Context *context,
2633 TextureTarget target,
2634 GLint level,
2635 GLint internalformat,
2636 GLsizei width,
2637 GLsizei height,
2638 GLint border,
2639 GLenum format,
2640 GLenum type,
2641 GLsizei bufSize,
2642 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002643{
2644 if (!ValidateRobustEntryPoint(context, bufSize))
2645 {
2646 return false;
2647 }
2648
2649 if (context->getClientMajorVersion() < 3)
2650 {
2651 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2652 0, 0, width, height, border, format, type, bufSize,
2653 pixels);
2654 }
2655
2656 ASSERT(context->getClientMajorVersion() >= 3);
2657 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2658 0, 0, width, height, 1, border, format, type, bufSize,
2659 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002660}
2661
2662bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002663 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002664 GLint level,
2665 GLint xoffset,
2666 GLint yoffset,
2667 GLsizei width,
2668 GLsizei height,
2669 GLenum format,
2670 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002671 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002672{
2673
Martin Radev1be913c2016-07-11 17:59:16 +03002674 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002675 {
2676 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002677 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002678 }
2679
Martin Radev1be913c2016-07-11 17:59:16 +03002680 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002681 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002682 yoffset, 0, width, height, 1, 0, format, type, -1,
2683 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002684}
2685
Geoff Langc52f6f12016-10-14 10:18:00 -04002686bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002687 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002688 GLint level,
2689 GLint xoffset,
2690 GLint yoffset,
2691 GLsizei width,
2692 GLsizei height,
2693 GLenum format,
2694 GLenum type,
2695 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002696 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002697{
2698 if (!ValidateRobustEntryPoint(context, bufSize))
2699 {
2700 return false;
2701 }
2702
2703 if (context->getClientMajorVersion() < 3)
2704 {
2705 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2706 yoffset, width, height, 0, format, type, bufSize,
2707 pixels);
2708 }
2709
2710 ASSERT(context->getClientMajorVersion() >= 3);
2711 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2712 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2713 pixels);
2714}
2715
Jamie Madill73a84962016-02-12 09:27:23 -05002716bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002717 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002718 GLint level,
2719 GLenum internalformat,
2720 GLsizei width,
2721 GLsizei height,
2722 GLint border,
2723 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002724 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002725{
Martin Radev1be913c2016-07-11 17:59:16 +03002726 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002727 {
2728 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002729 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002730 {
2731 return false;
2732 }
2733 }
2734 else
2735 {
Martin Radev1be913c2016-07-11 17:59:16 +03002736 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002737 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002738 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002739 data))
2740 {
2741 return false;
2742 }
2743 }
2744
Geoff Langca271392017-04-05 12:30:00 -04002745 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002746 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002747 if (blockSizeOrErr.isError())
2748 {
2749 context->handleError(blockSizeOrErr.getError());
2750 return false;
2751 }
2752
2753 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002754 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002755 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002756 return false;
2757 }
2758
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002759 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002760 {
2761 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2762 return false;
2763 }
2764
Jamie Madill73a84962016-02-12 09:27:23 -05002765 return true;
2766}
2767
Corentin Wallezb2931602017-04-11 15:58:57 -04002768bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002769 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002770 GLint level,
2771 GLenum internalformat,
2772 GLsizei width,
2773 GLsizei height,
2774 GLint border,
2775 GLsizei imageSize,
2776 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002777 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002778{
2779 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2780 {
2781 return false;
2782 }
2783
2784 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2785 border, imageSize, data);
2786}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002787
Corentin Wallezb2931602017-04-11 15:58:57 -04002788bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002789 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002790 GLint level,
2791 GLint xoffset,
2792 GLint yoffset,
2793 GLsizei width,
2794 GLsizei height,
2795 GLenum format,
2796 GLsizei imageSize,
2797 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002798 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002799{
2800 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2801 {
2802 return false;
2803 }
2804
2805 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2806 format, imageSize, data);
2807}
2808
Jamie Madill73a84962016-02-12 09:27:23 -05002809bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002810 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002811 GLint level,
2812 GLint xoffset,
2813 GLint yoffset,
2814 GLsizei width,
2815 GLsizei height,
2816 GLenum format,
2817 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002818 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002819{
Martin Radev1be913c2016-07-11 17:59:16 +03002820 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002821 {
2822 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002823 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002824 {
2825 return false;
2826 }
2827 }
2828 else
2829 {
Martin Radev1be913c2016-07-11 17:59:16 +03002830 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002831 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002832 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002833 data))
2834 {
2835 return false;
2836 }
2837 }
2838
Geoff Langca271392017-04-05 12:30:00 -04002839 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002840 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002841 if (blockSizeOrErr.isError())
2842 {
2843 context->handleError(blockSizeOrErr.getError());
2844 return false;
2845 }
2846
2847 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002848 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002849 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002850 return false;
2851 }
2852
2853 return true;
2854}
2855
Corentin Wallez336129f2017-10-17 15:55:40 -04002856bool ValidateGetBufferPointervOES(Context *context,
2857 BufferBinding target,
2858 GLenum pname,
2859 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002860{
Geoff Lang496c02d2016-10-20 11:38:11 -07002861 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002862}
2863
Corentin Wallez336129f2017-10-17 15:55:40 -04002864bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002865{
2866 if (!context->getExtensions().mapBuffer)
2867 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002868 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002869 return false;
2870 }
2871
Corentin Walleze4477002017-12-01 14:39:58 -05002872 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002873 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002874 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002875 return false;
2876 }
2877
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002878 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002879
2880 if (buffer == nullptr)
2881 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002882 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002883 return false;
2884 }
2885
2886 if (access != GL_WRITE_ONLY_OES)
2887 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002888 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002889 return false;
2890 }
2891
2892 if (buffer->isMapped())
2893 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002894 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002895 return false;
2896 }
2897
Geoff Lang79f71042017-08-14 16:43:43 -04002898 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002899}
2900
Corentin Wallez336129f2017-10-17 15:55:40 -04002901bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002902{
2903 if (!context->getExtensions().mapBuffer)
2904 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002905 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002906 return false;
2907 }
2908
2909 return ValidateUnmapBufferBase(context, target);
2910}
2911
2912bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002913 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002914 GLintptr offset,
2915 GLsizeiptr length,
2916 GLbitfield access)
2917{
2918 if (!context->getExtensions().mapBufferRange)
2919 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002920 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002921 return false;
2922 }
2923
2924 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2925}
2926
Corentin Wallez336129f2017-10-17 15:55:40 -04002927bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002928{
2929 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2930 ASSERT(buffer != nullptr);
2931
2932 // Check if this buffer is currently being used as a transform feedback output buffer
2933 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2934 if (transformFeedback != nullptr && transformFeedback->isActive())
2935 {
2936 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2937 {
2938 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2939 if (transformFeedbackBuffer.get() == buffer)
2940 {
2941 context->handleError(InvalidOperation()
2942 << "Buffer is currently bound for transform feedback.");
2943 return false;
2944 }
2945 }
2946 }
2947
James Darpiniane8a93c62018-01-04 18:02:24 -08002948 if (context->getExtensions().webglCompatibility &&
2949 buffer->isBoundForTransformFeedbackAndOtherUse())
2950 {
2951 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2952 return false;
2953 }
2954
Geoff Lang79f71042017-08-14 16:43:43 -04002955 return true;
2956}
2957
Olli Etuaho4f667482016-03-30 15:56:35 +03002958bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002959 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002960 GLintptr offset,
2961 GLsizeiptr length)
2962{
2963 if (!context->getExtensions().mapBufferRange)
2964 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002965 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002966 return false;
2967 }
2968
2969 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2970}
2971
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002972bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002973{
2974 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002975 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002976 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002977 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002978 return false;
2979 }
2980
Geoff Langf41a7152016-09-19 15:11:17 -04002981 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2982 !context->isTextureGenerated(texture))
2983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002984 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002985 return false;
2986 }
2987
Ian Ewell54f87462016-03-10 13:47:21 -05002988 switch (target)
2989 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002990 case TextureType::_2D:
2991 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002992 break;
2993
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002994 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002995 if (!context->getExtensions().textureRectangle)
2996 {
2997 context->handleError(InvalidEnum()
2998 << "Context does not support GL_ANGLE_texture_rectangle");
2999 return false;
3000 }
3001 break;
3002
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003003 case TextureType::_3D:
3004 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03003005 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003006 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003007 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003008 return false;
3009 }
3010 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003011
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003012 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003013 if (context->getClientVersion() < Version(3, 1))
3014 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003015 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003016 return false;
3017 }
Geoff Lang3b573612016-10-31 14:08:10 -04003018 break;
3019
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003020 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003021 if (!context->getExtensions().eglImageExternal &&
3022 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003023 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003024 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003025 return false;
3026 }
3027 break;
3028 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003029 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003030 return false;
3031 }
3032
3033 return true;
3034}
3035
Geoff Langd8605522016-04-13 10:19:12 -04003036bool ValidateBindUniformLocationCHROMIUM(Context *context,
3037 GLuint program,
3038 GLint location,
3039 const GLchar *name)
3040{
3041 if (!context->getExtensions().bindUniformLocation)
3042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003043 context->handleError(InvalidOperation()
3044 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003045 return false;
3046 }
3047
3048 Program *programObject = GetValidProgram(context, program);
3049 if (!programObject)
3050 {
3051 return false;
3052 }
3053
3054 if (location < 0)
3055 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003056 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003057 return false;
3058 }
3059
3060 const Caps &caps = context->getCaps();
3061 if (static_cast<size_t>(location) >=
3062 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3063 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003064 context->handleError(InvalidValue() << "Location must be less than "
3065 "(MAX_VERTEX_UNIFORM_VECTORS + "
3066 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003067 return false;
3068 }
3069
Geoff Langfc32e8b2017-05-31 14:16:59 -04003070 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3071 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003072 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003073 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003074 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003075 return false;
3076 }
3077
Geoff Langd8605522016-04-13 10:19:12 -04003078 if (strncmp(name, "gl_", 3) == 0)
3079 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003080 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003081 return false;
3082 }
3083
3084 return true;
3085}
3086
Jamie Madille2e406c2016-06-02 13:04:10 -04003087bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003088{
3089 if (!context->getExtensions().framebufferMixedSamples)
3090 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003091 context->handleError(InvalidOperation()
3092 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003093 return false;
3094 }
3095 switch (components)
3096 {
3097 case GL_RGB:
3098 case GL_RGBA:
3099 case GL_ALPHA:
3100 case GL_NONE:
3101 break;
3102 default:
3103 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003104 InvalidEnum()
3105 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003106 return false;
3107 }
3108
3109 return true;
3110}
3111
Sami Väisänene45e53b2016-05-25 10:36:04 +03003112// CHROMIUM_path_rendering
3113
Jamie Madill007530e2017-12-28 14:27:04 -05003114bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003115{
Jamie Madill007530e2017-12-28 14:27:04 -05003116 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003117 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003118 return false;
3119 }
Jamie Madill007530e2017-12-28 14:27:04 -05003120
Sami Väisänene45e53b2016-05-25 10:36:04 +03003121 if (matrix == nullptr)
3122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003123 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003124 return false;
3125 }
Jamie Madill007530e2017-12-28 14:27:04 -05003126
Sami Väisänene45e53b2016-05-25 10:36:04 +03003127 return true;
3128}
3129
Jamie Madill007530e2017-12-28 14:27:04 -05003130bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003131{
Jamie Madill007530e2017-12-28 14:27:04 -05003132 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003133}
3134
Jamie Madill007530e2017-12-28 14:27:04 -05003135bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003136{
3137 if (!context->getExtensions().pathRendering)
3138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003139 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003140 return false;
3141 }
3142
3143 // range = 0 is undefined in NV_path_rendering.
3144 // we add stricter semantic check here and require a non zero positive range.
3145 if (range <= 0)
3146 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003147 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003148 return false;
3149 }
3150
3151 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3152 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003153 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003154 return false;
3155 }
3156
3157 return true;
3158}
3159
Jamie Madill007530e2017-12-28 14:27:04 -05003160bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003161{
3162 if (!context->getExtensions().pathRendering)
3163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003164 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003165 return false;
3166 }
3167
3168 // range = 0 is undefined in NV_path_rendering.
3169 // we add stricter semantic check here and require a non zero positive range.
3170 if (range <= 0)
3171 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003172 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003173 return false;
3174 }
3175
3176 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3177 checkedRange += range;
3178
3179 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3180 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003181 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003182 return false;
3183 }
3184 return true;
3185}
3186
Jamie Madill007530e2017-12-28 14:27:04 -05003187bool ValidatePathCommandsCHROMIUM(Context *context,
3188 GLuint path,
3189 GLsizei numCommands,
3190 const GLubyte *commands,
3191 GLsizei numCoords,
3192 GLenum coordType,
3193 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003194{
3195 if (!context->getExtensions().pathRendering)
3196 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003197 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003198 return false;
3199 }
Brandon Jones59770802018-04-02 13:18:42 -07003200 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003201 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003202 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003203 return false;
3204 }
3205
3206 if (numCommands < 0)
3207 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003208 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003209 return false;
3210 }
3211 else if (numCommands > 0)
3212 {
3213 if (!commands)
3214 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003215 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003216 return false;
3217 }
3218 }
3219
3220 if (numCoords < 0)
3221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003222 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003223 return false;
3224 }
3225 else if (numCoords > 0)
3226 {
3227 if (!coords)
3228 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003229 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003230 return false;
3231 }
3232 }
3233
3234 std::uint32_t coordTypeSize = 0;
3235 switch (coordType)
3236 {
3237 case GL_BYTE:
3238 coordTypeSize = sizeof(GLbyte);
3239 break;
3240
3241 case GL_UNSIGNED_BYTE:
3242 coordTypeSize = sizeof(GLubyte);
3243 break;
3244
3245 case GL_SHORT:
3246 coordTypeSize = sizeof(GLshort);
3247 break;
3248
3249 case GL_UNSIGNED_SHORT:
3250 coordTypeSize = sizeof(GLushort);
3251 break;
3252
3253 case GL_FLOAT:
3254 coordTypeSize = sizeof(GLfloat);
3255 break;
3256
3257 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003258 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003259 return false;
3260 }
3261
3262 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3263 checkedSize += (coordTypeSize * numCoords);
3264 if (!checkedSize.IsValid())
3265 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003266 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003267 return false;
3268 }
3269
3270 // early return skips command data validation when it doesn't exist.
3271 if (!commands)
3272 return true;
3273
3274 GLsizei expectedNumCoords = 0;
3275 for (GLsizei i = 0; i < numCommands; ++i)
3276 {
3277 switch (commands[i])
3278 {
3279 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3280 break;
3281 case GL_MOVE_TO_CHROMIUM:
3282 case GL_LINE_TO_CHROMIUM:
3283 expectedNumCoords += 2;
3284 break;
3285 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3286 expectedNumCoords += 4;
3287 break;
3288 case GL_CUBIC_CURVE_TO_CHROMIUM:
3289 expectedNumCoords += 6;
3290 break;
3291 case GL_CONIC_CURVE_TO_CHROMIUM:
3292 expectedNumCoords += 5;
3293 break;
3294 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003295 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003296 return false;
3297 }
3298 }
3299 if (expectedNumCoords != numCoords)
3300 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003301 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003302 return false;
3303 }
3304
3305 return true;
3306}
3307
Jamie Madill007530e2017-12-28 14:27:04 -05003308bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003309{
3310 if (!context->getExtensions().pathRendering)
3311 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003312 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003313 return false;
3314 }
Brandon Jones59770802018-04-02 13:18:42 -07003315 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003316 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003317 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003318 return false;
3319 }
3320
3321 switch (pname)
3322 {
3323 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3324 if (value < 0.0f)
3325 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003326 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003327 return false;
3328 }
3329 break;
3330 case GL_PATH_END_CAPS_CHROMIUM:
3331 switch (static_cast<GLenum>(value))
3332 {
3333 case GL_FLAT_CHROMIUM:
3334 case GL_SQUARE_CHROMIUM:
3335 case GL_ROUND_CHROMIUM:
3336 break;
3337 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003338 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003339 return false;
3340 }
3341 break;
3342 case GL_PATH_JOIN_STYLE_CHROMIUM:
3343 switch (static_cast<GLenum>(value))
3344 {
3345 case GL_MITER_REVERT_CHROMIUM:
3346 case GL_BEVEL_CHROMIUM:
3347 case GL_ROUND_CHROMIUM:
3348 break;
3349 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003350 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003351 return false;
3352 }
Nico Weber41b072b2018-02-09 10:01:32 -05003353 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003354 case GL_PATH_MITER_LIMIT_CHROMIUM:
3355 if (value < 0.0f)
3356 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003357 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003358 return false;
3359 }
3360 break;
3361
3362 case GL_PATH_STROKE_BOUND_CHROMIUM:
3363 // no errors, only clamping.
3364 break;
3365
3366 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003367 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003368 return false;
3369 }
3370 return true;
3371}
3372
Jamie Madill007530e2017-12-28 14:27:04 -05003373bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3374{
3375 // TODO(jmadill): Use proper clamping cast.
3376 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3377}
3378
3379bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003380{
3381 if (!context->getExtensions().pathRendering)
3382 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003383 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003384 return false;
3385 }
3386
Brandon Jones59770802018-04-02 13:18:42 -07003387 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003388 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003389 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003390 return false;
3391 }
3392 if (!value)
3393 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003394 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003395 return false;
3396 }
3397
3398 switch (pname)
3399 {
3400 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3401 case GL_PATH_END_CAPS_CHROMIUM:
3402 case GL_PATH_JOIN_STYLE_CHROMIUM:
3403 case GL_PATH_MITER_LIMIT_CHROMIUM:
3404 case GL_PATH_STROKE_BOUND_CHROMIUM:
3405 break;
3406
3407 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003408 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003409 return false;
3410 }
3411
3412 return true;
3413}
3414
Jamie Madill007530e2017-12-28 14:27:04 -05003415bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3416{
3417 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3418 reinterpret_cast<GLfloat *>(value));
3419}
3420
3421bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003422{
3423 if (!context->getExtensions().pathRendering)
3424 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003425 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003426 return false;
3427 }
3428
3429 switch (func)
3430 {
3431 case GL_NEVER:
3432 case GL_ALWAYS:
3433 case GL_LESS:
3434 case GL_LEQUAL:
3435 case GL_EQUAL:
3436 case GL_GEQUAL:
3437 case GL_GREATER:
3438 case GL_NOTEQUAL:
3439 break;
3440 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003441 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003442 return false;
3443 }
3444
3445 return true;
3446}
3447
3448// Note that the spec specifies that for the path drawing commands
3449// if the path object is not an existing path object the command
3450// does nothing and no error is generated.
3451// However if the path object exists but has not been specified any
3452// commands then an error is generated.
3453
Jamie Madill007530e2017-12-28 14:27:04 -05003454bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003455{
3456 if (!context->getExtensions().pathRendering)
3457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003458 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003459 return false;
3460 }
Brandon Jones59770802018-04-02 13:18:42 -07003461 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003462 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003463 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003464 return false;
3465 }
3466
3467 switch (fillMode)
3468 {
3469 case GL_COUNT_UP_CHROMIUM:
3470 case GL_COUNT_DOWN_CHROMIUM:
3471 break;
3472 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474 return false;
3475 }
3476
3477 if (!isPow2(mask + 1))
3478 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003479 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003480 return false;
3481 }
3482
3483 return true;
3484}
3485
Jamie Madill007530e2017-12-28 14:27:04 -05003486bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003487{
3488 if (!context->getExtensions().pathRendering)
3489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003490 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003491 return false;
3492 }
Brandon Jones59770802018-04-02 13:18:42 -07003493 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003494 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003495 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003496 return false;
3497 }
3498
3499 return true;
3500}
3501
Brandon Jonesd1049182018-03-28 10:02:20 -07003502bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3503{
3504 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3505}
3506
3507bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3508{
3509 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3510}
3511
Jamie Madill007530e2017-12-28 14:27:04 -05003512bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003513{
3514 if (!context->getExtensions().pathRendering)
3515 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003516 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003517 return false;
3518 }
Brandon Jones59770802018-04-02 13:18:42 -07003519 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003520 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003521 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003522 return false;
3523 }
3524
3525 switch (coverMode)
3526 {
3527 case GL_CONVEX_HULL_CHROMIUM:
3528 case GL_BOUNDING_BOX_CHROMIUM:
3529 break;
3530 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003531 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003532 return false;
3533 }
3534 return true;
3535}
3536
Jamie Madill007530e2017-12-28 14:27:04 -05003537bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3538 GLuint path,
3539 GLenum fillMode,
3540 GLuint mask,
3541 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542{
Jamie Madill007530e2017-12-28 14:27:04 -05003543 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3544 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003545}
3546
Jamie Madill007530e2017-12-28 14:27:04 -05003547bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3548 GLuint path,
3549 GLint reference,
3550 GLuint mask,
3551 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003552{
Jamie Madill007530e2017-12-28 14:27:04 -05003553 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3554 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003555}
3556
Brandon Jonesd1049182018-03-28 10:02:20 -07003557bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003558{
3559 if (!context->getExtensions().pathRendering)
3560 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003561 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003562 return false;
3563 }
3564 return true;
3565}
3566
Jamie Madill007530e2017-12-28 14:27:04 -05003567bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3568 GLsizei numPaths,
3569 GLenum pathNameType,
3570 const void *paths,
3571 GLuint pathBase,
3572 GLenum coverMode,
3573 GLenum transformType,
3574 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003575{
3576 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3577 transformType, transformValues))
3578 return false;
3579
3580 switch (coverMode)
3581 {
3582 case GL_CONVEX_HULL_CHROMIUM:
3583 case GL_BOUNDING_BOX_CHROMIUM:
3584 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3585 break;
3586 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003587 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003588 return false;
3589 }
3590
3591 return true;
3592}
3593
Jamie Madill007530e2017-12-28 14:27:04 -05003594bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3595 GLsizei numPaths,
3596 GLenum pathNameType,
3597 const void *paths,
3598 GLuint pathBase,
3599 GLenum coverMode,
3600 GLenum transformType,
3601 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003602{
3603 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3604 transformType, transformValues))
3605 return false;
3606
3607 switch (coverMode)
3608 {
3609 case GL_CONVEX_HULL_CHROMIUM:
3610 case GL_BOUNDING_BOX_CHROMIUM:
3611 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3612 break;
3613 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003614 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003615 return false;
3616 }
3617
3618 return true;
3619}
3620
Jamie Madill007530e2017-12-28 14:27:04 -05003621bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3622 GLsizei numPaths,
3623 GLenum pathNameType,
3624 const void *paths,
3625 GLuint pathBase,
3626 GLenum fillMode,
3627 GLuint mask,
3628 GLenum transformType,
3629 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003630{
3631
3632 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3633 transformType, transformValues))
3634 return false;
3635
3636 switch (fillMode)
3637 {
3638 case GL_COUNT_UP_CHROMIUM:
3639 case GL_COUNT_DOWN_CHROMIUM:
3640 break;
3641 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003642 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003643 return false;
3644 }
3645 if (!isPow2(mask + 1))
3646 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003647 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003648 return false;
3649 }
3650 return true;
3651}
3652
Jamie Madill007530e2017-12-28 14:27:04 -05003653bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3654 GLsizei numPaths,
3655 GLenum pathNameType,
3656 const void *paths,
3657 GLuint pathBase,
3658 GLint reference,
3659 GLuint mask,
3660 GLenum transformType,
3661 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003662{
3663 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3664 transformType, transformValues))
3665 return false;
3666
3667 // no more validation here.
3668
3669 return true;
3670}
3671
Jamie Madill007530e2017-12-28 14:27:04 -05003672bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3673 GLsizei numPaths,
3674 GLenum pathNameType,
3675 const void *paths,
3676 GLuint pathBase,
3677 GLenum fillMode,
3678 GLuint mask,
3679 GLenum coverMode,
3680 GLenum transformType,
3681 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003682{
3683 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3684 transformType, transformValues))
3685 return false;
3686
3687 switch (coverMode)
3688 {
3689 case GL_CONVEX_HULL_CHROMIUM:
3690 case GL_BOUNDING_BOX_CHROMIUM:
3691 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3692 break;
3693 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003694 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003695 return false;
3696 }
3697
3698 switch (fillMode)
3699 {
3700 case GL_COUNT_UP_CHROMIUM:
3701 case GL_COUNT_DOWN_CHROMIUM:
3702 break;
3703 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003704 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003705 return false;
3706 }
3707 if (!isPow2(mask + 1))
3708 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003709 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003710 return false;
3711 }
3712
3713 return true;
3714}
3715
Jamie Madill007530e2017-12-28 14:27:04 -05003716bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3717 GLsizei numPaths,
3718 GLenum pathNameType,
3719 const void *paths,
3720 GLuint pathBase,
3721 GLint reference,
3722 GLuint mask,
3723 GLenum coverMode,
3724 GLenum transformType,
3725 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003726{
3727 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3728 transformType, transformValues))
3729 return false;
3730
3731 switch (coverMode)
3732 {
3733 case GL_CONVEX_HULL_CHROMIUM:
3734 case GL_BOUNDING_BOX_CHROMIUM:
3735 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3736 break;
3737 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003738 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003739 return false;
3740 }
3741
3742 return true;
3743}
3744
Jamie Madill007530e2017-12-28 14:27:04 -05003745bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3746 GLuint program,
3747 GLint location,
3748 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003749{
3750 if (!context->getExtensions().pathRendering)
3751 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003752 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003753 return false;
3754 }
3755
3756 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3757 if (location >= MaxLocation)
3758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003759 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003760 return false;
3761 }
3762
3763 const auto *programObject = context->getProgram(program);
3764 if (!programObject)
3765 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003766 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003767 return false;
3768 }
3769
3770 if (!name)
3771 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003772 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003773 return false;
3774 }
3775
3776 if (angle::BeginsWith(name, "gl_"))
3777 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003778 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003779 return false;
3780 }
3781
3782 return true;
3783}
3784
Jamie Madill007530e2017-12-28 14:27:04 -05003785bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3786 GLuint program,
3787 GLint location,
3788 GLenum genMode,
3789 GLint components,
3790 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003791{
3792 if (!context->getExtensions().pathRendering)
3793 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003794 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003795 return false;
3796 }
3797
3798 const auto *programObject = context->getProgram(program);
3799 if (!programObject || programObject->isFlaggedForDeletion())
3800 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003801 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003802 return false;
3803 }
3804
3805 if (!programObject->isLinked())
3806 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003807 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003808 return false;
3809 }
3810
3811 switch (genMode)
3812 {
3813 case GL_NONE:
3814 if (components != 0)
3815 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003816 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003817 return false;
3818 }
3819 break;
3820
3821 case GL_OBJECT_LINEAR_CHROMIUM:
3822 case GL_EYE_LINEAR_CHROMIUM:
3823 case GL_CONSTANT_CHROMIUM:
3824 if (components < 1 || components > 4)
3825 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003826 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003827 return false;
3828 }
3829 if (!coeffs)
3830 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003831 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003832 return false;
3833 }
3834 break;
3835
3836 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003837 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003838 return false;
3839 }
3840
3841 // If the location is -1 then the command is silently ignored
3842 // and no further validation is needed.
3843 if (location == -1)
3844 return true;
3845
Jamie Madillbd044ed2017-06-05 12:59:21 -04003846 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003847
3848 if (!binding.valid)
3849 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003850 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003851 return false;
3852 }
3853
3854 if (binding.type != GL_NONE)
3855 {
3856 GLint expectedComponents = 0;
3857 switch (binding.type)
3858 {
3859 case GL_FLOAT:
3860 expectedComponents = 1;
3861 break;
3862 case GL_FLOAT_VEC2:
3863 expectedComponents = 2;
3864 break;
3865 case GL_FLOAT_VEC3:
3866 expectedComponents = 3;
3867 break;
3868 case GL_FLOAT_VEC4:
3869 expectedComponents = 4;
3870 break;
3871 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003872 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003873 InvalidOperation()
3874 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003875 return false;
3876 }
3877 if (expectedComponents != components && genMode != GL_NONE)
3878 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003879 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003880 return false;
3881 }
3882 }
3883 return true;
3884}
3885
Geoff Lang97073d12016-04-20 10:42:34 -07003886bool ValidateCopyTextureCHROMIUM(Context *context,
3887 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003888 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003889 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003890 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003891 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003892 GLint internalFormat,
3893 GLenum destType,
3894 GLboolean unpackFlipY,
3895 GLboolean unpackPremultiplyAlpha,
3896 GLboolean unpackUnmultiplyAlpha)
3897{
3898 if (!context->getExtensions().copyTexture)
3899 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003900 context->handleError(InvalidOperation()
3901 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003902 return false;
3903 }
3904
Geoff Lang4f0e0032017-05-01 16:04:35 -04003905 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003906 if (source == nullptr)
3907 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003908 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003909 return false;
3910 }
3911
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003912 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003913 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003914 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003915 return false;
3916 }
3917
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003918 TextureType sourceType = source->getType();
3919 ASSERT(sourceType != TextureType::CubeMap);
3920 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003921
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003922 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003923 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003924 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003925 return false;
3926 }
3927
Geoff Lang4f0e0032017-05-01 16:04:35 -04003928 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3929 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3930 if (sourceWidth == 0 || sourceHeight == 0)
3931 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003932 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003933 return false;
3934 }
3935
3936 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3937 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003938 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003939 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003940 return false;
3941 }
3942
Geoff Lang63458a32017-10-30 15:16:53 -04003943 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3944 {
3945 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3946 return false;
3947 }
3948
Geoff Lang4f0e0032017-05-01 16:04:35 -04003949 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003950 if (dest == nullptr)
3951 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003952 context->handleError(InvalidValue()
3953 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003954 return false;
3955 }
3956
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003957 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003958 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003959 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003960 return false;
3961 }
3962
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003963 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003964 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003965 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003966 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003967 return false;
3968 }
3969
Geoff Lang97073d12016-04-20 10:42:34 -07003970 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3971 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003972 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003973 return false;
3974 }
3975
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003976 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003977 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003978 context->handleError(
3979 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003980 return false;
3981 }
3982
Geoff Lang97073d12016-04-20 10:42:34 -07003983 if (dest->getImmutableFormat())
3984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003985 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003986 return false;
3987 }
3988
3989 return true;
3990}
3991
3992bool ValidateCopySubTextureCHROMIUM(Context *context,
3993 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003994 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003995 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003996 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003997 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003998 GLint xoffset,
3999 GLint yoffset,
4000 GLint x,
4001 GLint y,
4002 GLsizei width,
4003 GLsizei height,
4004 GLboolean unpackFlipY,
4005 GLboolean unpackPremultiplyAlpha,
4006 GLboolean unpackUnmultiplyAlpha)
4007{
4008 if (!context->getExtensions().copyTexture)
4009 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004010 context->handleError(InvalidOperation()
4011 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004012 return false;
4013 }
4014
Geoff Lang4f0e0032017-05-01 16:04:35 -04004015 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004016 if (source == nullptr)
4017 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004018 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004019 return false;
4020 }
4021
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004022 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004023 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004024 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004025 return false;
4026 }
4027
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004028 TextureType sourceType = source->getType();
4029 ASSERT(sourceType != TextureType::CubeMap);
4030 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004031
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004032 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004033 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004034 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004035 return false;
4036 }
4037
4038 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4039 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004040 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004041 context->handleError(InvalidValue()
4042 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004043 return false;
4044 }
4045
4046 if (x < 0 || y < 0)
4047 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004048 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004049 return false;
4050 }
4051
4052 if (width < 0 || height < 0)
4053 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004054 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004055 return false;
4056 }
4057
Geoff Lang4f0e0032017-05-01 16:04:35 -04004058 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4059 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004060 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004061 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004062 return false;
4063 }
4064
Geoff Lang4f0e0032017-05-01 16:04:35 -04004065 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4066 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004067 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004068 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004069 return false;
4070 }
4071
Geoff Lang63458a32017-10-30 15:16:53 -04004072 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4073 {
4074 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4075 return false;
4076 }
4077
Geoff Lang4f0e0032017-05-01 16:04:35 -04004078 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004079 if (dest == nullptr)
4080 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004081 context->handleError(InvalidValue()
4082 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004083 return false;
4084 }
4085
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004086 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004087 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004088 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004089 return false;
4090 }
4091
Brandon Jones28783792018-03-05 09:37:32 -08004092 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4093 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004094 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004095 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004096 return false;
4097 }
4098
Geoff Lang4f0e0032017-05-01 16:04:35 -04004099 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4100 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004101 context
4102 ->handleError(InvalidOperation()
4103 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004104 return false;
4105 }
4106
4107 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4108 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004109 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004110 context->handleError(InvalidOperation()
4111 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004112 return false;
4113 }
4114
4115 if (xoffset < 0 || yoffset < 0)
4116 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004117 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004118 return false;
4119 }
4120
Geoff Lang4f0e0032017-05-01 16:04:35 -04004121 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4122 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004124 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004125 return false;
4126 }
4127
4128 return true;
4129}
4130
Geoff Lang47110bf2016-04-20 11:13:22 -07004131bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4132{
4133 if (!context->getExtensions().copyCompressedTexture)
4134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004135 context->handleError(InvalidOperation()
4136 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004137 return false;
4138 }
4139
4140 const gl::Texture *source = context->getTexture(sourceId);
4141 if (source == nullptr)
4142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004143 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004144 return false;
4145 }
4146
Corentin Wallez99d492c2018-02-27 15:17:10 -05004147 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004148 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004149 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004150 return false;
4151 }
4152
Corentin Wallez99d492c2018-02-27 15:17:10 -05004153 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4154 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004155 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004156 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004157 return false;
4158 }
4159
Corentin Wallez99d492c2018-02-27 15:17:10 -05004160 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004161 if (!sourceFormat.info->compressed)
4162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004163 context->handleError(InvalidOperation()
4164 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004165 return false;
4166 }
4167
4168 const gl::Texture *dest = context->getTexture(destId);
4169 if (dest == nullptr)
4170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004171 context->handleError(InvalidValue()
4172 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004173 return false;
4174 }
4175
Corentin Wallez99d492c2018-02-27 15:17:10 -05004176 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004177 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004178 context->handleError(InvalidValue()
4179 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004180 return false;
4181 }
4182
4183 if (dest->getImmutableFormat())
4184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004185 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004186 return false;
4187 }
4188
4189 return true;
4190}
4191
Jiawei Shao385b3e02018-03-21 09:43:28 +08004192bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004193{
4194 switch (type)
4195 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004196 case ShaderType::Vertex:
4197 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004198 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004199
Jiawei Shao385b3e02018-03-21 09:43:28 +08004200 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004201 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004202 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004203 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004204 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004205 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004206 break;
4207
Jiawei Shao385b3e02018-03-21 09:43:28 +08004208 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004209 if (!context->getExtensions().geometryShader)
4210 {
4211 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4212 return false;
4213 }
4214 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004215 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004216 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004217 return false;
4218 }
Jamie Madill29639852016-09-02 15:00:09 -04004219
4220 return true;
4221}
4222
Jamie Madill5b772312018-03-08 20:28:32 -05004223bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004224 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004225 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004226 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004227 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004228{
4229 if (size < 0)
4230 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004231 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004232 return false;
4233 }
4234
4235 switch (usage)
4236 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004237 case BufferUsage::StreamDraw:
4238 case BufferUsage::StaticDraw:
4239 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004240 break;
4241
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004242 case BufferUsage::StreamRead:
4243 case BufferUsage::StaticRead:
4244 case BufferUsage::DynamicRead:
4245 case BufferUsage::StreamCopy:
4246 case BufferUsage::StaticCopy:
4247 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004248 if (context->getClientMajorVersion() < 3)
4249 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004250 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004251 return false;
4252 }
4253 break;
4254
4255 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004256 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004257 return false;
4258 }
4259
Corentin Walleze4477002017-12-01 14:39:58 -05004260 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004261 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004262 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004263 return false;
4264 }
4265
4266 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4267
4268 if (!buffer)
4269 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004270 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004271 return false;
4272 }
4273
James Darpiniane8a93c62018-01-04 18:02:24 -08004274 if (context->getExtensions().webglCompatibility &&
4275 buffer->isBoundForTransformFeedbackAndOtherUse())
4276 {
4277 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4278 return false;
4279 }
4280
Jamie Madill29639852016-09-02 15:00:09 -04004281 return true;
4282}
4283
Jamie Madill5b772312018-03-08 20:28:32 -05004284bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004285 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004286 GLintptr offset,
4287 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004288 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004289{
Brandon Jones6cad5662017-06-14 13:25:13 -07004290 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004291 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004292 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4293 return false;
4294 }
4295
4296 if (offset < 0)
4297 {
4298 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004299 return false;
4300 }
4301
Corentin Walleze4477002017-12-01 14:39:58 -05004302 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004303 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004304 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004305 return false;
4306 }
4307
4308 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4309
4310 if (!buffer)
4311 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004312 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004313 return false;
4314 }
4315
4316 if (buffer->isMapped())
4317 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004318 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004319 return false;
4320 }
4321
James Darpiniane8a93c62018-01-04 18:02:24 -08004322 if (context->getExtensions().webglCompatibility &&
4323 buffer->isBoundForTransformFeedbackAndOtherUse())
4324 {
4325 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4326 return false;
4327 }
4328
Jamie Madill29639852016-09-02 15:00:09 -04004329 // Check for possible overflow of size + offset
4330 angle::CheckedNumeric<size_t> checkedSize(size);
4331 checkedSize += offset;
4332 if (!checkedSize.IsValid())
4333 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004334 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004335 return false;
4336 }
4337
4338 if (size + offset > buffer->getSize())
4339 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004340 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004341 return false;
4342 }
4343
Martin Radev4c4c8e72016-08-04 12:25:34 +03004344 return true;
4345}
4346
Geoff Lang111a99e2017-10-17 10:58:41 -04004347bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004348{
Geoff Langc339c4e2016-11-29 10:37:36 -05004349 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004350 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004351 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004352 return false;
4353 }
4354
Geoff Lang111a99e2017-10-17 10:58:41 -04004355 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004356 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004357 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004358 return false;
4359 }
4360
4361 return true;
4362}
4363
Jamie Madill5b772312018-03-08 20:28:32 -05004364bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004365{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004366 if (context->getClientMajorVersion() < 2)
4367 {
4368 return ValidateMultitextureUnit(context, texture);
4369 }
4370
Jamie Madillef300b12016-10-07 15:12:09 -04004371 if (texture < GL_TEXTURE0 ||
4372 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4373 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004374 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004375 return false;
4376 }
4377
4378 return true;
4379}
4380
Jamie Madill5b772312018-03-08 20:28:32 -05004381bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004382{
4383 Program *programObject = GetValidProgram(context, program);
4384 if (!programObject)
4385 {
4386 return false;
4387 }
4388
4389 Shader *shaderObject = GetValidShader(context, shader);
4390 if (!shaderObject)
4391 {
4392 return false;
4393 }
4394
Jiawei Shao385b3e02018-03-21 09:43:28 +08004395 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004396 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004397 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4398 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004399 }
4400
4401 return true;
4402}
4403
Jamie Madill5b772312018-03-08 20:28:32 -05004404bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004405{
4406 if (index >= MAX_VERTEX_ATTRIBS)
4407 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004408 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004409 return false;
4410 }
4411
4412 if (strncmp(name, "gl_", 3) == 0)
4413 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004414 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004415 return false;
4416 }
4417
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004418 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004419 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004420 const size_t length = strlen(name);
4421
4422 if (!IsValidESSLString(name, length))
4423 {
4424 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4425 // for shader-related entry points
4426 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4427 return false;
4428 }
4429
4430 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4431 {
4432 return false;
4433 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004434 }
4435
Jamie Madill01a80ee2016-11-07 12:06:18 -05004436 return GetValidProgram(context, program) != nullptr;
4437}
4438
Jamie Madill5b772312018-03-08 20:28:32 -05004439bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004440{
Corentin Walleze4477002017-12-01 14:39:58 -05004441 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004442 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004443 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444 return false;
4445 }
4446
4447 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4448 !context->isBufferGenerated(buffer))
4449 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004450 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004451 return false;
4452 }
4453
4454 return true;
4455}
4456
Jamie Madill5b772312018-03-08 20:28:32 -05004457bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004458{
Geoff Lange8afa902017-09-27 15:00:43 -04004459 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004460 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004461 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004462 return false;
4463 }
4464
4465 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4466 !context->isFramebufferGenerated(framebuffer))
4467 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004468 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004469 return false;
4470 }
4471
4472 return true;
4473}
4474
Jamie Madill5b772312018-03-08 20:28:32 -05004475bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004476{
4477 if (target != GL_RENDERBUFFER)
4478 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004479 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004480 return false;
4481 }
4482
4483 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4484 !context->isRenderbufferGenerated(renderbuffer))
4485 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004486 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004487 return false;
4488 }
4489
4490 return true;
4491}
4492
Jamie Madill5b772312018-03-08 20:28:32 -05004493static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004494{
4495 switch (mode)
4496 {
4497 case GL_FUNC_ADD:
4498 case GL_FUNC_SUBTRACT:
4499 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004500 return true;
4501
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004502 case GL_MIN:
4503 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004504 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004505
4506 default:
4507 return false;
4508 }
4509}
4510
Jamie Madill5b772312018-03-08 20:28:32 -05004511bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004512{
4513 return true;
4514}
4515
Jamie Madill5b772312018-03-08 20:28:32 -05004516bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004517{
Geoff Lang50cac572017-09-26 17:37:43 -04004518 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004519 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004520 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004521 return false;
4522 }
4523
4524 return true;
4525}
4526
Jamie Madill5b772312018-03-08 20:28:32 -05004527bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004528{
Geoff Lang50cac572017-09-26 17:37:43 -04004529 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004530 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004531 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004532 return false;
4533 }
4534
Geoff Lang50cac572017-09-26 17:37:43 -04004535 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004537 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004538 return false;
4539 }
4540
4541 return true;
4542}
4543
Jamie Madill5b772312018-03-08 20:28:32 -05004544bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004545{
4546 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4547}
4548
4549static bool ValidSrcBlendFunc(GLenum srcBlend)
4550{
4551 switch (srcBlend)
4552 {
4553 case GL_ZERO:
4554 case GL_ONE:
4555 case GL_SRC_COLOR:
4556 case GL_ONE_MINUS_SRC_COLOR:
4557 case GL_DST_COLOR:
4558 case GL_ONE_MINUS_DST_COLOR:
4559 case GL_SRC_ALPHA:
4560 case GL_ONE_MINUS_SRC_ALPHA:
4561 case GL_DST_ALPHA:
4562 case GL_ONE_MINUS_DST_ALPHA:
4563 case GL_CONSTANT_COLOR:
4564 case GL_ONE_MINUS_CONSTANT_COLOR:
4565 case GL_CONSTANT_ALPHA:
4566 case GL_ONE_MINUS_CONSTANT_ALPHA:
4567 case GL_SRC_ALPHA_SATURATE:
4568 return true;
4569
4570 default:
4571 return false;
4572 }
4573}
4574
4575static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4576{
4577 switch (dstBlend)
4578 {
4579 case GL_ZERO:
4580 case GL_ONE:
4581 case GL_SRC_COLOR:
4582 case GL_ONE_MINUS_SRC_COLOR:
4583 case GL_DST_COLOR:
4584 case GL_ONE_MINUS_DST_COLOR:
4585 case GL_SRC_ALPHA:
4586 case GL_ONE_MINUS_SRC_ALPHA:
4587 case GL_DST_ALPHA:
4588 case GL_ONE_MINUS_DST_ALPHA:
4589 case GL_CONSTANT_COLOR:
4590 case GL_ONE_MINUS_CONSTANT_COLOR:
4591 case GL_CONSTANT_ALPHA:
4592 case GL_ONE_MINUS_CONSTANT_ALPHA:
4593 return true;
4594
4595 case GL_SRC_ALPHA_SATURATE:
4596 return (contextMajorVersion >= 3);
4597
4598 default:
4599 return false;
4600 }
4601}
4602
Jamie Madill5b772312018-03-08 20:28:32 -05004603bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004604 GLenum srcRGB,
4605 GLenum dstRGB,
4606 GLenum srcAlpha,
4607 GLenum dstAlpha)
4608{
4609 if (!ValidSrcBlendFunc(srcRGB))
4610 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004611 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004612 return false;
4613 }
4614
4615 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4616 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004617 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004618 return false;
4619 }
4620
4621 if (!ValidSrcBlendFunc(srcAlpha))
4622 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004623 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004624 return false;
4625 }
4626
4627 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4628 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004629 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004630 return false;
4631 }
4632
Frank Henigman146e8a12017-03-02 23:22:37 -05004633 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4634 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004635 {
4636 bool constantColorUsed =
4637 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4638 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4639
4640 bool constantAlphaUsed =
4641 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4642 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4643
4644 if (constantColorUsed && constantAlphaUsed)
4645 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004646 const char *msg;
4647 if (context->getExtensions().webglCompatibility)
4648 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004649 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004650 }
4651 else
4652 {
4653 msg =
4654 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4655 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4656 "implementation.";
4657 ERR() << msg;
4658 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004659 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004660 return false;
4661 }
4662 }
4663
4664 return true;
4665}
4666
Geoff Langc339c4e2016-11-29 10:37:36 -05004667bool ValidateGetString(Context *context, GLenum name)
4668{
4669 switch (name)
4670 {
4671 case GL_VENDOR:
4672 case GL_RENDERER:
4673 case GL_VERSION:
4674 case GL_SHADING_LANGUAGE_VERSION:
4675 case GL_EXTENSIONS:
4676 break;
4677
4678 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4679 if (!context->getExtensions().requestExtension)
4680 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004682 return false;
4683 }
4684 break;
4685
4686 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004687 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004688 return false;
4689 }
4690
4691 return true;
4692}
4693
Jamie Madill5b772312018-03-08 20:28:32 -05004694bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004695{
4696 if (width <= 0.0f || isNaN(width))
4697 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004698 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004699 return false;
4700 }
4701
4702 return true;
4703}
4704
Jamie Madill5b772312018-03-08 20:28:32 -05004705bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004706 GLuint index,
4707 GLint size,
4708 GLenum type,
4709 GLboolean normalized,
4710 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004711 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004712{
Shao80957d92017-02-20 21:25:59 +08004713 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004714 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004715 return false;
4716 }
4717
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004718 if (stride < 0)
4719 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004720 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004721 return false;
4722 }
4723
Shao80957d92017-02-20 21:25:59 +08004724 const Caps &caps = context->getCaps();
4725 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004726 {
Shao80957d92017-02-20 21:25:59 +08004727 if (stride > caps.maxVertexAttribStride)
4728 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004729 context->handleError(InvalidValue()
4730 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004731 return false;
4732 }
4733
4734 if (index >= caps.maxVertexAttribBindings)
4735 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004736 context->handleError(InvalidValue()
4737 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004738 return false;
4739 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004740 }
4741
4742 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4743 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4744 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4745 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004746 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4747 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004748 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4749 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004751 context
4752 ->handleError(InvalidOperation()
4753 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004754 return false;
4755 }
4756
4757 if (context->getExtensions().webglCompatibility)
4758 {
4759 // WebGL 1.0 [Section 6.14] Fixed point support
4760 // The WebGL API does not support the GL_FIXED data type.
4761 if (type == GL_FIXED)
4762 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004763 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004764 return false;
4765 }
4766
Geoff Lang2d62ab72017-03-23 16:54:40 -04004767 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004768 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004769 return false;
4770 }
4771 }
4772
4773 return true;
4774}
4775
Jamie Madill5b772312018-03-08 20:28:32 -05004776bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004777{
4778 if (context->getExtensions().webglCompatibility && zNear > zFar)
4779 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004780 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004781 return false;
4782 }
4783
4784 return true;
4785}
4786
Jamie Madill5b772312018-03-08 20:28:32 -05004787bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004788 GLenum target,
4789 GLenum internalformat,
4790 GLsizei width,
4791 GLsizei height)
4792{
4793 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4794 height);
4795}
4796
Jamie Madill5b772312018-03-08 20:28:32 -05004797bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004798 GLenum target,
4799 GLsizei samples,
4800 GLenum internalformat,
4801 GLsizei width,
4802 GLsizei height)
4803{
4804 if (!context->getExtensions().framebufferMultisample)
4805 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004806 context->handleError(InvalidOperation()
4807 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004808 return false;
4809 }
4810
4811 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4812 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4813 // generated.
4814 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4815 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004816 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004817 return false;
4818 }
4819
4820 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4821 // the specified storage. This is different than ES 3.0 in which a sample number higher
4822 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4823 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4824 if (context->getClientMajorVersion() >= 3)
4825 {
4826 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4827 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4828 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004829 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004830 return false;
4831 }
4832 }
4833
4834 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4835 width, height);
4836}
4837
Jamie Madill5b772312018-03-08 20:28:32 -05004838bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004839{
Geoff Lange8afa902017-09-27 15:00:43 -04004840 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004841 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004842 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004843 return false;
4844 }
4845
4846 return true;
4847}
4848
Jamie Madill5b772312018-03-08 20:28:32 -05004849bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004850{
4851 return true;
4852}
4853
Jamie Madill5b772312018-03-08 20:28:32 -05004854bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004855{
4856 return true;
4857}
4858
Jamie Madill5b772312018-03-08 20:28:32 -05004859bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004860{
4861 return true;
4862}
4863
Jamie Madill5b772312018-03-08 20:28:32 -05004864bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004865 GLboolean red,
4866 GLboolean green,
4867 GLboolean blue,
4868 GLboolean alpha)
4869{
4870 return true;
4871}
4872
Jamie Madill5b772312018-03-08 20:28:32 -05004873bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004874{
4875 return true;
4876}
4877
Jamie Madill5b772312018-03-08 20:28:32 -05004878bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004879{
4880 return true;
4881}
4882
Jamie Madill5b772312018-03-08 20:28:32 -05004883bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004884{
4885 switch (mode)
4886 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004887 case CullFaceMode::Front:
4888 case CullFaceMode::Back:
4889 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004890 break;
4891
4892 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004893 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894 return false;
4895 }
4896
4897 return true;
4898}
4899
Jamie Madill5b772312018-03-08 20:28:32 -05004900bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004901{
4902 if (program == 0)
4903 {
4904 return false;
4905 }
4906
4907 if (!context->getProgram(program))
4908 {
4909 if (context->getShader(program))
4910 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004911 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004912 return false;
4913 }
4914 else
4915 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004916 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004917 return false;
4918 }
4919 }
4920
4921 return true;
4922}
4923
Jamie Madill5b772312018-03-08 20:28:32 -05004924bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004925{
4926 if (shader == 0)
4927 {
4928 return false;
4929 }
4930
4931 if (!context->getShader(shader))
4932 {
4933 if (context->getProgram(shader))
4934 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004935 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004936 return false;
4937 }
4938 else
4939 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004940 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004941 return false;
4942 }
4943 }
4944
4945 return true;
4946}
4947
Jamie Madill5b772312018-03-08 20:28:32 -05004948bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004949{
4950 switch (func)
4951 {
4952 case GL_NEVER:
4953 case GL_ALWAYS:
4954 case GL_LESS:
4955 case GL_LEQUAL:
4956 case GL_EQUAL:
4957 case GL_GREATER:
4958 case GL_GEQUAL:
4959 case GL_NOTEQUAL:
4960 break;
4961
4962 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004963 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004964 return false;
4965 }
4966
4967 return true;
4968}
4969
Jamie Madill5b772312018-03-08 20:28:32 -05004970bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004971{
4972 return true;
4973}
4974
Jamie Madill5b772312018-03-08 20:28:32 -05004975bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004976{
4977 Program *programObject = GetValidProgram(context, program);
4978 if (!programObject)
4979 {
4980 return false;
4981 }
4982
4983 Shader *shaderObject = GetValidShader(context, shader);
4984 if (!shaderObject)
4985 {
4986 return false;
4987 }
4988
Jiawei Shao385b3e02018-03-21 09:43:28 +08004989 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004990 if (attachedShader != shaderObject)
4991 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004992 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004993 return false;
4994 }
4995
4996 return true;
4997}
4998
Jamie Madill5b772312018-03-08 20:28:32 -05004999bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005000{
5001 if (index >= MAX_VERTEX_ATTRIBS)
5002 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005003 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005004 return false;
5005 }
5006
5007 return true;
5008}
5009
Jamie Madill5b772312018-03-08 20:28:32 -05005010bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005011{
5012 if (index >= MAX_VERTEX_ATTRIBS)
5013 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005014 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005015 return false;
5016 }
5017
5018 return true;
5019}
5020
Jamie Madill5b772312018-03-08 20:28:32 -05005021bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005022{
5023 return true;
5024}
5025
Jamie Madill5b772312018-03-08 20:28:32 -05005026bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005027{
5028 return true;
5029}
5030
Jamie Madill5b772312018-03-08 20:28:32 -05005031bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005032{
5033 switch (mode)
5034 {
5035 case GL_CW:
5036 case GL_CCW:
5037 break;
5038 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005039 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005040 return false;
5041 }
5042
5043 return true;
5044}
5045
Jamie Madill5b772312018-03-08 20:28:32 -05005046bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005047 GLuint program,
5048 GLuint index,
5049 GLsizei bufsize,
5050 GLsizei *length,
5051 GLint *size,
5052 GLenum *type,
5053 GLchar *name)
5054{
5055 if (bufsize < 0)
5056 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005057 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005058 return false;
5059 }
5060
5061 Program *programObject = GetValidProgram(context, program);
5062
5063 if (!programObject)
5064 {
5065 return false;
5066 }
5067
5068 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5069 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005070 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005071 return false;
5072 }
5073
5074 return true;
5075}
5076
Jamie Madill5b772312018-03-08 20:28:32 -05005077bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005078 GLuint program,
5079 GLuint index,
5080 GLsizei bufsize,
5081 GLsizei *length,
5082 GLint *size,
5083 GLenum *type,
5084 GLchar *name)
5085{
5086 if (bufsize < 0)
5087 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005088 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005089 return false;
5090 }
5091
5092 Program *programObject = GetValidProgram(context, program);
5093
5094 if (!programObject)
5095 {
5096 return false;
5097 }
5098
5099 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5100 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005101 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005102 return false;
5103 }
5104
5105 return true;
5106}
5107
Jamie Madill5b772312018-03-08 20:28:32 -05005108bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005109 GLuint program,
5110 GLsizei maxcount,
5111 GLsizei *count,
5112 GLuint *shaders)
5113{
5114 if (maxcount < 0)
5115 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005116 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005117 return false;
5118 }
5119
5120 Program *programObject = GetValidProgram(context, program);
5121
5122 if (!programObject)
5123 {
5124 return false;
5125 }
5126
5127 return true;
5128}
5129
Jamie Madill5b772312018-03-08 20:28:32 -05005130bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005131{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005132 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5133 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005134 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005135 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005136 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005137 return false;
5138 }
5139
Jamie Madillc1d770e2017-04-13 17:31:24 -04005140 Program *programObject = GetValidProgram(context, program);
5141
5142 if (!programObject)
5143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005145 return false;
5146 }
5147
5148 if (!programObject->isLinked())
5149 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005150 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005151 return false;
5152 }
5153
5154 return true;
5155}
5156
Jamie Madill5b772312018-03-08 20:28:32 -05005157bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005158{
5159 GLenum nativeType;
5160 unsigned int numParams = 0;
5161 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5162}
5163
Jamie Madill5b772312018-03-08 20:28:32 -05005164bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005165{
5166 return true;
5167}
5168
Jamie Madill5b772312018-03-08 20:28:32 -05005169bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005170{
5171 GLenum nativeType;
5172 unsigned int numParams = 0;
5173 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5174}
5175
Jamie Madill5b772312018-03-08 20:28:32 -05005176bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005177{
5178 GLenum nativeType;
5179 unsigned int numParams = 0;
5180 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5181}
5182
Jamie Madill5b772312018-03-08 20:28:32 -05005183bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005184 GLuint program,
5185 GLsizei bufsize,
5186 GLsizei *length,
5187 GLchar *infolog)
5188{
5189 if (bufsize < 0)
5190 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005191 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005192 return false;
5193 }
5194
5195 Program *programObject = GetValidProgram(context, program);
5196 if (!programObject)
5197 {
5198 return false;
5199 }
5200
5201 return true;
5202}
5203
Jamie Madill5b772312018-03-08 20:28:32 -05005204bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005205 GLuint shader,
5206 GLsizei bufsize,
5207 GLsizei *length,
5208 GLchar *infolog)
5209{
5210 if (bufsize < 0)
5211 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005212 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 return false;
5214 }
5215
5216 Shader *shaderObject = GetValidShader(context, shader);
5217 if (!shaderObject)
5218 {
5219 return false;
5220 }
5221
5222 return true;
5223}
5224
Jamie Madill5b772312018-03-08 20:28:32 -05005225bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005226 GLenum shadertype,
5227 GLenum precisiontype,
5228 GLint *range,
5229 GLint *precision)
5230{
5231 switch (shadertype)
5232 {
5233 case GL_VERTEX_SHADER:
5234 case GL_FRAGMENT_SHADER:
5235 break;
5236 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005237 context->handleError(InvalidOperation()
5238 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005239 return false;
5240 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005241 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005242 return false;
5243 }
5244
5245 switch (precisiontype)
5246 {
5247 case GL_LOW_FLOAT:
5248 case GL_MEDIUM_FLOAT:
5249 case GL_HIGH_FLOAT:
5250 case GL_LOW_INT:
5251 case GL_MEDIUM_INT:
5252 case GL_HIGH_INT:
5253 break;
5254
5255 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005256 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005257 return false;
5258 }
5259
5260 return true;
5261}
5262
Jamie Madill5b772312018-03-08 20:28:32 -05005263bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005264 GLuint shader,
5265 GLsizei bufsize,
5266 GLsizei *length,
5267 GLchar *source)
5268{
5269 if (bufsize < 0)
5270 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005271 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005272 return false;
5273 }
5274
5275 Shader *shaderObject = GetValidShader(context, shader);
5276 if (!shaderObject)
5277 {
5278 return false;
5279 }
5280
5281 return true;
5282}
5283
Jamie Madill5b772312018-03-08 20:28:32 -05005284bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005285{
5286 if (strstr(name, "gl_") == name)
5287 {
5288 return false;
5289 }
5290
Geoff Langfc32e8b2017-05-31 14:16:59 -04005291 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5292 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005293 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005294 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005295 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005296 return false;
5297 }
5298
Jamie Madillc1d770e2017-04-13 17:31:24 -04005299 Program *programObject = GetValidProgram(context, program);
5300
5301 if (!programObject)
5302 {
5303 return false;
5304 }
5305
5306 if (!programObject->isLinked())
5307 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005308 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005309 return false;
5310 }
5311
5312 return true;
5313}
5314
Jamie Madill5b772312018-03-08 20:28:32 -05005315bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005316{
5317 switch (mode)
5318 {
5319 case GL_FASTEST:
5320 case GL_NICEST:
5321 case GL_DONT_CARE:
5322 break;
5323
5324 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005325 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005326 return false;
5327 }
5328
5329 switch (target)
5330 {
5331 case GL_GENERATE_MIPMAP_HINT:
5332 break;
5333
Geoff Lange7bd2182017-06-16 16:13:13 -04005334 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5335 if (context->getClientVersion() < ES_3_0 &&
5336 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005337 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005338 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005339 return false;
5340 }
5341 break;
5342
5343 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005344 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345 return false;
5346 }
5347
5348 return true;
5349}
5350
Jamie Madill5b772312018-03-08 20:28:32 -05005351bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005352{
5353 return true;
5354}
5355
Jamie Madill5b772312018-03-08 20:28:32 -05005356bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005357{
5358 return true;
5359}
5360
Jamie Madill5b772312018-03-08 20:28:32 -05005361bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005362{
5363 return true;
5364}
5365
Jamie Madill5b772312018-03-08 20:28:32 -05005366bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005367{
5368 return true;
5369}
5370
Jamie Madill5b772312018-03-08 20:28:32 -05005371bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005372{
5373 return true;
5374}
5375
Jamie Madill5b772312018-03-08 20:28:32 -05005376bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005377{
5378 return true;
5379}
5380
Jamie Madill5b772312018-03-08 20:28:32 -05005381bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005382{
5383 if (context->getClientMajorVersion() < 3)
5384 {
5385 switch (pname)
5386 {
5387 case GL_UNPACK_IMAGE_HEIGHT:
5388 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005389 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005390 return false;
5391
5392 case GL_UNPACK_ROW_LENGTH:
5393 case GL_UNPACK_SKIP_ROWS:
5394 case GL_UNPACK_SKIP_PIXELS:
5395 if (!context->getExtensions().unpackSubimage)
5396 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005397 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005398 return false;
5399 }
5400 break;
5401
5402 case GL_PACK_ROW_LENGTH:
5403 case GL_PACK_SKIP_ROWS:
5404 case GL_PACK_SKIP_PIXELS:
5405 if (!context->getExtensions().packSubimage)
5406 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005407 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005408 return false;
5409 }
5410 break;
5411 }
5412 }
5413
5414 if (param < 0)
5415 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005416 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005417 return false;
5418 }
5419
5420 switch (pname)
5421 {
5422 case GL_UNPACK_ALIGNMENT:
5423 if (param != 1 && param != 2 && param != 4 && param != 8)
5424 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005425 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005426 return false;
5427 }
5428 break;
5429
5430 case GL_PACK_ALIGNMENT:
5431 if (param != 1 && param != 2 && param != 4 && param != 8)
5432 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005433 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005434 return false;
5435 }
5436 break;
5437
5438 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005439 if (!context->getExtensions().packReverseRowOrder)
5440 {
5441 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5442 }
5443 break;
5444
Jamie Madillc1d770e2017-04-13 17:31:24 -04005445 case GL_UNPACK_ROW_LENGTH:
5446 case GL_UNPACK_IMAGE_HEIGHT:
5447 case GL_UNPACK_SKIP_IMAGES:
5448 case GL_UNPACK_SKIP_ROWS:
5449 case GL_UNPACK_SKIP_PIXELS:
5450 case GL_PACK_ROW_LENGTH:
5451 case GL_PACK_SKIP_ROWS:
5452 case GL_PACK_SKIP_PIXELS:
5453 break;
5454
5455 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005456 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005457 return false;
5458 }
5459
5460 return true;
5461}
5462
Jamie Madill5b772312018-03-08 20:28:32 -05005463bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005464{
5465 return true;
5466}
5467
Jamie Madill5b772312018-03-08 20:28:32 -05005468bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005469{
5470 return true;
5471}
5472
Jamie Madill5b772312018-03-08 20:28:32 -05005473bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005474{
5475 return true;
5476}
5477
Jamie Madill5b772312018-03-08 20:28:32 -05005478bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005479{
5480 if (width < 0 || height < 0)
5481 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005482 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005483 return false;
5484 }
5485
5486 return true;
5487}
5488
Jamie Madill5b772312018-03-08 20:28:32 -05005489bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005490 GLsizei n,
5491 const GLuint *shaders,
5492 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005493 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494 GLsizei length)
5495{
5496 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5497 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5498 shaderBinaryFormats.end())
5499 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005500 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005501 return false;
5502 }
5503
5504 return true;
5505}
5506
Jamie Madill5b772312018-03-08 20:28:32 -05005507bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005508 GLuint shader,
5509 GLsizei count,
5510 const GLchar *const *string,
5511 const GLint *length)
5512{
5513 if (count < 0)
5514 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005515 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005516 return false;
5517 }
5518
Geoff Langfc32e8b2017-05-31 14:16:59 -04005519 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5520 // shader-related entry points
5521 if (context->getExtensions().webglCompatibility)
5522 {
5523 for (GLsizei i = 0; i < count; i++)
5524 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005525 size_t len =
5526 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005527
5528 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005529 if (!IsValidESSLShaderSourceString(string[i], len,
5530 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005531 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005532 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005533 return false;
5534 }
5535 }
5536 }
5537
Jamie Madillc1d770e2017-04-13 17:31:24 -04005538 Shader *shaderObject = GetValidShader(context, shader);
5539 if (!shaderObject)
5540 {
5541 return false;
5542 }
5543
5544 return true;
5545}
5546
Jamie Madill5b772312018-03-08 20:28:32 -05005547bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005548{
5549 if (!IsValidStencilFunc(func))
5550 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005551 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005552 return false;
5553 }
5554
5555 return true;
5556}
5557
Jamie Madill5b772312018-03-08 20:28:32 -05005558bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005559{
5560 if (!IsValidStencilFace(face))
5561 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005562 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005563 return false;
5564 }
5565
5566 if (!IsValidStencilFunc(func))
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 ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005576{
5577 return true;
5578}
5579
Jamie Madill5b772312018-03-08 20:28:32 -05005580bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005581{
5582 if (!IsValidStencilFace(face))
5583 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005584 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005585 return false;
5586 }
5587
5588 return true;
5589}
5590
Jamie Madill5b772312018-03-08 20:28:32 -05005591bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005592{
5593 if (!IsValidStencilOp(fail))
5594 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005595 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596 return false;
5597 }
5598
5599 if (!IsValidStencilOp(zfail))
5600 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602 return false;
5603 }
5604
5605 if (!IsValidStencilOp(zpass))
5606 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005607 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005608 return false;
5609 }
5610
5611 return true;
5612}
5613
Jamie Madill5b772312018-03-08 20:28:32 -05005614bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005615 GLenum face,
5616 GLenum fail,
5617 GLenum zfail,
5618 GLenum zpass)
5619{
5620 if (!IsValidStencilFace(face))
5621 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005622 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005623 return false;
5624 }
5625
5626 return ValidateStencilOp(context, fail, zfail, zpass);
5627}
5628
Jamie Madill5b772312018-03-08 20:28:32 -05005629bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005630{
5631 return ValidateUniform(context, GL_FLOAT, location, 1);
5632}
5633
Jamie Madill5b772312018-03-08 20:28:32 -05005634bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005635{
5636 return ValidateUniform(context, GL_FLOAT, location, count);
5637}
5638
Jamie Madill5b772312018-03-08 20:28:32 -05005639bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005640{
5641 return ValidateUniform1iv(context, location, 1, &x);
5642}
5643
Jamie Madill5b772312018-03-08 20:28:32 -05005644bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005645{
5646 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5647}
5648
Jamie Madill5b772312018-03-08 20:28:32 -05005649bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650{
5651 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655{
5656 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5657}
5658
Jamie Madill5b772312018-03-08 20:28:32 -05005659bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005660{
5661 return ValidateUniform(context, GL_INT_VEC2, location, count);
5662}
5663
Jamie Madill5b772312018-03-08 20:28:32 -05005664bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005665{
5666 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670{
5671 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5672}
5673
Jamie Madill5b772312018-03-08 20:28:32 -05005674bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675{
5676 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005680{
5681 return ValidateUniform(context, GL_INT_VEC3, location, count);
5682}
5683
Jamie Madill5b772312018-03-08 20:28:32 -05005684bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005685{
5686 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5687}
5688
Jamie Madill5b772312018-03-08 20:28:32 -05005689bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005690{
5691 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5692}
5693
Jamie Madill5b772312018-03-08 20:28:32 -05005694bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005695{
5696 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5697}
5698
Jamie Madill5b772312018-03-08 20:28:32 -05005699bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005700{
5701 return ValidateUniform(context, GL_INT_VEC4, location, count);
5702}
5703
Jamie Madill5b772312018-03-08 20:28:32 -05005704bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005705 GLint location,
5706 GLsizei count,
5707 GLboolean transpose,
5708 const GLfloat *value)
5709{
5710 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5711}
5712
Jamie Madill5b772312018-03-08 20:28:32 -05005713bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005714 GLint location,
5715 GLsizei count,
5716 GLboolean transpose,
5717 const GLfloat *value)
5718{
5719 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5720}
5721
Jamie Madill5b772312018-03-08 20:28:32 -05005722bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005723 GLint location,
5724 GLsizei count,
5725 GLboolean transpose,
5726 const GLfloat *value)
5727{
5728 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5729}
5730
Jamie Madill5b772312018-03-08 20:28:32 -05005731bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005732{
5733 Program *programObject = GetValidProgram(context, program);
5734
5735 if (!programObject)
5736 {
5737 return false;
5738 }
5739
5740 return true;
5741}
5742
Jamie Madill5b772312018-03-08 20:28:32 -05005743bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005744{
5745 return ValidateVertexAttribIndex(context, index);
5746}
5747
Jamie Madill5b772312018-03-08 20:28:32 -05005748bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005749{
5750 return ValidateVertexAttribIndex(context, index);
5751}
5752
Jamie Madill5b772312018-03-08 20:28:32 -05005753bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005754{
5755 return ValidateVertexAttribIndex(context, index);
5756}
5757
Jamie Madill5b772312018-03-08 20:28:32 -05005758bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005759{
5760 return ValidateVertexAttribIndex(context, index);
5761}
5762
Jamie Madill5b772312018-03-08 20:28:32 -05005763bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005764{
5765 return ValidateVertexAttribIndex(context, index);
5766}
5767
Jamie Madill5b772312018-03-08 20:28:32 -05005768bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005769{
5770 return ValidateVertexAttribIndex(context, index);
5771}
5772
Jamie Madill5b772312018-03-08 20:28:32 -05005773bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005774 GLuint index,
5775 GLfloat x,
5776 GLfloat y,
5777 GLfloat z,
5778 GLfloat w)
5779{
5780 return ValidateVertexAttribIndex(context, index);
5781}
5782
Jamie Madill5b772312018-03-08 20:28:32 -05005783bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005784{
5785 return ValidateVertexAttribIndex(context, index);
5786}
5787
Jamie Madill5b772312018-03-08 20:28:32 -05005788bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005789{
5790 if (width < 0 || height < 0)
5791 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005792 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005793 return false;
5794 }
5795
5796 return true;
5797}
5798
Jamie Madill5b772312018-03-08 20:28:32 -05005799bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005800{
5801 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5802}
5803
Jamie Madill5b772312018-03-08 20:28:32 -05005804bool ValidateDrawElements(Context *context,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005805 GLenum mode,
5806 GLsizei count,
5807 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005808 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005809{
5810 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5811}
5812
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005813bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005814 GLenum target,
5815 GLenum attachment,
5816 GLenum pname,
5817 GLint *params)
5818{
5819 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5820 nullptr);
5821}
5822
Jamie Madill5b772312018-03-08 20:28:32 -05005823bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005824{
5825 return ValidateGetProgramivBase(context, program, pname, nullptr);
5826}
5827
Jamie Madill5b772312018-03-08 20:28:32 -05005828bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005829 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005830 GLint level,
5831 GLenum internalformat,
5832 GLint x,
5833 GLint y,
5834 GLsizei width,
5835 GLsizei height,
5836 GLint border)
5837{
5838 if (context->getClientMajorVersion() < 3)
5839 {
5840 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5841 0, x, y, width, height, border);
5842 }
5843
5844 ASSERT(context->getClientMajorVersion() == 3);
5845 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5846 0, x, y, width, height, border);
5847}
5848
5849bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005850 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005851 GLint level,
5852 GLint xoffset,
5853 GLint yoffset,
5854 GLint x,
5855 GLint y,
5856 GLsizei width,
5857 GLsizei height)
5858{
5859 if (context->getClientMajorVersion() < 3)
5860 {
5861 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5862 yoffset, x, y, width, height, 0);
5863 }
5864
5865 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5866 yoffset, 0, x, y, width, height, 0);
5867}
5868
5869bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5870{
5871 return ValidateGenOrDelete(context, n);
5872}
5873
5874bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5875{
5876 return ValidateGenOrDelete(context, n);
5877}
5878
5879bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5880{
5881 return ValidateGenOrDelete(context, n);
5882}
5883
5884bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5885{
5886 return ValidateGenOrDelete(context, n);
5887}
5888
5889bool ValidateDisable(Context *context, GLenum cap)
5890{
5891 if (!ValidCap(context, cap, false))
5892 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005893 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005894 return false;
5895 }
5896
5897 return true;
5898}
5899
5900bool ValidateEnable(Context *context, GLenum cap)
5901{
5902 if (!ValidCap(context, cap, false))
5903 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005904 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005905 return false;
5906 }
5907
5908 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5909 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5910 {
5911 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005912 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005913
5914 // We also output an error message to the debugger window if tracing is active, so that
5915 // developers can see the error message.
5916 ERR() << errorMessage;
5917 return false;
5918 }
5919
5920 return true;
5921}
5922
5923bool ValidateFramebufferRenderbuffer(Context *context,
5924 GLenum target,
5925 GLenum attachment,
5926 GLenum renderbuffertarget,
5927 GLuint renderbuffer)
5928{
Geoff Lange8afa902017-09-27 15:00:43 -04005929 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005930 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005931 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5932 return false;
5933 }
5934
5935 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5936 {
5937 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005938 return false;
5939 }
5940
5941 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5942 renderbuffertarget, renderbuffer);
5943}
5944
5945bool ValidateFramebufferTexture2D(Context *context,
5946 GLenum target,
5947 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005948 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005949 GLuint texture,
5950 GLint level)
5951{
5952 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5953 // extension
5954 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5955 level != 0)
5956 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005957 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005958 return false;
5959 }
5960
5961 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5962 {
5963 return false;
5964 }
5965
5966 if (texture != 0)
5967 {
5968 gl::Texture *tex = context->getTexture(texture);
5969 ASSERT(tex);
5970
5971 const gl::Caps &caps = context->getCaps();
5972
5973 switch (textarget)
5974 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005975 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005976 {
5977 if (level > gl::log2(caps.max2DTextureSize))
5978 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005979 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005980 return false;
5981 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005982 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005983 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005984 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005985 return false;
5986 }
5987 }
5988 break;
5989
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005990 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005991 {
5992 if (level != 0)
5993 {
5994 context->handleError(InvalidValue());
5995 return false;
5996 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005997 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005998 {
5999 context->handleError(InvalidOperation()
6000 << "Textarget must match the texture target type.");
6001 return false;
6002 }
6003 }
6004 break;
6005
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006006 case TextureTarget::CubeMapNegativeX:
6007 case TextureTarget::CubeMapNegativeY:
6008 case TextureTarget::CubeMapNegativeZ:
6009 case TextureTarget::CubeMapPositiveX:
6010 case TextureTarget::CubeMapPositiveY:
6011 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 {
6013 if (level > gl::log2(caps.maxCubeMapTextureSize))
6014 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006015 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006016 return false;
6017 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006018 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006019 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006020 context->handleError(InvalidOperation()
6021 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006022 return false;
6023 }
6024 }
6025 break;
6026
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006027 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006028 {
6029 if (context->getClientVersion() < ES_3_1)
6030 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006031 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006032 return false;
6033 }
6034
6035 if (level != 0)
6036 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006037 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006038 return false;
6039 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006040 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006042 context->handleError(InvalidOperation()
6043 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006044 return false;
6045 }
6046 }
6047 break;
6048
6049 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006051 return false;
6052 }
6053
6054 const Format &format = tex->getFormat(textarget, level);
6055 if (format.info->compressed)
6056 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006057 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 return false;
6059 }
6060 }
6061
6062 return true;
6063}
6064
6065bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6066{
6067 return ValidateGenOrDelete(context, n);
6068}
6069
6070bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6071{
6072 return ValidateGenOrDelete(context, n);
6073}
6074
6075bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6076{
6077 return ValidateGenOrDelete(context, n);
6078}
6079
6080bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6081{
6082 return ValidateGenOrDelete(context, n);
6083}
6084
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006085bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006086{
6087 if (!ValidTextureTarget(context, target))
6088 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006089 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006090 return false;
6091 }
6092
6093 Texture *texture = context->getTargetTexture(target);
6094
6095 if (texture == nullptr)
6096 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006097 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006098 return false;
6099 }
6100
6101 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6102
6103 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6104 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6105 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006107 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006108 return false;
6109 }
6110
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006111 TextureTarget baseTarget = (target == TextureType::CubeMap)
6112 ? TextureTarget::CubeMapPositiveX
6113 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006114 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6115 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6116 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006117 {
6118 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6119 return false;
6120 }
6121
Geoff Lang536eca12017-09-13 11:23:35 -04006122 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6123 bool formatUnsized = !format.sized;
6124 bool formatColorRenderableAndFilterable =
6125 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6126 format.renderSupport(context->getClientVersion(), context->getExtensions());
6127 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006128 {
Geoff Lang536eca12017-09-13 11:23:35 -04006129 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006130 return false;
6131 }
6132
Geoff Lang536eca12017-09-13 11:23:35 -04006133 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6134 // generation
6135 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6136 {
6137 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6138 return false;
6139 }
6140
6141 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
Geoff Lange24032a2018-03-28 15:41:46 -04006142 // not. Differentiate the ES3 format from the extension format by checking if the format is
6143 // sized, GL_EXT_sRGB does not add any sized formats.
6144 bool supportsSRGBMipmapGeneration = context->getExtensions().webglCompatibility;
6145 if (!supportsSRGBMipmapGeneration && !format.sized && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006146 {
Geoff Lang536eca12017-09-13 11:23:35 -04006147 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006148 return false;
6149 }
6150
6151 // Non-power of 2 ES2 check
6152 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6153 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6154 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6155 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006156 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6157 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006158 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006159 return false;
6160 }
6161
6162 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006163 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006166 return false;
6167 }
6168
6169 return true;
6170}
6171
Jamie Madill5b772312018-03-08 20:28:32 -05006172bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006173 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006174 GLenum pname,
6175 GLint *params)
6176{
6177 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6178}
6179
6180bool ValidateGetRenderbufferParameteriv(Context *context,
6181 GLenum target,
6182 GLenum pname,
6183 GLint *params)
6184{
6185 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6186}
6187
6188bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6189{
6190 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6191}
6192
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006193bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006194{
6195 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6196}
6197
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006198bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006199{
6200 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6201}
6202
6203bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6204{
6205 return ValidateGetUniformBase(context, program, location);
6206}
6207
6208bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6209{
6210 return ValidateGetUniformBase(context, program, location);
6211}
6212
6213bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6214{
6215 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6216}
6217
6218bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6219{
6220 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6221}
6222
6223bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6224{
6225 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6226}
6227
6228bool ValidateIsEnabled(Context *context, GLenum cap)
6229{
6230 if (!ValidCap(context, cap, true))
6231 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006232 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006233 return false;
6234 }
6235
6236 return true;
6237}
6238
6239bool ValidateLinkProgram(Context *context, GLuint program)
6240{
6241 if (context->hasActiveTransformFeedback(program))
6242 {
6243 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006244 context->handleError(InvalidOperation() << "Cannot link program while program is "
6245 "associated with an active transform "
6246 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006247 return false;
6248 }
6249
6250 Program *programObject = GetValidProgram(context, program);
6251 if (!programObject)
6252 {
6253 return false;
6254 }
6255
6256 return true;
6257}
6258
Jamie Madill4928b7c2017-06-20 12:57:39 -04006259bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006260 GLint x,
6261 GLint y,
6262 GLsizei width,
6263 GLsizei height,
6264 GLenum format,
6265 GLenum type,
6266 void *pixels)
6267{
6268 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6269 nullptr, pixels);
6270}
6271
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006272bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006273{
6274 return ValidateTexParameterBase(context, target, pname, -1, &param);
6275}
6276
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006277bool ValidateTexParameterfv(Context *context,
6278 TextureType target,
6279 GLenum pname,
6280 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006281{
6282 return ValidateTexParameterBase(context, target, pname, -1, params);
6283}
6284
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006285bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006286{
6287 return ValidateTexParameterBase(context, target, pname, -1, &param);
6288}
6289
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006290bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006291{
6292 return ValidateTexParameterBase(context, target, pname, -1, params);
6293}
6294
6295bool ValidateUseProgram(Context *context, GLuint program)
6296{
6297 if (program != 0)
6298 {
6299 Program *programObject = context->getProgram(program);
6300 if (!programObject)
6301 {
6302 // ES 3.1.0 section 7.3 page 72
6303 if (context->getShader(program))
6304 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006306 return false;
6307 }
6308 else
6309 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006310 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006311 return false;
6312 }
6313 }
6314 if (!programObject->isLinked())
6315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006317 return false;
6318 }
6319 }
6320 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6321 {
6322 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006323 context
6324 ->handleError(InvalidOperation()
6325 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006326 return false;
6327 }
6328
6329 return true;
6330}
6331
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006332bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6333{
6334 if (!context->getExtensions().fence)
6335 {
6336 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6337 return false;
6338 }
6339
6340 if (n < 0)
6341 {
6342 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6343 return false;
6344 }
6345
6346 return true;
6347}
6348
6349bool ValidateFinishFenceNV(Context *context, GLuint fence)
6350{
6351 if (!context->getExtensions().fence)
6352 {
6353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6354 return false;
6355 }
6356
6357 FenceNV *fenceObject = context->getFenceNV(fence);
6358
6359 if (fenceObject == nullptr)
6360 {
6361 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6362 return false;
6363 }
6364
6365 if (!fenceObject->isSet())
6366 {
6367 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6368 return false;
6369 }
6370
6371 return true;
6372}
6373
6374bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6375{
6376 if (!context->getExtensions().fence)
6377 {
6378 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6379 return false;
6380 }
6381
6382 if (n < 0)
6383 {
6384 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6385 return false;
6386 }
6387
6388 return true;
6389}
6390
6391bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6392{
6393 if (!context->getExtensions().fence)
6394 {
6395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6396 return false;
6397 }
6398
6399 FenceNV *fenceObject = context->getFenceNV(fence);
6400
6401 if (fenceObject == nullptr)
6402 {
6403 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6404 return false;
6405 }
6406
6407 if (!fenceObject->isSet())
6408 {
6409 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6410 return false;
6411 }
6412
6413 switch (pname)
6414 {
6415 case GL_FENCE_STATUS_NV:
6416 case GL_FENCE_CONDITION_NV:
6417 break;
6418
6419 default:
6420 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6421 return false;
6422 }
6423
6424 return true;
6425}
6426
6427bool ValidateGetGraphicsResetStatusEXT(Context *context)
6428{
6429 if (!context->getExtensions().robustness)
6430 {
6431 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6432 return false;
6433 }
6434
6435 return true;
6436}
6437
6438bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6439 GLuint shader,
6440 GLsizei bufsize,
6441 GLsizei *length,
6442 GLchar *source)
6443{
6444 if (!context->getExtensions().translatedShaderSource)
6445 {
6446 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6447 return false;
6448 }
6449
6450 if (bufsize < 0)
6451 {
6452 context->handleError(InvalidValue());
6453 return false;
6454 }
6455
6456 Shader *shaderObject = context->getShader(shader);
6457
6458 if (!shaderObject)
6459 {
6460 context->handleError(InvalidOperation());
6461 return false;
6462 }
6463
6464 return true;
6465}
6466
6467bool ValidateIsFenceNV(Context *context, GLuint fence)
6468{
6469 if (!context->getExtensions().fence)
6470 {
6471 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6472 return false;
6473 }
6474
6475 return true;
6476}
6477
Jamie Madill007530e2017-12-28 14:27:04 -05006478bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6479{
6480 if (!context->getExtensions().fence)
6481 {
6482 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6483 return false;
6484 }
6485
6486 if (condition != GL_ALL_COMPLETED_NV)
6487 {
6488 context->handleError(InvalidEnum());
6489 return false;
6490 }
6491
6492 FenceNV *fenceObject = context->getFenceNV(fence);
6493
6494 if (fenceObject == nullptr)
6495 {
6496 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6497 return false;
6498 }
6499
6500 return true;
6501}
6502
6503bool ValidateTestFenceNV(Context *context, GLuint fence)
6504{
6505 if (!context->getExtensions().fence)
6506 {
6507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6508 return false;
6509 }
6510
6511 FenceNV *fenceObject = context->getFenceNV(fence);
6512
6513 if (fenceObject == nullptr)
6514 {
6515 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6516 return false;
6517 }
6518
6519 if (fenceObject->isSet() != GL_TRUE)
6520 {
6521 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6522 return false;
6523 }
6524
6525 return true;
6526}
6527
6528bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006529 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006530 GLsizei levels,
6531 GLenum internalformat,
6532 GLsizei width,
6533 GLsizei height)
6534{
6535 if (!context->getExtensions().textureStorage)
6536 {
6537 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6538 return false;
6539 }
6540
6541 if (context->getClientMajorVersion() < 3)
6542 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006543 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006544 height);
6545 }
6546
6547 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006548 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006549 1);
6550}
6551
6552bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6553{
6554 if (!context->getExtensions().instancedArrays)
6555 {
6556 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6557 return false;
6558 }
6559
6560 if (index >= MAX_VERTEX_ATTRIBS)
6561 {
6562 context->handleError(InvalidValue());
6563 return false;
6564 }
6565
6566 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6567 {
6568 if (index == 0 && divisor != 0)
6569 {
6570 const char *errorMessage =
6571 "The current context doesn't support setting a non-zero divisor on the "
6572 "attribute with index zero. "
6573 "Please reorder the attributes in your vertex shader so that attribute zero "
6574 "can have a zero divisor.";
6575 context->handleError(InvalidOperation() << errorMessage);
6576
6577 // We also output an error message to the debugger window if tracing is active, so
6578 // that developers can see the error message.
6579 ERR() << errorMessage;
6580 return false;
6581 }
6582 }
6583
6584 return true;
6585}
6586
6587bool ValidateTexImage3DOES(Context *context,
6588 GLenum target,
6589 GLint level,
6590 GLenum internalformat,
6591 GLsizei width,
6592 GLsizei height,
6593 GLsizei depth,
6594 GLint border,
6595 GLenum format,
6596 GLenum type,
6597 const void *pixels)
6598{
6599 UNIMPLEMENTED(); // FIXME
6600 return false;
6601}
6602
6603bool ValidatePopGroupMarkerEXT(Context *context)
6604{
6605 if (!context->getExtensions().debugMarker)
6606 {
6607 // The debug marker calls should not set error state
6608 // However, it seems reasonable to set an error state if the extension is not enabled
6609 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6610 return false;
6611 }
6612
6613 return true;
6614}
6615
Jamie Madillfa920eb2018-01-04 11:45:50 -05006616bool ValidateTexStorage1DEXT(Context *context,
6617 GLenum target,
6618 GLsizei levels,
6619 GLenum internalformat,
6620 GLsizei width)
6621{
6622 UNIMPLEMENTED();
6623 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6624 return false;
6625}
6626
6627bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006628 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006629 GLsizei levels,
6630 GLenum internalformat,
6631 GLsizei width,
6632 GLsizei height,
6633 GLsizei depth)
6634{
6635 if (!context->getExtensions().textureStorage)
6636 {
6637 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6638 return false;
6639 }
6640
6641 if (context->getClientMajorVersion() < 3)
6642 {
6643 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6644 return false;
6645 }
6646
6647 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6648 depth);
6649}
6650
Jamie Madillc29968b2016-01-20 11:17:23 -05006651} // namespace gl