blob: 4e037da37868bf2e1cadf535fbec54dede27efa6 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070078 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030079 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madill5b772312018-03-08 20:28:32 -0500458bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700795 // GLES1 emulation: GLES1-specific caps
796 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700797 case GL_VERTEX_ARRAY:
798 case GL_NORMAL_ARRAY:
799 case GL_COLOR_ARRAY:
800 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700801 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700802 case GL_LIGHTING:
803 case GL_LIGHT0:
804 case GL_LIGHT1:
805 case GL_LIGHT2:
806 case GL_LIGHT3:
807 case GL_LIGHT4:
808 case GL_LIGHT5:
809 case GL_LIGHT6:
810 case GL_LIGHT7:
811 case GL_NORMALIZE:
812 case GL_RESCALE_NORMAL:
813 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700814 case GL_CLIP_PLANE0:
815 case GL_CLIP_PLANE1:
816 case GL_CLIP_PLANE2:
817 case GL_CLIP_PLANE3:
818 case GL_CLIP_PLANE4:
819 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700820 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700821 case GL_POINT_SMOOTH:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700822 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700823 case GL_POINT_SIZE_ARRAY_OES:
824 return context->getClientVersion() < Version(2, 0) &&
825 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700826 case GL_TEXTURE_CUBE_MAP:
827 return context->getClientVersion() < Version(2, 0) &&
828 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700829 case GL_POINT_SPRITE_OES:
830 return context->getClientVersion() < Version(2, 0) &&
831 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400832 default:
833 return false;
834 }
835}
836
Geoff Langfc32e8b2017-05-31 14:16:59 -0400837// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
838// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400839bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400840{
841 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400842 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
843 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400844 {
845 return true;
846 }
847
848 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
849 if (c >= 9 && c <= 13)
850 {
851 return true;
852 }
853
854 return false;
855}
856
Geoff Langcab92ee2017-07-19 17:32:07 -0400857bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400858{
Geoff Langa71a98e2017-06-19 15:15:00 -0400859 for (size_t i = 0; i < len; i++)
860 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400861 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400862 {
863 return false;
864 }
865 }
866
867 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400868}
869
Geoff Langcab92ee2017-07-19 17:32:07 -0400870bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
871{
872 enum class ParseState
873 {
874 // Have not seen an ASCII non-whitespace character yet on
875 // this line. Possible that we might see a preprocessor
876 // directive.
877 BEGINING_OF_LINE,
878
879 // Have seen at least one ASCII non-whitespace character
880 // on this line.
881 MIDDLE_OF_LINE,
882
883 // Handling a preprocessor directive. Passes through all
884 // characters up to the end of the line. Disables comment
885 // processing.
886 IN_PREPROCESSOR_DIRECTIVE,
887
888 // Handling a single-line comment. The comment text is
889 // replaced with a single space.
890 IN_SINGLE_LINE_COMMENT,
891
892 // Handling a multi-line comment. Newlines are passed
893 // through to preserve line numbers.
894 IN_MULTI_LINE_COMMENT
895 };
896
897 ParseState state = ParseState::BEGINING_OF_LINE;
898 size_t pos = 0;
899
900 while (pos < len)
901 {
902 char c = str[pos];
903 char next = pos + 1 < len ? str[pos + 1] : 0;
904
905 // Check for newlines
906 if (c == '\n' || c == '\r')
907 {
908 if (state != ParseState::IN_MULTI_LINE_COMMENT)
909 {
910 state = ParseState::BEGINING_OF_LINE;
911 }
912
913 pos++;
914 continue;
915 }
916
917 switch (state)
918 {
919 case ParseState::BEGINING_OF_LINE:
920 if (c == ' ')
921 {
922 // Maintain the BEGINING_OF_LINE state until a non-space is seen
923 pos++;
924 }
925 else if (c == '#')
926 {
927 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
928 pos++;
929 }
930 else
931 {
932 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
933 state = ParseState::MIDDLE_OF_LINE;
934 }
935 break;
936
937 case ParseState::MIDDLE_OF_LINE:
938 if (c == '/' && next == '/')
939 {
940 state = ParseState::IN_SINGLE_LINE_COMMENT;
941 pos++;
942 }
943 else if (c == '/' && next == '*')
944 {
945 state = ParseState::IN_MULTI_LINE_COMMENT;
946 pos++;
947 }
948 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
949 {
950 // Skip line continuation characters
951 }
952 else if (!IsValidESSLCharacter(c))
953 {
954 return false;
955 }
956 pos++;
957 break;
958
959 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700960 // Line-continuation characters may not be permitted.
961 // Otherwise, just pass it through. Do not parse comments in this state.
962 if (!lineContinuationAllowed && c == '\\')
963 {
964 return false;
965 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400966 pos++;
967 break;
968
969 case ParseState::IN_SINGLE_LINE_COMMENT:
970 // Line-continuation characters are processed before comment processing.
971 // Advance string if a new line character is immediately behind
972 // line-continuation character.
973 if (c == '\\' && (next == '\n' || next == '\r'))
974 {
975 pos++;
976 }
977 pos++;
978 break;
979
980 case ParseState::IN_MULTI_LINE_COMMENT:
981 if (c == '*' && next == '/')
982 {
983 state = ParseState::MIDDLE_OF_LINE;
984 pos++;
985 }
986 pos++;
987 break;
988 }
989 }
990
991 return true;
992}
993
Jamie Madill5b772312018-03-08 20:28:32 -0500994bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700995{
996 ASSERT(context->isWebGL());
997
998 // WebGL 1.0 [Section 6.16] GLSL Constructs
999 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1000 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1001 {
1002 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1003 return false;
1004 }
1005
1006 return true;
1007}
1008
Jamie Madill5b772312018-03-08 20:28:32 -05001009bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001010{
1011 ASSERT(context->isWebGL());
1012
1013 if (context->isWebGL1() && length > 256)
1014 {
1015 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1016 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1017 // locations.
1018 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1019
1020 return false;
1021 }
1022 else if (length > 1024)
1023 {
1024 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1025 // uniform and attribute locations.
1026 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1027 return false;
1028 }
1029
1030 return true;
1031}
1032
Jamie Madill007530e2017-12-28 14:27:04 -05001033bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1034{
1035 if (!context->getExtensions().pathRendering)
1036 {
1037 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1038 return false;
1039 }
1040
1041 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1042 {
1043 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1044 return false;
1045 }
1046 return true;
1047}
Jamie Madillc29968b2016-01-20 11:17:23 -05001048} // anonymous namespace
1049
Geoff Langff5b2d52016-09-07 11:32:23 -04001050bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001051 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001052 GLint level,
1053 GLenum internalformat,
1054 bool isCompressed,
1055 bool isSubImage,
1056 GLint xoffset,
1057 GLint yoffset,
1058 GLsizei width,
1059 GLsizei height,
1060 GLint border,
1061 GLenum format,
1062 GLenum type,
1063 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001064 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001065{
Jamie Madill6f38f822014-06-06 17:12:20 -04001066 if (!ValidTexture2DDestinationTarget(context, target))
1067 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001068 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001069 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001070 }
1071
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001072 TextureType texType = TextureTargetToType(target);
1073 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001075 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001076 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001077 }
1078
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001079 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001080 {
1081 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1082 return false;
1083 }
1084
1085 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001086 std::numeric_limits<GLsizei>::max() - yoffset < height)
1087 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001088 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001089 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001090 }
1091
Geoff Lang6e898aa2017-06-02 11:17:26 -04001092 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1093 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1094 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1095 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1096 // case.
1097 bool nonEqualFormatsAllowed =
1098 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1099 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1100
1101 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001103 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001104 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001105 }
1106
Geoff Langaae65a42014-05-26 12:43:44 -04001107 const gl::Caps &caps = context->getCaps();
1108
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001109 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001110 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001111 case TextureType::_2D:
1112 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1113 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1114 {
1115 context->handleError(InvalidValue());
1116 return false;
1117 }
1118 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001119
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001120 case TextureType::Rectangle:
1121 ASSERT(level == 0);
1122 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1123 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1124 {
1125 context->handleError(InvalidValue());
1126 return false;
1127 }
1128 if (isCompressed)
1129 {
1130 context->handleError(InvalidEnum()
1131 << "Rectangle texture cannot have a compressed format.");
1132 return false;
1133 }
1134 break;
1135
1136 case TextureType::CubeMap:
1137 if (!isSubImage && width != height)
1138 {
1139 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1140 return false;
1141 }
1142
1143 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1144 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1145 {
1146 context->handleError(InvalidValue());
1147 return false;
1148 }
1149 break;
1150
1151 default:
1152 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001153 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001154 }
1155
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001156 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001157 if (!texture)
1158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001160 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001161 }
1162
Geoff Langa9be0dc2014-12-17 12:34:40 -05001163 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001164 {
Geoff Langca271392017-04-05 12:30:00 -04001165 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1166 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001168 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001169 return false;
1170 }
1171
Geoff Langa9be0dc2014-12-17 12:34:40 -05001172 if (format != GL_NONE)
1173 {
Geoff Langca271392017-04-05 12:30:00 -04001174 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1175 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001176 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001177 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001178 return false;
1179 }
1180 }
1181
1182 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1183 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001185 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001186 return false;
1187 }
Geoff Langfb052642017-10-24 13:42:09 -04001188
1189 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001190 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001191 {
1192 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1193 return false;
1194 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001195 }
1196 else
1197 {
Geoff Lang69cce582015-09-17 13:20:36 -04001198 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001200 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001201 return false;
1202 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001203 }
1204
1205 // Verify zero border
1206 if (border != 0)
1207 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001208 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001209 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001210 }
1211
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001212 if (isCompressed)
1213 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001214 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001215 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1216 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001217
1218 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1219
1220 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001221 {
Geoff Lange88e4542018-05-03 15:05:57 -04001222 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1223 return false;
1224 }
1225
1226 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1227 context->getExtensions()))
1228 {
1229 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1230 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001231 }
Geoff Lang966c9402017-04-18 12:38:27 -04001232
1233 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001234 {
Geoff Lange88e4542018-05-03 15:05:57 -04001235 // From the OES_compressed_ETC1_RGB8_texture spec:
1236 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1237 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1238 // ETC1_RGB8_OES.
1239 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1240 {
1241 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1242 return false;
1243 }
1244
Geoff Lang966c9402017-04-18 12:38:27 -04001245 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1246 height, texture->getWidth(target, level),
1247 texture->getHeight(target, level)))
1248 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001249 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001250 return false;
1251 }
1252
1253 if (format != actualInternalFormat)
1254 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001255 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001256 return false;
1257 }
1258 }
1259 else
1260 {
1261 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1262 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001263 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001264 return false;
1265 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001266 }
1267 }
1268 else
1269 {
1270 // validate <type> by itself (used as secondary key below)
1271 switch (type)
1272 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001273 case GL_UNSIGNED_BYTE:
1274 case GL_UNSIGNED_SHORT_5_6_5:
1275 case GL_UNSIGNED_SHORT_4_4_4_4:
1276 case GL_UNSIGNED_SHORT_5_5_5_1:
1277 case GL_UNSIGNED_SHORT:
1278 case GL_UNSIGNED_INT:
1279 case GL_UNSIGNED_INT_24_8_OES:
1280 case GL_HALF_FLOAT_OES:
1281 case GL_FLOAT:
1282 break;
1283 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001284 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001285 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001286 }
1287
1288 // validate <format> + <type> combinations
1289 // - invalid <format> -> sets INVALID_ENUM
1290 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1291 switch (format)
1292 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001293 case GL_ALPHA:
1294 case GL_LUMINANCE:
1295 case GL_LUMINANCE_ALPHA:
1296 switch (type)
1297 {
1298 case GL_UNSIGNED_BYTE:
1299 case GL_FLOAT:
1300 case GL_HALF_FLOAT_OES:
1301 break;
1302 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001303 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001304 return false;
1305 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001306 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001307 case GL_RED:
1308 case GL_RG:
1309 if (!context->getExtensions().textureRG)
1310 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001311 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001312 return false;
1313 }
1314 switch (type)
1315 {
1316 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001317 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001318 case GL_FLOAT:
1319 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001320 if (!context->getExtensions().textureFloat)
1321 {
1322 context->handleError(InvalidEnum());
1323 return false;
1324 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001325 break;
1326 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001327 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001328 return false;
1329 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001330 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001331 case GL_RGB:
1332 switch (type)
1333 {
1334 case GL_UNSIGNED_BYTE:
1335 case GL_UNSIGNED_SHORT_5_6_5:
1336 case GL_FLOAT:
1337 case GL_HALF_FLOAT_OES:
1338 break;
1339 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001340 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001341 return false;
1342 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001343 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001344 case GL_RGBA:
1345 switch (type)
1346 {
1347 case GL_UNSIGNED_BYTE:
1348 case GL_UNSIGNED_SHORT_4_4_4_4:
1349 case GL_UNSIGNED_SHORT_5_5_5_1:
1350 case GL_FLOAT:
1351 case GL_HALF_FLOAT_OES:
1352 break;
1353 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001355 return false;
1356 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001357 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001358 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001359 if (!context->getExtensions().textureFormatBGRA8888)
1360 {
1361 context->handleError(InvalidEnum());
1362 return false;
1363 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001364 switch (type)
1365 {
1366 case GL_UNSIGNED_BYTE:
1367 break;
1368 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001369 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001370 return false;
1371 }
1372 break;
1373 case GL_SRGB_EXT:
1374 case GL_SRGB_ALPHA_EXT:
1375 if (!context->getExtensions().sRGB)
1376 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001377 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001378 return false;
1379 }
1380 switch (type)
1381 {
1382 case GL_UNSIGNED_BYTE:
1383 break;
1384 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001385 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001386 return false;
1387 }
1388 break;
1389 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1390 // handled below
1391 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1392 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1393 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1394 break;
1395 case GL_DEPTH_COMPONENT:
1396 switch (type)
1397 {
1398 case GL_UNSIGNED_SHORT:
1399 case GL_UNSIGNED_INT:
1400 break;
1401 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001402 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001403 return false;
1404 }
1405 break;
1406 case GL_DEPTH_STENCIL_OES:
1407 switch (type)
1408 {
1409 case GL_UNSIGNED_INT_24_8_OES:
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 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001417 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001418 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001419 }
1420
1421 switch (format)
1422 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001423 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1424 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1425 if (context->getExtensions().textureCompressionDXT1)
1426 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001427 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001428 return false;
1429 }
1430 else
1431 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001432 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 return false;
1434 }
1435 break;
1436 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1437 if (context->getExtensions().textureCompressionDXT3)
1438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001439 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001440 return false;
1441 }
1442 else
1443 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001444 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001445 return false;
1446 }
1447 break;
1448 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1449 if (context->getExtensions().textureCompressionDXT5)
1450 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001451 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001452 return false;
1453 }
1454 else
1455 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001456 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001457 return false;
1458 }
1459 break;
1460 case GL_ETC1_RGB8_OES:
1461 if (context->getExtensions().compressedETC1RGB8Texture)
1462 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001463 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001464 return false;
1465 }
1466 else
1467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001468 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001469 return false;
1470 }
1471 break;
1472 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001473 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1474 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1475 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1476 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001477 if (context->getExtensions().lossyETCDecode)
1478 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001479 context->handleError(InvalidOperation()
1480 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001481 return false;
1482 }
1483 else
1484 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001485 context->handleError(InvalidEnum()
1486 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 return false;
1488 }
1489 break;
1490 case GL_DEPTH_COMPONENT:
1491 case GL_DEPTH_STENCIL_OES:
1492 if (!context->getExtensions().depthTextures)
1493 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001494 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001495 return false;
1496 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001497 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001498 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001499 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001500 return false;
1501 }
1502 // OES_depth_texture supports loading depth data and multiple levels,
1503 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001504 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001505 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001506 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1507 return false;
1508 }
1509 if (level != 0)
1510 {
1511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001512 return false;
1513 }
1514 break;
1515 default:
1516 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001517 }
1518
Geoff Lang6e898aa2017-06-02 11:17:26 -04001519 if (!isSubImage)
1520 {
1521 switch (internalformat)
1522 {
1523 case GL_RGBA32F:
1524 if (!context->getExtensions().colorBufferFloatRGBA)
1525 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001526 context->handleError(InvalidValue()
1527 << "Sized GL_RGBA32F internal format requires "
1528 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001529 return false;
1530 }
1531 if (type != GL_FLOAT)
1532 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001533 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001534 return false;
1535 }
1536 if (format != GL_RGBA)
1537 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001538 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001539 return false;
1540 }
1541 break;
1542
1543 case GL_RGB32F:
1544 if (!context->getExtensions().colorBufferFloatRGB)
1545 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001546 context->handleError(InvalidValue()
1547 << "Sized GL_RGB32F internal format requires "
1548 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001549 return false;
1550 }
1551 if (type != GL_FLOAT)
1552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001553 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001554 return false;
1555 }
1556 if (format != GL_RGB)
1557 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001558 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001559 return false;
1560 }
1561 break;
1562
1563 default:
1564 break;
1565 }
1566 }
1567
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001568 if (type == GL_FLOAT)
1569 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001570 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001571 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001572 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001573 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001574 }
1575 }
1576 else if (type == GL_HALF_FLOAT_OES)
1577 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001578 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001579 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001580 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001581 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001582 }
1583 }
1584 }
1585
Geoff Langdbcced82017-06-06 15:55:54 -04001586 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001587 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001588 imageSize))
1589 {
1590 return false;
1591 }
1592
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001593 return true;
1594}
1595
He Yunchaoced53ae2016-11-29 15:00:51 +08001596bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001597 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001598 GLsizei levels,
1599 GLenum internalformat,
1600 GLsizei width,
1601 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001602{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001603 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1604 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001605 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001606 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001607 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001608 }
1609
1610 if (width < 1 || height < 1 || levels < 1)
1611 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001612 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001613 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001614 }
1615
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001616 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001617 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001618 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001619 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001620 }
1621
1622 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1623 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001624 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001625 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001626 }
1627
Geoff Langca271392017-04-05 12:30:00 -04001628 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001629 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001630 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001631 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001632 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 }
1634
Geoff Langaae65a42014-05-26 12:43:44 -04001635 const gl::Caps &caps = context->getCaps();
1636
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001637 switch (target)
1638 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001639 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001640 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1641 static_cast<GLuint>(height) > caps.max2DTextureSize)
1642 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001643 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001644 return false;
1645 }
1646 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001647 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001648 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1649 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1650 {
1651 context->handleError(InvalidValue());
1652 return false;
1653 }
1654 if (formatInfo.compressed)
1655 {
1656 context->handleError(InvalidEnum()
1657 << "Rectangle texture cannot have a compressed format.");
1658 return false;
1659 }
1660 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001661 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001662 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1663 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1664 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001665 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001666 return false;
1667 }
1668 break;
1669 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001670 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001671 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001672 }
1673
Geoff Langc0b9ef42014-07-02 10:02:37 -04001674 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001675 {
1676 if (!gl::isPow2(width) || !gl::isPow2(height))
1677 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001678 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001679 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001680 }
1681 }
1682
1683 switch (internalformat)
1684 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001685 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1686 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1687 if (!context->getExtensions().textureCompressionDXT1)
1688 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001689 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001690 return false;
1691 }
1692 break;
1693 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1694 if (!context->getExtensions().textureCompressionDXT3)
1695 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001696 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001697 return false;
1698 }
1699 break;
1700 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1701 if (!context->getExtensions().textureCompressionDXT5)
1702 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001703 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001704 return false;
1705 }
1706 break;
1707 case GL_ETC1_RGB8_OES:
1708 if (!context->getExtensions().compressedETC1RGB8Texture)
1709 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001710 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001711 return false;
1712 }
1713 break;
1714 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001715 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1716 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1717 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1718 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001719 if (!context->getExtensions().lossyETCDecode)
1720 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001721 context->handleError(InvalidEnum()
1722 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001723 return false;
1724 }
1725 break;
1726 case GL_RGBA32F_EXT:
1727 case GL_RGB32F_EXT:
1728 case GL_ALPHA32F_EXT:
1729 case GL_LUMINANCE32F_EXT:
1730 case GL_LUMINANCE_ALPHA32F_EXT:
1731 if (!context->getExtensions().textureFloat)
1732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001733 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001734 return false;
1735 }
1736 break;
1737 case GL_RGBA16F_EXT:
1738 case GL_RGB16F_EXT:
1739 case GL_ALPHA16F_EXT:
1740 case GL_LUMINANCE16F_EXT:
1741 case GL_LUMINANCE_ALPHA16F_EXT:
1742 if (!context->getExtensions().textureHalfFloat)
1743 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001744 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001745 return false;
1746 }
1747 break;
1748 case GL_R8_EXT:
1749 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001750 if (!context->getExtensions().textureRG)
1751 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001752 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001753 return false;
1754 }
1755 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001756 case GL_R16F_EXT:
1757 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001758 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1759 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001760 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001761 return false;
1762 }
1763 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001764 case GL_R32F_EXT:
1765 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001766 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001767 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001768 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 return false;
1770 }
1771 break;
1772 case GL_DEPTH_COMPONENT16:
1773 case GL_DEPTH_COMPONENT32_OES:
1774 case GL_DEPTH24_STENCIL8_OES:
1775 if (!context->getExtensions().depthTextures)
1776 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001777 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001778 return false;
1779 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001780 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001781 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001782 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001783 return false;
1784 }
1785 // ANGLE_depth_texture only supports 1-level textures
1786 if (levels != 1)
1787 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001788 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001789 return false;
1790 }
1791 break;
1792 default:
1793 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001794 }
1795
Geoff Lang691e58c2014-12-19 17:03:25 -05001796 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001797 if (!texture || texture->id() == 0)
1798 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001799 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001800 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001801 }
1802
Geoff Lang69cce582015-09-17 13:20:36 -04001803 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001804 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001805 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001806 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001807 }
1808
1809 return true;
1810}
1811
He Yunchaoced53ae2016-11-29 15:00:51 +08001812bool ValidateDiscardFramebufferEXT(Context *context,
1813 GLenum target,
1814 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001815 const GLenum *attachments)
1816{
Jamie Madillc29968b2016-01-20 11:17:23 -05001817 if (!context->getExtensions().discardFramebuffer)
1818 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001819 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001820 return false;
1821 }
1822
Austin Kinross08332632015-05-05 13:35:47 -07001823 bool defaultFramebuffer = false;
1824
1825 switch (target)
1826 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001827 case GL_FRAMEBUFFER:
1828 defaultFramebuffer =
1829 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1830 break;
1831 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001832 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001833 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001834 }
1835
He Yunchaoced53ae2016-11-29 15:00:51 +08001836 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1837 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001838}
1839
Austin Kinrossbc781f32015-10-26 09:27:38 -07001840bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1841{
1842 if (!context->getExtensions().vertexArrayObject)
1843 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001844 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001845 return false;
1846 }
1847
1848 return ValidateBindVertexArrayBase(context, array);
1849}
1850
Jamie Madilld7576732017-08-26 18:49:50 -04001851bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001852{
1853 if (!context->getExtensions().vertexArrayObject)
1854 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001855 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001856 return false;
1857 }
1858
Olli Etuaho41997e72016-03-10 13:38:39 +02001859 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001860}
1861
Jamie Madilld7576732017-08-26 18:49:50 -04001862bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001863{
1864 if (!context->getExtensions().vertexArrayObject)
1865 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001866 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001867 return false;
1868 }
1869
Olli Etuaho41997e72016-03-10 13:38:39 +02001870 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001871}
1872
Jamie Madilld7576732017-08-26 18:49:50 -04001873bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001874{
1875 if (!context->getExtensions().vertexArrayObject)
1876 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001877 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001878 return false;
1879 }
1880
1881 return true;
1882}
Geoff Langc5629752015-12-07 16:29:04 -05001883
1884bool ValidateProgramBinaryOES(Context *context,
1885 GLuint program,
1886 GLenum binaryFormat,
1887 const void *binary,
1888 GLint length)
1889{
1890 if (!context->getExtensions().getProgramBinary)
1891 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001892 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001893 return false;
1894 }
1895
1896 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1897}
1898
1899bool ValidateGetProgramBinaryOES(Context *context,
1900 GLuint program,
1901 GLsizei bufSize,
1902 GLsizei *length,
1903 GLenum *binaryFormat,
1904 void *binary)
1905{
1906 if (!context->getExtensions().getProgramBinary)
1907 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001908 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001909 return false;
1910 }
1911
1912 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1913}
Geoff Lange102fee2015-12-10 11:23:30 -05001914
Geoff Lang70d0f492015-12-10 17:45:46 -05001915static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1916{
1917 switch (source)
1918 {
1919 case GL_DEBUG_SOURCE_API:
1920 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1921 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1922 case GL_DEBUG_SOURCE_OTHER:
1923 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1924 return !mustBeThirdPartyOrApplication;
1925
1926 case GL_DEBUG_SOURCE_THIRD_PARTY:
1927 case GL_DEBUG_SOURCE_APPLICATION:
1928 return true;
1929
1930 default:
1931 return false;
1932 }
1933}
1934
1935static bool ValidDebugType(GLenum type)
1936{
1937 switch (type)
1938 {
1939 case GL_DEBUG_TYPE_ERROR:
1940 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1941 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1942 case GL_DEBUG_TYPE_PERFORMANCE:
1943 case GL_DEBUG_TYPE_PORTABILITY:
1944 case GL_DEBUG_TYPE_OTHER:
1945 case GL_DEBUG_TYPE_MARKER:
1946 case GL_DEBUG_TYPE_PUSH_GROUP:
1947 case GL_DEBUG_TYPE_POP_GROUP:
1948 return true;
1949
1950 default:
1951 return false;
1952 }
1953}
1954
1955static bool ValidDebugSeverity(GLenum severity)
1956{
1957 switch (severity)
1958 {
1959 case GL_DEBUG_SEVERITY_HIGH:
1960 case GL_DEBUG_SEVERITY_MEDIUM:
1961 case GL_DEBUG_SEVERITY_LOW:
1962 case GL_DEBUG_SEVERITY_NOTIFICATION:
1963 return true;
1964
1965 default:
1966 return false;
1967 }
1968}
1969
Geoff Lange102fee2015-12-10 11:23:30 -05001970bool ValidateDebugMessageControlKHR(Context *context,
1971 GLenum source,
1972 GLenum type,
1973 GLenum severity,
1974 GLsizei count,
1975 const GLuint *ids,
1976 GLboolean enabled)
1977{
1978 if (!context->getExtensions().debug)
1979 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001980 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001981 return false;
1982 }
1983
Geoff Lang70d0f492015-12-10 17:45:46 -05001984 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1985 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001986 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001987 return false;
1988 }
1989
1990 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1991 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001992 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001993 return false;
1994 }
1995
1996 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1997 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001998 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001999 return false;
2000 }
2001
2002 if (count > 0)
2003 {
2004 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002006 context->handleError(
2007 InvalidOperation()
2008 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002009 return false;
2010 }
2011
2012 if (severity != GL_DONT_CARE)
2013 {
Jamie Madill437fa652016-05-03 15:13:24 -04002014 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002015 InvalidOperation()
2016 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002017 return false;
2018 }
2019 }
2020
Geoff Lange102fee2015-12-10 11:23:30 -05002021 return true;
2022}
2023
2024bool ValidateDebugMessageInsertKHR(Context *context,
2025 GLenum source,
2026 GLenum type,
2027 GLuint id,
2028 GLenum severity,
2029 GLsizei length,
2030 const GLchar *buf)
2031{
2032 if (!context->getExtensions().debug)
2033 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002034 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002035 return false;
2036 }
2037
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002038 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002039 {
2040 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2041 // not generate an error.
2042 return false;
2043 }
2044
2045 if (!ValidDebugSeverity(severity))
2046 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002047 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002048 return false;
2049 }
2050
2051 if (!ValidDebugType(type))
2052 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002053 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002054 return false;
2055 }
2056
2057 if (!ValidDebugSource(source, true))
2058 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002059 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002060 return false;
2061 }
2062
2063 size_t messageLength = (length < 0) ? strlen(buf) : length;
2064 if (messageLength > context->getExtensions().maxDebugMessageLength)
2065 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002066 context->handleError(InvalidValue()
2067 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002068 return false;
2069 }
2070
Geoff Lange102fee2015-12-10 11:23:30 -05002071 return true;
2072}
2073
2074bool ValidateDebugMessageCallbackKHR(Context *context,
2075 GLDEBUGPROCKHR callback,
2076 const void *userParam)
2077{
2078 if (!context->getExtensions().debug)
2079 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002081 return false;
2082 }
2083
Geoff Lange102fee2015-12-10 11:23:30 -05002084 return true;
2085}
2086
2087bool ValidateGetDebugMessageLogKHR(Context *context,
2088 GLuint count,
2089 GLsizei bufSize,
2090 GLenum *sources,
2091 GLenum *types,
2092 GLuint *ids,
2093 GLenum *severities,
2094 GLsizei *lengths,
2095 GLchar *messageLog)
2096{
2097 if (!context->getExtensions().debug)
2098 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002099 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002100 return false;
2101 }
2102
Geoff Lang70d0f492015-12-10 17:45:46 -05002103 if (bufSize < 0 && messageLog != nullptr)
2104 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002105 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002106 return false;
2107 }
2108
Geoff Lange102fee2015-12-10 11:23:30 -05002109 return true;
2110}
2111
2112bool ValidatePushDebugGroupKHR(Context *context,
2113 GLenum source,
2114 GLuint id,
2115 GLsizei length,
2116 const GLchar *message)
2117{
2118 if (!context->getExtensions().debug)
2119 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002120 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002121 return false;
2122 }
2123
Geoff Lang70d0f492015-12-10 17:45:46 -05002124 if (!ValidDebugSource(source, true))
2125 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002126 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002127 return false;
2128 }
2129
2130 size_t messageLength = (length < 0) ? strlen(message) : length;
2131 if (messageLength > context->getExtensions().maxDebugMessageLength)
2132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002133 context->handleError(InvalidValue()
2134 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002135 return false;
2136 }
2137
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002138 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002139 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2140 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002141 context
2142 ->handleError(StackOverflow()
2143 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002144 return false;
2145 }
2146
Geoff Lange102fee2015-12-10 11:23:30 -05002147 return true;
2148}
2149
2150bool ValidatePopDebugGroupKHR(Context *context)
2151{
2152 if (!context->getExtensions().debug)
2153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002155 return false;
2156 }
2157
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002158 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002159 if (currentStackSize <= 1)
2160 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002161 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002162 return false;
2163 }
2164
2165 return true;
2166}
2167
2168static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2169{
2170 switch (identifier)
2171 {
2172 case GL_BUFFER:
2173 if (context->getBuffer(name) == nullptr)
2174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002175 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002176 return false;
2177 }
2178 return true;
2179
2180 case GL_SHADER:
2181 if (context->getShader(name) == nullptr)
2182 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002183 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002184 return false;
2185 }
2186 return true;
2187
2188 case GL_PROGRAM:
2189 if (context->getProgram(name) == nullptr)
2190 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002191 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002192 return false;
2193 }
2194 return true;
2195
2196 case GL_VERTEX_ARRAY:
2197 if (context->getVertexArray(name) == nullptr)
2198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002199 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002200 return false;
2201 }
2202 return true;
2203
2204 case GL_QUERY:
2205 if (context->getQuery(name) == nullptr)
2206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002207 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002208 return false;
2209 }
2210 return true;
2211
2212 case GL_TRANSFORM_FEEDBACK:
2213 if (context->getTransformFeedback(name) == nullptr)
2214 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002215 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002216 return false;
2217 }
2218 return true;
2219
2220 case GL_SAMPLER:
2221 if (context->getSampler(name) == nullptr)
2222 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002223 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002224 return false;
2225 }
2226 return true;
2227
2228 case GL_TEXTURE:
2229 if (context->getTexture(name) == nullptr)
2230 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002231 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002232 return false;
2233 }
2234 return true;
2235
2236 case GL_RENDERBUFFER:
2237 if (context->getRenderbuffer(name) == nullptr)
2238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002239 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002240 return false;
2241 }
2242 return true;
2243
2244 case GL_FRAMEBUFFER:
2245 if (context->getFramebuffer(name) == nullptr)
2246 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002247 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002248 return false;
2249 }
2250 return true;
2251
2252 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002253 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002254 return false;
2255 }
Geoff Lange102fee2015-12-10 11:23:30 -05002256}
2257
Martin Radev9d901792016-07-15 15:58:58 +03002258static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2259{
2260 size_t labelLength = 0;
2261
2262 if (length < 0)
2263 {
2264 if (label != nullptr)
2265 {
2266 labelLength = strlen(label);
2267 }
2268 }
2269 else
2270 {
2271 labelLength = static_cast<size_t>(length);
2272 }
2273
2274 if (labelLength > context->getExtensions().maxLabelLength)
2275 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002276 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002277 return false;
2278 }
2279
2280 return true;
2281}
2282
Geoff Lange102fee2015-12-10 11:23:30 -05002283bool ValidateObjectLabelKHR(Context *context,
2284 GLenum identifier,
2285 GLuint name,
2286 GLsizei length,
2287 const GLchar *label)
2288{
2289 if (!context->getExtensions().debug)
2290 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002291 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002292 return false;
2293 }
2294
Geoff Lang70d0f492015-12-10 17:45:46 -05002295 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2296 {
2297 return false;
2298 }
2299
Martin Radev9d901792016-07-15 15:58:58 +03002300 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002301 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002302 return false;
2303 }
2304
Geoff Lange102fee2015-12-10 11:23:30 -05002305 return true;
2306}
2307
2308bool ValidateGetObjectLabelKHR(Context *context,
2309 GLenum identifier,
2310 GLuint name,
2311 GLsizei bufSize,
2312 GLsizei *length,
2313 GLchar *label)
2314{
2315 if (!context->getExtensions().debug)
2316 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002317 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002318 return false;
2319 }
2320
Geoff Lang70d0f492015-12-10 17:45:46 -05002321 if (bufSize < 0)
2322 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002323 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002324 return false;
2325 }
2326
2327 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2328 {
2329 return false;
2330 }
2331
Martin Radev9d901792016-07-15 15:58:58 +03002332 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002333}
2334
2335static bool ValidateObjectPtrName(Context *context, const void *ptr)
2336{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002337 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002338 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002339 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002340 return false;
2341 }
2342
Geoff Lange102fee2015-12-10 11:23:30 -05002343 return true;
2344}
2345
2346bool ValidateObjectPtrLabelKHR(Context *context,
2347 const void *ptr,
2348 GLsizei length,
2349 const GLchar *label)
2350{
2351 if (!context->getExtensions().debug)
2352 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002354 return false;
2355 }
2356
Geoff Lang70d0f492015-12-10 17:45:46 -05002357 if (!ValidateObjectPtrName(context, ptr))
2358 {
2359 return false;
2360 }
2361
Martin Radev9d901792016-07-15 15:58:58 +03002362 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002363 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002364 return false;
2365 }
2366
Geoff Lange102fee2015-12-10 11:23:30 -05002367 return true;
2368}
2369
2370bool ValidateGetObjectPtrLabelKHR(Context *context,
2371 const void *ptr,
2372 GLsizei bufSize,
2373 GLsizei *length,
2374 GLchar *label)
2375{
2376 if (!context->getExtensions().debug)
2377 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002378 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002379 return false;
2380 }
2381
Geoff Lang70d0f492015-12-10 17:45:46 -05002382 if (bufSize < 0)
2383 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002384 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002385 return false;
2386 }
2387
2388 if (!ValidateObjectPtrName(context, ptr))
2389 {
2390 return false;
2391 }
2392
Martin Radev9d901792016-07-15 15:58:58 +03002393 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002394}
2395
2396bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2397{
2398 if (!context->getExtensions().debug)
2399 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002401 return false;
2402 }
2403
Geoff Lang70d0f492015-12-10 17:45:46 -05002404 // TODO: represent this in Context::getQueryParameterInfo.
2405 switch (pname)
2406 {
2407 case GL_DEBUG_CALLBACK_FUNCTION:
2408 case GL_DEBUG_CALLBACK_USER_PARAM:
2409 break;
2410
2411 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002412 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002413 return false;
2414 }
2415
Geoff Lange102fee2015-12-10 11:23:30 -05002416 return true;
2417}
Jamie Madillc29968b2016-01-20 11:17:23 -05002418
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002419bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2420 GLenum pname,
2421 GLsizei bufSize,
2422 GLsizei *length,
2423 void **params)
2424{
2425 UNIMPLEMENTED();
2426 return false;
2427}
2428
Jamie Madillc29968b2016-01-20 11:17:23 -05002429bool ValidateBlitFramebufferANGLE(Context *context,
2430 GLint srcX0,
2431 GLint srcY0,
2432 GLint srcX1,
2433 GLint srcY1,
2434 GLint dstX0,
2435 GLint dstY0,
2436 GLint dstX1,
2437 GLint dstY1,
2438 GLbitfield mask,
2439 GLenum filter)
2440{
2441 if (!context->getExtensions().framebufferBlit)
2442 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002444 return false;
2445 }
2446
2447 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2448 {
2449 // TODO(jmadill): Determine if this should be available on other implementations.
Olli Etuahof0e3c192018-08-15 13:37:21 +03002450 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002451 return false;
2452 }
2453
2454 if (filter == GL_LINEAR)
2455 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002456 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002457 return false;
2458 }
2459
Jamie Madill51f40ec2016-06-15 14:06:00 -04002460 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2461 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002462
2463 if (mask & GL_COLOR_BUFFER_BIT)
2464 {
2465 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2466 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2467
2468 if (readColorAttachment && drawColorAttachment)
2469 {
2470 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002471 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002472 readColorAttachment->type() != GL_RENDERBUFFER &&
2473 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2474 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002475 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2476 BlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002477 return false;
2478 }
2479
Geoff Langa15472a2015-08-11 11:48:03 -04002480 for (size_t drawbufferIdx = 0;
2481 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002482 {
Geoff Langa15472a2015-08-11 11:48:03 -04002483 const FramebufferAttachment *attachment =
2484 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2485 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002486 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002487 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002488 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002489 attachment->type() != GL_RENDERBUFFER &&
2490 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2491 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002492 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2493 BlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002494 return false;
2495 }
2496
2497 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002498 if (!Format::EquivalentForBlit(attachment->getFormat(),
2499 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002500 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002501 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2502 BlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002503 return false;
2504 }
2505 }
2506 }
2507
Jamie Madill427064d2018-04-13 16:20:34 -04002508 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002509 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002510 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2511 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2512 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002513 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2514 BlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002515 return false;
2516 }
2517 }
2518 }
2519
2520 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2521 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2522 for (size_t i = 0; i < 2; i++)
2523 {
2524 if (mask & masks[i])
2525 {
2526 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002527 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002528 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002529 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002530
2531 if (readBuffer && drawBuffer)
2532 {
2533 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2534 dstX0, dstY0, dstX1, dstY1))
2535 {
2536 // only whole-buffer copies are permitted
Olli Etuahof0e3c192018-08-15 13:37:21 +03002537 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2538 BlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002539 return false;
2540 }
2541
2542 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2543 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002544 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2545 BlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002546 return false;
2547 }
2548 }
2549 }
2550 }
2551
2552 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2553 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002554}
Jamie Madillc29968b2016-01-20 11:17:23 -05002555
Jamie Madill5b772312018-03-08 20:28:32 -05002556bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002557{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002558 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002559 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002560
Jamie Madill427064d2018-04-13 16:20:34 -04002561 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002562 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002563 return false;
2564 }
2565
2566 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2567 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002568 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002569 return false;
2570 }
2571
Olli Etuaho94c91a92018-07-19 15:10:24 +03002572 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002573 {
2574 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2575 GL_SIGNED_NORMALIZED};
2576
Corentin Wallez59c41592017-07-11 13:19:54 -04002577 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002578 drawBufferIdx++)
2579 {
2580 if (!ValidateWebGLFramebufferAttachmentClearType(
2581 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2582 {
2583 return false;
2584 }
2585 }
2586 }
2587
Olli Etuaho94c91a92018-07-19 15:10:24 +03002588 if (extensions.multiview && extensions.disjointTimerQuery)
2589 {
2590 const State &state = context->getGLState();
2591 Framebuffer *framebuffer = state.getDrawFramebuffer();
2592 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2593 {
2594 context->handleError(InvalidOperation() << "There is an active query for target "
2595 "GL_TIME_ELAPSED_EXT when the number of "
2596 "views in the active draw framebuffer is "
2597 "greater than 1.");
2598 return false;
2599 }
2600 }
2601
Jamie Madillc29968b2016-01-20 11:17:23 -05002602 return true;
2603}
2604
Jamie Madill5b772312018-03-08 20:28:32 -05002605bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002606{
2607 if (!context->getExtensions().drawBuffers)
2608 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002609 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002610 return false;
2611 }
2612
2613 return ValidateDrawBuffersBase(context, n, bufs);
2614}
2615
Jamie Madill73a84962016-02-12 09:27:23 -05002616bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002617 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002618 GLint level,
2619 GLint internalformat,
2620 GLsizei width,
2621 GLsizei height,
2622 GLint border,
2623 GLenum format,
2624 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002625 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002626{
Martin Radev1be913c2016-07-11 17:59:16 +03002627 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002628 {
2629 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002630 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002631 }
2632
Martin Radev1be913c2016-07-11 17:59:16 +03002633 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002634 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002635 0, 0, width, height, 1, border, format, type, -1,
2636 pixels);
2637}
2638
Brandon Jones416aaf92018-04-10 08:10:16 -07002639bool ValidateTexImage2DRobustANGLE(Context *context,
2640 TextureTarget target,
2641 GLint level,
2642 GLint internalformat,
2643 GLsizei width,
2644 GLsizei height,
2645 GLint border,
2646 GLenum format,
2647 GLenum type,
2648 GLsizei bufSize,
2649 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002650{
2651 if (!ValidateRobustEntryPoint(context, bufSize))
2652 {
2653 return false;
2654 }
2655
2656 if (context->getClientMajorVersion() < 3)
2657 {
2658 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2659 0, 0, width, height, border, format, type, bufSize,
2660 pixels);
2661 }
2662
2663 ASSERT(context->getClientMajorVersion() >= 3);
2664 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2665 0, 0, width, height, 1, border, format, type, bufSize,
2666 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002667}
2668
2669bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002670 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002671 GLint level,
2672 GLint xoffset,
2673 GLint yoffset,
2674 GLsizei width,
2675 GLsizei height,
2676 GLenum format,
2677 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002678 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002679{
2680
Martin Radev1be913c2016-07-11 17:59:16 +03002681 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002682 {
2683 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002684 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002685 }
2686
Martin Radev1be913c2016-07-11 17:59:16 +03002687 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002688 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002689 yoffset, 0, width, height, 1, 0, format, type, -1,
2690 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002691}
2692
Geoff Langc52f6f12016-10-14 10:18:00 -04002693bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002694 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002695 GLint level,
2696 GLint xoffset,
2697 GLint yoffset,
2698 GLsizei width,
2699 GLsizei height,
2700 GLenum format,
2701 GLenum type,
2702 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002703 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002704{
2705 if (!ValidateRobustEntryPoint(context, bufSize))
2706 {
2707 return false;
2708 }
2709
2710 if (context->getClientMajorVersion() < 3)
2711 {
2712 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2713 yoffset, width, height, 0, format, type, bufSize,
2714 pixels);
2715 }
2716
2717 ASSERT(context->getClientMajorVersion() >= 3);
2718 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2719 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2720 pixels);
2721}
2722
Jamie Madill73a84962016-02-12 09:27:23 -05002723bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002724 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002725 GLint level,
2726 GLenum internalformat,
2727 GLsizei width,
2728 GLsizei height,
2729 GLint border,
2730 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002731 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002732{
Martin Radev1be913c2016-07-11 17:59:16 +03002733 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002734 {
2735 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002736 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002737 {
2738 return false;
2739 }
2740 }
2741 else
2742 {
Martin Radev1be913c2016-07-11 17:59:16 +03002743 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002744 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002745 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002746 data))
2747 {
2748 return false;
2749 }
2750 }
2751
Geoff Langca271392017-04-05 12:30:00 -04002752 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002753
2754 GLuint blockSize = 0;
2755 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002756 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002757 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002758 return false;
2759 }
2760
Jamie Madillca2ff382018-07-11 09:01:17 -04002761 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002762 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002763 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002764 return false;
2765 }
2766
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002767 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002768 {
2769 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2770 return false;
2771 }
2772
Jamie Madill73a84962016-02-12 09:27:23 -05002773 return true;
2774}
2775
Corentin Wallezb2931602017-04-11 15:58:57 -04002776bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002777 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002778 GLint level,
2779 GLenum internalformat,
2780 GLsizei width,
2781 GLsizei height,
2782 GLint border,
2783 GLsizei imageSize,
2784 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002785 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002786{
2787 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2788 {
2789 return false;
2790 }
2791
2792 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2793 border, imageSize, data);
2794}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002795
Corentin Wallezb2931602017-04-11 15:58:57 -04002796bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002797 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002798 GLint level,
2799 GLint xoffset,
2800 GLint yoffset,
2801 GLsizei width,
2802 GLsizei height,
2803 GLenum format,
2804 GLsizei imageSize,
2805 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002806 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002807{
2808 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2809 {
2810 return false;
2811 }
2812
2813 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2814 format, imageSize, data);
2815}
2816
Jamie Madill73a84962016-02-12 09:27:23 -05002817bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002818 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002819 GLint level,
2820 GLint xoffset,
2821 GLint yoffset,
2822 GLsizei width,
2823 GLsizei height,
2824 GLenum format,
2825 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002826 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002827{
Martin Radev1be913c2016-07-11 17:59:16 +03002828 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002829 {
2830 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002831 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002832 {
2833 return false;
2834 }
2835 }
2836 else
2837 {
Martin Radev1be913c2016-07-11 17:59:16 +03002838 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002839 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002840 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002841 data))
2842 {
2843 return false;
2844 }
2845 }
2846
Geoff Langca271392017-04-05 12:30:00 -04002847 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002848 GLuint blockSize = 0;
2849 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002850 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002851 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002852 return false;
2853 }
2854
Jamie Madillca2ff382018-07-11 09:01:17 -04002855 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002856 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002857 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002858 return false;
2859 }
2860
2861 return true;
2862}
2863
Corentin Wallez336129f2017-10-17 15:55:40 -04002864bool ValidateGetBufferPointervOES(Context *context,
2865 BufferBinding target,
2866 GLenum pname,
2867 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002868{
Geoff Lang496c02d2016-10-20 11:38:11 -07002869 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002870}
2871
Corentin Wallez336129f2017-10-17 15:55:40 -04002872bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002873{
2874 if (!context->getExtensions().mapBuffer)
2875 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002876 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002877 return false;
2878 }
2879
Corentin Walleze4477002017-12-01 14:39:58 -05002880 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002881 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002882 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002883 return false;
2884 }
2885
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002886 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002887
2888 if (buffer == nullptr)
2889 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002890 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002891 return false;
2892 }
2893
2894 if (access != GL_WRITE_ONLY_OES)
2895 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002896 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002897 return false;
2898 }
2899
2900 if (buffer->isMapped())
2901 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002902 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002903 return false;
2904 }
2905
Geoff Lang79f71042017-08-14 16:43:43 -04002906 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002907}
2908
Corentin Wallez336129f2017-10-17 15:55:40 -04002909bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002910{
2911 if (!context->getExtensions().mapBuffer)
2912 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002913 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002914 return false;
2915 }
2916
2917 return ValidateUnmapBufferBase(context, target);
2918}
2919
2920bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002921 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002922 GLintptr offset,
2923 GLsizeiptr length,
2924 GLbitfield access)
2925{
2926 if (!context->getExtensions().mapBufferRange)
2927 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002928 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002929 return false;
2930 }
2931
2932 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2933}
2934
Corentin Wallez336129f2017-10-17 15:55:40 -04002935bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002936{
2937 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2938 ASSERT(buffer != nullptr);
2939
2940 // Check if this buffer is currently being used as a transform feedback output buffer
2941 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2942 if (transformFeedback != nullptr && transformFeedback->isActive())
2943 {
2944 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2945 {
2946 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2947 if (transformFeedbackBuffer.get() == buffer)
2948 {
2949 context->handleError(InvalidOperation()
2950 << "Buffer is currently bound for transform feedback.");
2951 return false;
2952 }
2953 }
2954 }
2955
James Darpiniane8a93c62018-01-04 18:02:24 -08002956 if (context->getExtensions().webglCompatibility &&
2957 buffer->isBoundForTransformFeedbackAndOtherUse())
2958 {
2959 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2960 return false;
2961 }
2962
Geoff Lang79f71042017-08-14 16:43:43 -04002963 return true;
2964}
2965
Olli Etuaho4f667482016-03-30 15:56:35 +03002966bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002967 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002968 GLintptr offset,
2969 GLsizeiptr length)
2970{
2971 if (!context->getExtensions().mapBufferRange)
2972 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002973 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002974 return false;
2975 }
2976
2977 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2978}
2979
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002980bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002981{
2982 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002983 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002984 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002985 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002986 return false;
2987 }
2988
Geoff Langf41a7152016-09-19 15:11:17 -04002989 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2990 !context->isTextureGenerated(texture))
2991 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002992 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002993 return false;
2994 }
2995
Ian Ewell54f87462016-03-10 13:47:21 -05002996 switch (target)
2997 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002998 case TextureType::_2D:
2999 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05003000 break;
3001
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003002 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003003 if (!context->getExtensions().textureRectangle)
3004 {
3005 context->handleError(InvalidEnum()
3006 << "Context does not support GL_ANGLE_texture_rectangle");
3007 return false;
3008 }
3009 break;
3010
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003011 case TextureType::_3D:
3012 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03003013 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003014 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003015 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003016 return false;
3017 }
3018 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003019
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003020 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003021 if (context->getClientVersion() < Version(3, 1))
3022 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003023 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003024 return false;
3025 }
Geoff Lang3b573612016-10-31 14:08:10 -04003026 break;
3027
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003028 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003029 if (!context->getExtensions().eglImageExternal &&
3030 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003031 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003032 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003033 return false;
3034 }
3035 break;
3036 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003037 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003038 return false;
3039 }
3040
3041 return true;
3042}
3043
Geoff Langd8605522016-04-13 10:19:12 -04003044bool ValidateBindUniformLocationCHROMIUM(Context *context,
3045 GLuint program,
3046 GLint location,
3047 const GLchar *name)
3048{
3049 if (!context->getExtensions().bindUniformLocation)
3050 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003051 context->handleError(InvalidOperation()
3052 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003053 return false;
3054 }
3055
3056 Program *programObject = GetValidProgram(context, program);
3057 if (!programObject)
3058 {
3059 return false;
3060 }
3061
3062 if (location < 0)
3063 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003064 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003065 return false;
3066 }
3067
3068 const Caps &caps = context->getCaps();
3069 if (static_cast<size_t>(location) >=
3070 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003072 context->handleError(InvalidValue() << "Location must be less than "
3073 "(MAX_VERTEX_UNIFORM_VECTORS + "
3074 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003075 return false;
3076 }
3077
Geoff Langfc32e8b2017-05-31 14:16:59 -04003078 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3079 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003080 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003081 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003082 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003083 return false;
3084 }
3085
Geoff Langd8605522016-04-13 10:19:12 -04003086 if (strncmp(name, "gl_", 3) == 0)
3087 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003088 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003089 return false;
3090 }
3091
3092 return true;
3093}
3094
Jamie Madille2e406c2016-06-02 13:04:10 -04003095bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003096{
3097 if (!context->getExtensions().framebufferMixedSamples)
3098 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003099 context->handleError(InvalidOperation()
3100 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003101 return false;
3102 }
3103 switch (components)
3104 {
3105 case GL_RGB:
3106 case GL_RGBA:
3107 case GL_ALPHA:
3108 case GL_NONE:
3109 break;
3110 default:
3111 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003112 InvalidEnum()
3113 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003114 return false;
3115 }
3116
3117 return true;
3118}
3119
Sami Väisänene45e53b2016-05-25 10:36:04 +03003120// CHROMIUM_path_rendering
3121
Jamie Madill007530e2017-12-28 14:27:04 -05003122bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003123{
Jamie Madill007530e2017-12-28 14:27:04 -05003124 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003125 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003126 return false;
3127 }
Jamie Madill007530e2017-12-28 14:27:04 -05003128
Sami Väisänene45e53b2016-05-25 10:36:04 +03003129 if (matrix == nullptr)
3130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003131 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003132 return false;
3133 }
Jamie Madill007530e2017-12-28 14:27:04 -05003134
Sami Väisänene45e53b2016-05-25 10:36:04 +03003135 return true;
3136}
3137
Jamie Madill007530e2017-12-28 14:27:04 -05003138bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003139{
Jamie Madill007530e2017-12-28 14:27:04 -05003140 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003141}
3142
Jamie Madill007530e2017-12-28 14:27:04 -05003143bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003144{
3145 if (!context->getExtensions().pathRendering)
3146 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003147 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003148 return false;
3149 }
3150
3151 // range = 0 is undefined in NV_path_rendering.
3152 // we add stricter semantic check here and require a non zero positive range.
3153 if (range <= 0)
3154 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003155 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003156 return false;
3157 }
3158
3159 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3160 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003161 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003162 return false;
3163 }
3164
3165 return true;
3166}
3167
Jamie Madill007530e2017-12-28 14:27:04 -05003168bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003169{
3170 if (!context->getExtensions().pathRendering)
3171 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003172 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003173 return false;
3174 }
3175
3176 // range = 0 is undefined in NV_path_rendering.
3177 // we add stricter semantic check here and require a non zero positive range.
3178 if (range <= 0)
3179 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003180 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181 return false;
3182 }
3183
3184 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3185 checkedRange += range;
3186
3187 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3188 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003189 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003190 return false;
3191 }
3192 return true;
3193}
3194
Jamie Madill007530e2017-12-28 14:27:04 -05003195bool ValidatePathCommandsCHROMIUM(Context *context,
3196 GLuint path,
3197 GLsizei numCommands,
3198 const GLubyte *commands,
3199 GLsizei numCoords,
3200 GLenum coordType,
3201 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003202{
3203 if (!context->getExtensions().pathRendering)
3204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003205 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003206 return false;
3207 }
Brandon Jones59770802018-04-02 13:18:42 -07003208 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003209 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003210 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003211 return false;
3212 }
3213
3214 if (numCommands < 0)
3215 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003216 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003217 return false;
3218 }
3219 else if (numCommands > 0)
3220 {
3221 if (!commands)
3222 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003223 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003224 return false;
3225 }
3226 }
3227
3228 if (numCoords < 0)
3229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003230 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003231 return false;
3232 }
3233 else if (numCoords > 0)
3234 {
3235 if (!coords)
3236 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003237 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003238 return false;
3239 }
3240 }
3241
3242 std::uint32_t coordTypeSize = 0;
3243 switch (coordType)
3244 {
3245 case GL_BYTE:
3246 coordTypeSize = sizeof(GLbyte);
3247 break;
3248
3249 case GL_UNSIGNED_BYTE:
3250 coordTypeSize = sizeof(GLubyte);
3251 break;
3252
3253 case GL_SHORT:
3254 coordTypeSize = sizeof(GLshort);
3255 break;
3256
3257 case GL_UNSIGNED_SHORT:
3258 coordTypeSize = sizeof(GLushort);
3259 break;
3260
3261 case GL_FLOAT:
3262 coordTypeSize = sizeof(GLfloat);
3263 break;
3264
3265 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003266 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003267 return false;
3268 }
3269
3270 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3271 checkedSize += (coordTypeSize * numCoords);
3272 if (!checkedSize.IsValid())
3273 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003274 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003275 return false;
3276 }
3277
3278 // early return skips command data validation when it doesn't exist.
3279 if (!commands)
3280 return true;
3281
3282 GLsizei expectedNumCoords = 0;
3283 for (GLsizei i = 0; i < numCommands; ++i)
3284 {
3285 switch (commands[i])
3286 {
3287 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3288 break;
3289 case GL_MOVE_TO_CHROMIUM:
3290 case GL_LINE_TO_CHROMIUM:
3291 expectedNumCoords += 2;
3292 break;
3293 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3294 expectedNumCoords += 4;
3295 break;
3296 case GL_CUBIC_CURVE_TO_CHROMIUM:
3297 expectedNumCoords += 6;
3298 break;
3299 case GL_CONIC_CURVE_TO_CHROMIUM:
3300 expectedNumCoords += 5;
3301 break;
3302 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003303 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003304 return false;
3305 }
3306 }
3307 if (expectedNumCoords != numCoords)
3308 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003309 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003310 return false;
3311 }
3312
3313 return true;
3314}
3315
Jamie Madill007530e2017-12-28 14:27:04 -05003316bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317{
3318 if (!context->getExtensions().pathRendering)
3319 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003320 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003321 return false;
3322 }
Brandon Jones59770802018-04-02 13:18:42 -07003323 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003324 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003325 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003326 return false;
3327 }
3328
3329 switch (pname)
3330 {
3331 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3332 if (value < 0.0f)
3333 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003334 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003335 return false;
3336 }
3337 break;
3338 case GL_PATH_END_CAPS_CHROMIUM:
3339 switch (static_cast<GLenum>(value))
3340 {
3341 case GL_FLAT_CHROMIUM:
3342 case GL_SQUARE_CHROMIUM:
3343 case GL_ROUND_CHROMIUM:
3344 break;
3345 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003346 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003347 return false;
3348 }
3349 break;
3350 case GL_PATH_JOIN_STYLE_CHROMIUM:
3351 switch (static_cast<GLenum>(value))
3352 {
3353 case GL_MITER_REVERT_CHROMIUM:
3354 case GL_BEVEL_CHROMIUM:
3355 case GL_ROUND_CHROMIUM:
3356 break;
3357 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003358 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003359 return false;
3360 }
Nico Weber41b072b2018-02-09 10:01:32 -05003361 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003362 case GL_PATH_MITER_LIMIT_CHROMIUM:
3363 if (value < 0.0f)
3364 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003365 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003366 return false;
3367 }
3368 break;
3369
3370 case GL_PATH_STROKE_BOUND_CHROMIUM:
3371 // no errors, only clamping.
3372 break;
3373
3374 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003375 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003376 return false;
3377 }
3378 return true;
3379}
3380
Jamie Madill007530e2017-12-28 14:27:04 -05003381bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3382{
3383 // TODO(jmadill): Use proper clamping cast.
3384 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3385}
3386
3387bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003388{
3389 if (!context->getExtensions().pathRendering)
3390 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003391 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003392 return false;
3393 }
3394
Brandon Jones59770802018-04-02 13:18:42 -07003395 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003396 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003397 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003398 return false;
3399 }
3400 if (!value)
3401 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003402 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003403 return false;
3404 }
3405
3406 switch (pname)
3407 {
3408 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3409 case GL_PATH_END_CAPS_CHROMIUM:
3410 case GL_PATH_JOIN_STYLE_CHROMIUM:
3411 case GL_PATH_MITER_LIMIT_CHROMIUM:
3412 case GL_PATH_STROKE_BOUND_CHROMIUM:
3413 break;
3414
3415 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003416 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003417 return false;
3418 }
3419
3420 return true;
3421}
3422
Jamie Madill007530e2017-12-28 14:27:04 -05003423bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3424{
3425 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3426 reinterpret_cast<GLfloat *>(value));
3427}
3428
3429bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003430{
3431 if (!context->getExtensions().pathRendering)
3432 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003433 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003434 return false;
3435 }
3436
3437 switch (func)
3438 {
3439 case GL_NEVER:
3440 case GL_ALWAYS:
3441 case GL_LESS:
3442 case GL_LEQUAL:
3443 case GL_EQUAL:
3444 case GL_GEQUAL:
3445 case GL_GREATER:
3446 case GL_NOTEQUAL:
3447 break;
3448 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003449 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003450 return false;
3451 }
3452
3453 return true;
3454}
3455
3456// Note that the spec specifies that for the path drawing commands
3457// if the path object is not an existing path object the command
3458// does nothing and no error is generated.
3459// However if the path object exists but has not been specified any
3460// commands then an error is generated.
3461
Jamie Madill007530e2017-12-28 14:27:04 -05003462bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003463{
3464 if (!context->getExtensions().pathRendering)
3465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003466 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003467 return false;
3468 }
Brandon Jones59770802018-04-02 13:18:42 -07003469 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003470 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003471 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003472 return false;
3473 }
3474
3475 switch (fillMode)
3476 {
3477 case GL_COUNT_UP_CHROMIUM:
3478 case GL_COUNT_DOWN_CHROMIUM:
3479 break;
3480 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003481 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003482 return false;
3483 }
3484
3485 if (!isPow2(mask + 1))
3486 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003487 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003488 return false;
3489 }
3490
3491 return true;
3492}
3493
Jamie Madill007530e2017-12-28 14:27:04 -05003494bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003495{
3496 if (!context->getExtensions().pathRendering)
3497 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003498 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003499 return false;
3500 }
Brandon Jones59770802018-04-02 13:18:42 -07003501 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003502 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003503 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003504 return false;
3505 }
3506
3507 return true;
3508}
3509
Brandon Jonesd1049182018-03-28 10:02:20 -07003510bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3511{
3512 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3513}
3514
3515bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3516{
3517 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3518}
3519
Jamie Madill007530e2017-12-28 14:27:04 -05003520bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003521{
3522 if (!context->getExtensions().pathRendering)
3523 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003524 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003525 return false;
3526 }
Brandon Jones59770802018-04-02 13:18:42 -07003527 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003528 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003529 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003530 return false;
3531 }
3532
3533 switch (coverMode)
3534 {
3535 case GL_CONVEX_HULL_CHROMIUM:
3536 case GL_BOUNDING_BOX_CHROMIUM:
3537 break;
3538 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003539 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003540 return false;
3541 }
3542 return true;
3543}
3544
Jamie Madill007530e2017-12-28 14:27:04 -05003545bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3546 GLuint path,
3547 GLenum fillMode,
3548 GLuint mask,
3549 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003550{
Jamie Madill007530e2017-12-28 14:27:04 -05003551 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3552 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003553}
3554
Jamie Madill007530e2017-12-28 14:27:04 -05003555bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3556 GLuint path,
3557 GLint reference,
3558 GLuint mask,
3559 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003560{
Jamie Madill007530e2017-12-28 14:27:04 -05003561 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3562 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003563}
3564
Brandon Jonesd1049182018-03-28 10:02:20 -07003565bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003566{
3567 if (!context->getExtensions().pathRendering)
3568 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003569 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003570 return false;
3571 }
3572 return true;
3573}
3574
Jamie Madill007530e2017-12-28 14:27:04 -05003575bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3576 GLsizei numPaths,
3577 GLenum pathNameType,
3578 const void *paths,
3579 GLuint pathBase,
3580 GLenum coverMode,
3581 GLenum transformType,
3582 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003583{
3584 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3585 transformType, transformValues))
3586 return false;
3587
3588 switch (coverMode)
3589 {
3590 case GL_CONVEX_HULL_CHROMIUM:
3591 case GL_BOUNDING_BOX_CHROMIUM:
3592 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3593 break;
3594 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003595 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003596 return false;
3597 }
3598
3599 return true;
3600}
3601
Jamie Madill007530e2017-12-28 14:27:04 -05003602bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3603 GLsizei numPaths,
3604 GLenum pathNameType,
3605 const void *paths,
3606 GLuint pathBase,
3607 GLenum coverMode,
3608 GLenum transformType,
3609 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003610{
3611 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3612 transformType, transformValues))
3613 return false;
3614
3615 switch (coverMode)
3616 {
3617 case GL_CONVEX_HULL_CHROMIUM:
3618 case GL_BOUNDING_BOX_CHROMIUM:
3619 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3620 break;
3621 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003622 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003623 return false;
3624 }
3625
3626 return true;
3627}
3628
Jamie Madill007530e2017-12-28 14:27:04 -05003629bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3630 GLsizei numPaths,
3631 GLenum pathNameType,
3632 const void *paths,
3633 GLuint pathBase,
3634 GLenum fillMode,
3635 GLuint mask,
3636 GLenum transformType,
3637 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003638{
3639
3640 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3641 transformType, transformValues))
3642 return false;
3643
3644 switch (fillMode)
3645 {
3646 case GL_COUNT_UP_CHROMIUM:
3647 case GL_COUNT_DOWN_CHROMIUM:
3648 break;
3649 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003650 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003651 return false;
3652 }
3653 if (!isPow2(mask + 1))
3654 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003655 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003656 return false;
3657 }
3658 return true;
3659}
3660
Jamie Madill007530e2017-12-28 14:27:04 -05003661bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3662 GLsizei numPaths,
3663 GLenum pathNameType,
3664 const void *paths,
3665 GLuint pathBase,
3666 GLint reference,
3667 GLuint mask,
3668 GLenum transformType,
3669 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003670{
3671 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3672 transformType, transformValues))
3673 return false;
3674
3675 // no more validation here.
3676
3677 return true;
3678}
3679
Jamie Madill007530e2017-12-28 14:27:04 -05003680bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3681 GLsizei numPaths,
3682 GLenum pathNameType,
3683 const void *paths,
3684 GLuint pathBase,
3685 GLenum fillMode,
3686 GLuint mask,
3687 GLenum coverMode,
3688 GLenum transformType,
3689 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003690{
3691 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3692 transformType, transformValues))
3693 return false;
3694
3695 switch (coverMode)
3696 {
3697 case GL_CONVEX_HULL_CHROMIUM:
3698 case GL_BOUNDING_BOX_CHROMIUM:
3699 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3700 break;
3701 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003702 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003703 return false;
3704 }
3705
3706 switch (fillMode)
3707 {
3708 case GL_COUNT_UP_CHROMIUM:
3709 case GL_COUNT_DOWN_CHROMIUM:
3710 break;
3711 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003712 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003713 return false;
3714 }
3715 if (!isPow2(mask + 1))
3716 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003717 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003718 return false;
3719 }
3720
3721 return true;
3722}
3723
Jamie Madill007530e2017-12-28 14:27:04 -05003724bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3725 GLsizei numPaths,
3726 GLenum pathNameType,
3727 const void *paths,
3728 GLuint pathBase,
3729 GLint reference,
3730 GLuint mask,
3731 GLenum coverMode,
3732 GLenum transformType,
3733 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003734{
3735 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3736 transformType, transformValues))
3737 return false;
3738
3739 switch (coverMode)
3740 {
3741 case GL_CONVEX_HULL_CHROMIUM:
3742 case GL_BOUNDING_BOX_CHROMIUM:
3743 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3744 break;
3745 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003746 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003747 return false;
3748 }
3749
3750 return true;
3751}
3752
Jamie Madill007530e2017-12-28 14:27:04 -05003753bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3754 GLuint program,
3755 GLint location,
3756 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003757{
3758 if (!context->getExtensions().pathRendering)
3759 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003760 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003761 return false;
3762 }
3763
3764 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3765 if (location >= MaxLocation)
3766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003767 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003768 return false;
3769 }
3770
3771 const auto *programObject = context->getProgram(program);
3772 if (!programObject)
3773 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003774 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003775 return false;
3776 }
3777
3778 if (!name)
3779 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003780 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003781 return false;
3782 }
3783
3784 if (angle::BeginsWith(name, "gl_"))
3785 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003786 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003787 return false;
3788 }
3789
3790 return true;
3791}
3792
Jamie Madill007530e2017-12-28 14:27:04 -05003793bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3794 GLuint program,
3795 GLint location,
3796 GLenum genMode,
3797 GLint components,
3798 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003799{
3800 if (!context->getExtensions().pathRendering)
3801 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003802 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003803 return false;
3804 }
3805
3806 const auto *programObject = context->getProgram(program);
3807 if (!programObject || programObject->isFlaggedForDeletion())
3808 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003809 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003810 return false;
3811 }
3812
3813 if (!programObject->isLinked())
3814 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003815 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003816 return false;
3817 }
3818
3819 switch (genMode)
3820 {
3821 case GL_NONE:
3822 if (components != 0)
3823 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003824 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003825 return false;
3826 }
3827 break;
3828
3829 case GL_OBJECT_LINEAR_CHROMIUM:
3830 case GL_EYE_LINEAR_CHROMIUM:
3831 case GL_CONSTANT_CHROMIUM:
3832 if (components < 1 || components > 4)
3833 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003834 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003835 return false;
3836 }
3837 if (!coeffs)
3838 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003839 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003840 return false;
3841 }
3842 break;
3843
3844 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003845 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003846 return false;
3847 }
3848
3849 // If the location is -1 then the command is silently ignored
3850 // and no further validation is needed.
3851 if (location == -1)
3852 return true;
3853
jchen103fd614d2018-08-13 12:21:58 +08003854 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003855
3856 if (!binding.valid)
3857 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003858 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003859 return false;
3860 }
3861
3862 if (binding.type != GL_NONE)
3863 {
3864 GLint expectedComponents = 0;
3865 switch (binding.type)
3866 {
3867 case GL_FLOAT:
3868 expectedComponents = 1;
3869 break;
3870 case GL_FLOAT_VEC2:
3871 expectedComponents = 2;
3872 break;
3873 case GL_FLOAT_VEC3:
3874 expectedComponents = 3;
3875 break;
3876 case GL_FLOAT_VEC4:
3877 expectedComponents = 4;
3878 break;
3879 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003880 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003881 InvalidOperation()
3882 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003883 return false;
3884 }
3885 if (expectedComponents != components && genMode != GL_NONE)
3886 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003887 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003888 return false;
3889 }
3890 }
3891 return true;
3892}
3893
Geoff Lang97073d12016-04-20 10:42:34 -07003894bool ValidateCopyTextureCHROMIUM(Context *context,
3895 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003896 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003897 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003898 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003899 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003900 GLint internalFormat,
3901 GLenum destType,
3902 GLboolean unpackFlipY,
3903 GLboolean unpackPremultiplyAlpha,
3904 GLboolean unpackUnmultiplyAlpha)
3905{
3906 if (!context->getExtensions().copyTexture)
3907 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003908 context->handleError(InvalidOperation()
3909 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003910 return false;
3911 }
3912
Geoff Lang4f0e0032017-05-01 16:04:35 -04003913 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003914 if (source == nullptr)
3915 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003916 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003917 return false;
3918 }
3919
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003920 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003921 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003922 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003923 return false;
3924 }
3925
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003926 TextureType sourceType = source->getType();
3927 ASSERT(sourceType != TextureType::CubeMap);
3928 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003929
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003930 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003931 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003932 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003933 return false;
3934 }
3935
Geoff Lang4f0e0032017-05-01 16:04:35 -04003936 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3937 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3938 if (sourceWidth == 0 || sourceHeight == 0)
3939 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003940 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003941 return false;
3942 }
3943
3944 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3945 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003946 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003947 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003948 return false;
3949 }
3950
Geoff Lang63458a32017-10-30 15:16:53 -04003951 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3952 {
3953 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3954 return false;
3955 }
3956
Geoff Lang4f0e0032017-05-01 16:04:35 -04003957 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003958 if (dest == nullptr)
3959 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003960 context->handleError(InvalidValue()
3961 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003962 return false;
3963 }
3964
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003965 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003966 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003967 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003968 return false;
3969 }
3970
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003971 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003972 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003973 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003974 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003975 return false;
3976 }
3977
Geoff Lang97073d12016-04-20 10:42:34 -07003978 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3979 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003980 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003981 return false;
3982 }
3983
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003984 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003985 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003986 context->handleError(
3987 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003988 return false;
3989 }
3990
Geoff Lang97073d12016-04-20 10:42:34 -07003991 if (dest->getImmutableFormat())
3992 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003993 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003994 return false;
3995 }
3996
3997 return true;
3998}
3999
4000bool ValidateCopySubTextureCHROMIUM(Context *context,
4001 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004002 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004003 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004004 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004005 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004006 GLint xoffset,
4007 GLint yoffset,
4008 GLint x,
4009 GLint y,
4010 GLsizei width,
4011 GLsizei height,
4012 GLboolean unpackFlipY,
4013 GLboolean unpackPremultiplyAlpha,
4014 GLboolean unpackUnmultiplyAlpha)
4015{
4016 if (!context->getExtensions().copyTexture)
4017 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004018 context->handleError(InvalidOperation()
4019 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004020 return false;
4021 }
4022
Geoff Lang4f0e0032017-05-01 16:04:35 -04004023 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004024 if (source == nullptr)
4025 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004026 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004027 return false;
4028 }
4029
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004030 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004031 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004032 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004033 return false;
4034 }
4035
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004036 TextureType sourceType = source->getType();
4037 ASSERT(sourceType != TextureType::CubeMap);
4038 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004039
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004040 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004041 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004042 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004043 return false;
4044 }
4045
4046 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4047 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004049 context->handleError(InvalidValue()
4050 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004051 return false;
4052 }
4053
4054 if (x < 0 || y < 0)
4055 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004056 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004057 return false;
4058 }
4059
4060 if (width < 0 || height < 0)
4061 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004062 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004063 return false;
4064 }
4065
Geoff Lang4f0e0032017-05-01 16:04:35 -04004066 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4067 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004068 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004069 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004070 return false;
4071 }
4072
Geoff Lang4f0e0032017-05-01 16:04:35 -04004073 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4074 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004075 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004076 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004077 return false;
4078 }
4079
Geoff Lang63458a32017-10-30 15:16:53 -04004080 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4081 {
4082 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4083 return false;
4084 }
4085
Geoff Lang4f0e0032017-05-01 16:04:35 -04004086 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004087 if (dest == nullptr)
4088 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004089 context->handleError(InvalidValue()
4090 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004091 return false;
4092 }
4093
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004094 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004095 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004096 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004097 return false;
4098 }
4099
Brandon Jones28783792018-03-05 09:37:32 -08004100 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4101 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004103 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004104 return false;
4105 }
4106
Geoff Lang4f0e0032017-05-01 16:04:35 -04004107 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4108 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004109 context
4110 ->handleError(InvalidOperation()
4111 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004112 return false;
4113 }
4114
4115 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4116 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004117 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004118 context->handleError(InvalidOperation()
4119 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004120 return false;
4121 }
4122
4123 if (xoffset < 0 || yoffset < 0)
4124 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004125 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004126 return false;
4127 }
4128
Geoff Lang4f0e0032017-05-01 16:04:35 -04004129 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4130 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004132 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004133 return false;
4134 }
4135
4136 return true;
4137}
4138
Geoff Lang47110bf2016-04-20 11:13:22 -07004139bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4140{
4141 if (!context->getExtensions().copyCompressedTexture)
4142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004143 context->handleError(InvalidOperation()
4144 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004145 return false;
4146 }
4147
4148 const gl::Texture *source = context->getTexture(sourceId);
4149 if (source == nullptr)
4150 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004151 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004152 return false;
4153 }
4154
Corentin Wallez99d492c2018-02-27 15:17:10 -05004155 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004156 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004157 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004158 return false;
4159 }
4160
Corentin Wallez99d492c2018-02-27 15:17:10 -05004161 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4162 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004164 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004165 return false;
4166 }
4167
Corentin Wallez99d492c2018-02-27 15:17:10 -05004168 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004169 if (!sourceFormat.info->compressed)
4170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004171 context->handleError(InvalidOperation()
4172 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004173 return false;
4174 }
4175
4176 const gl::Texture *dest = context->getTexture(destId);
4177 if (dest == nullptr)
4178 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004179 context->handleError(InvalidValue()
4180 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004181 return false;
4182 }
4183
Corentin Wallez99d492c2018-02-27 15:17:10 -05004184 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004186 context->handleError(InvalidValue()
4187 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004188 return false;
4189 }
4190
4191 if (dest->getImmutableFormat())
4192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004193 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004194 return false;
4195 }
4196
4197 return true;
4198}
4199
Jiawei Shao385b3e02018-03-21 09:43:28 +08004200bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004201{
4202 switch (type)
4203 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004204 case ShaderType::Vertex:
4205 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004206 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004207
Jiawei Shao385b3e02018-03-21 09:43:28 +08004208 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004209 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004210 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004211 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004212 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004213 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004214 break;
4215
Jiawei Shao385b3e02018-03-21 09:43:28 +08004216 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004217 if (!context->getExtensions().geometryShader)
4218 {
4219 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4220 return false;
4221 }
4222 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004223 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004224 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004225 return false;
4226 }
Jamie Madill29639852016-09-02 15:00:09 -04004227
4228 return true;
4229}
4230
Jamie Madill5b772312018-03-08 20:28:32 -05004231bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004232 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004233 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004234 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004235 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004236{
4237 if (size < 0)
4238 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004239 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004240 return false;
4241 }
4242
4243 switch (usage)
4244 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004245 case BufferUsage::StreamDraw:
4246 case BufferUsage::StaticDraw:
4247 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004248 break;
4249
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004250 case BufferUsage::StreamRead:
4251 case BufferUsage::StaticRead:
4252 case BufferUsage::DynamicRead:
4253 case BufferUsage::StreamCopy:
4254 case BufferUsage::StaticCopy:
4255 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004256 if (context->getClientMajorVersion() < 3)
4257 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004258 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004259 return false;
4260 }
4261 break;
4262
4263 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004264 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004265 return false;
4266 }
4267
Corentin Walleze4477002017-12-01 14:39:58 -05004268 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004269 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004270 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004271 return false;
4272 }
4273
4274 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4275
4276 if (!buffer)
4277 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004278 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004279 return false;
4280 }
4281
James Darpiniane8a93c62018-01-04 18:02:24 -08004282 if (context->getExtensions().webglCompatibility &&
4283 buffer->isBoundForTransformFeedbackAndOtherUse())
4284 {
4285 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4286 return false;
4287 }
4288
Jamie Madill29639852016-09-02 15:00:09 -04004289 return true;
4290}
4291
Jamie Madill5b772312018-03-08 20:28:32 -05004292bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004293 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004294 GLintptr offset,
4295 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004296 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004297{
Brandon Jones6cad5662017-06-14 13:25:13 -07004298 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004299 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004300 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4301 return false;
4302 }
4303
4304 if (offset < 0)
4305 {
4306 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004307 return false;
4308 }
4309
Corentin Walleze4477002017-12-01 14:39:58 -05004310 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004311 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004312 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004313 return false;
4314 }
4315
4316 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4317
4318 if (!buffer)
4319 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004320 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004321 return false;
4322 }
4323
4324 if (buffer->isMapped())
4325 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004326 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004327 return false;
4328 }
4329
James Darpiniane8a93c62018-01-04 18:02:24 -08004330 if (context->getExtensions().webglCompatibility &&
4331 buffer->isBoundForTransformFeedbackAndOtherUse())
4332 {
4333 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4334 return false;
4335 }
4336
Jamie Madill29639852016-09-02 15:00:09 -04004337 // Check for possible overflow of size + offset
4338 angle::CheckedNumeric<size_t> checkedSize(size);
4339 checkedSize += offset;
4340 if (!checkedSize.IsValid())
4341 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004342 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004343 return false;
4344 }
4345
4346 if (size + offset > buffer->getSize())
4347 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004348 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004349 return false;
4350 }
4351
Martin Radev4c4c8e72016-08-04 12:25:34 +03004352 return true;
4353}
4354
Geoff Lang111a99e2017-10-17 10:58:41 -04004355bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004356{
Geoff Langc339c4e2016-11-29 10:37:36 -05004357 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004358 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004359 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004360 return false;
4361 }
4362
Geoff Lang111a99e2017-10-17 10:58:41 -04004363 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004364 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004365 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004366 return false;
4367 }
4368
4369 return true;
4370}
4371
Jamie Madill5b772312018-03-08 20:28:32 -05004372bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004373{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004374 if (context->getClientMajorVersion() < 2)
4375 {
4376 return ValidateMultitextureUnit(context, texture);
4377 }
4378
Jamie Madillef300b12016-10-07 15:12:09 -04004379 if (texture < GL_TEXTURE0 ||
4380 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4381 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004382 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004383 return false;
4384 }
4385
4386 return true;
4387}
4388
Jamie Madill5b772312018-03-08 20:28:32 -05004389bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004390{
4391 Program *programObject = GetValidProgram(context, program);
4392 if (!programObject)
4393 {
4394 return false;
4395 }
4396
4397 Shader *shaderObject = GetValidShader(context, shader);
4398 if (!shaderObject)
4399 {
4400 return false;
4401 }
4402
Jiawei Shao385b3e02018-03-21 09:43:28 +08004403 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004404 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004405 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4406 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004407 }
4408
4409 return true;
4410}
4411
Jamie Madill5b772312018-03-08 20:28:32 -05004412bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004413{
4414 if (index >= MAX_VERTEX_ATTRIBS)
4415 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004416 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004417 return false;
4418 }
4419
4420 if (strncmp(name, "gl_", 3) == 0)
4421 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004422 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004423 return false;
4424 }
4425
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004426 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004427 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004428 const size_t length = strlen(name);
4429
4430 if (!IsValidESSLString(name, length))
4431 {
4432 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4433 // for shader-related entry points
4434 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4435 return false;
4436 }
4437
4438 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4439 {
4440 return false;
4441 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004442 }
4443
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444 return GetValidProgram(context, program) != nullptr;
4445}
4446
Jamie Madill5b772312018-03-08 20:28:32 -05004447bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004448{
Corentin Walleze4477002017-12-01 14:39:58 -05004449 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004450 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004451 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004452 return false;
4453 }
4454
4455 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4456 !context->isBufferGenerated(buffer))
4457 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004458 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004459 return false;
4460 }
4461
4462 return true;
4463}
4464
Jamie Madill5b772312018-03-08 20:28:32 -05004465bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004466{
Geoff Lange8afa902017-09-27 15:00:43 -04004467 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004468 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004469 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004470 return false;
4471 }
4472
4473 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4474 !context->isFramebufferGenerated(framebuffer))
4475 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004477 return false;
4478 }
4479
4480 return true;
4481}
4482
Jamie Madill5b772312018-03-08 20:28:32 -05004483bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004484{
4485 if (target != GL_RENDERBUFFER)
4486 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004487 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004488 return false;
4489 }
4490
4491 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4492 !context->isRenderbufferGenerated(renderbuffer))
4493 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004494 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004495 return false;
4496 }
4497
4498 return true;
4499}
4500
Jamie Madill5b772312018-03-08 20:28:32 -05004501static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004502{
4503 switch (mode)
4504 {
4505 case GL_FUNC_ADD:
4506 case GL_FUNC_SUBTRACT:
4507 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004508 return true;
4509
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004510 case GL_MIN:
4511 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004512 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004513
4514 default:
4515 return false;
4516 }
4517}
4518
Jamie Madill5b772312018-03-08 20:28:32 -05004519bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004520{
4521 return true;
4522}
4523
Jamie Madill5b772312018-03-08 20:28:32 -05004524bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004525{
Geoff Lang50cac572017-09-26 17:37:43 -04004526 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004527 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004528 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004529 return false;
4530 }
4531
4532 return true;
4533}
4534
Jamie Madill5b772312018-03-08 20:28:32 -05004535bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004536{
Geoff Lang50cac572017-09-26 17:37:43 -04004537 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004538 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004539 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004540 return false;
4541 }
4542
Geoff Lang50cac572017-09-26 17:37:43 -04004543 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004544 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004545 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004546 return false;
4547 }
4548
4549 return true;
4550}
4551
Jamie Madill5b772312018-03-08 20:28:32 -05004552bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004553{
4554 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4555}
4556
4557static bool ValidSrcBlendFunc(GLenum srcBlend)
4558{
4559 switch (srcBlend)
4560 {
4561 case GL_ZERO:
4562 case GL_ONE:
4563 case GL_SRC_COLOR:
4564 case GL_ONE_MINUS_SRC_COLOR:
4565 case GL_DST_COLOR:
4566 case GL_ONE_MINUS_DST_COLOR:
4567 case GL_SRC_ALPHA:
4568 case GL_ONE_MINUS_SRC_ALPHA:
4569 case GL_DST_ALPHA:
4570 case GL_ONE_MINUS_DST_ALPHA:
4571 case GL_CONSTANT_COLOR:
4572 case GL_ONE_MINUS_CONSTANT_COLOR:
4573 case GL_CONSTANT_ALPHA:
4574 case GL_ONE_MINUS_CONSTANT_ALPHA:
4575 case GL_SRC_ALPHA_SATURATE:
4576 return true;
4577
4578 default:
4579 return false;
4580 }
4581}
4582
4583static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4584{
4585 switch (dstBlend)
4586 {
4587 case GL_ZERO:
4588 case GL_ONE:
4589 case GL_SRC_COLOR:
4590 case GL_ONE_MINUS_SRC_COLOR:
4591 case GL_DST_COLOR:
4592 case GL_ONE_MINUS_DST_COLOR:
4593 case GL_SRC_ALPHA:
4594 case GL_ONE_MINUS_SRC_ALPHA:
4595 case GL_DST_ALPHA:
4596 case GL_ONE_MINUS_DST_ALPHA:
4597 case GL_CONSTANT_COLOR:
4598 case GL_ONE_MINUS_CONSTANT_COLOR:
4599 case GL_CONSTANT_ALPHA:
4600 case GL_ONE_MINUS_CONSTANT_ALPHA:
4601 return true;
4602
4603 case GL_SRC_ALPHA_SATURATE:
4604 return (contextMajorVersion >= 3);
4605
4606 default:
4607 return false;
4608 }
4609}
4610
Jamie Madill5b772312018-03-08 20:28:32 -05004611bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004612 GLenum srcRGB,
4613 GLenum dstRGB,
4614 GLenum srcAlpha,
4615 GLenum dstAlpha)
4616{
4617 if (!ValidSrcBlendFunc(srcRGB))
4618 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004619 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004620 return false;
4621 }
4622
4623 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4624 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004625 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004626 return false;
4627 }
4628
4629 if (!ValidSrcBlendFunc(srcAlpha))
4630 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004631 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004632 return false;
4633 }
4634
4635 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4636 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004637 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004638 return false;
4639 }
4640
Frank Henigman146e8a12017-03-02 23:22:37 -05004641 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4642 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004643 {
4644 bool constantColorUsed =
4645 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4646 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4647
4648 bool constantAlphaUsed =
4649 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4650 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4651
4652 if (constantColorUsed && constantAlphaUsed)
4653 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004654 const char *msg;
4655 if (context->getExtensions().webglCompatibility)
4656 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004657 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004658 }
4659 else
4660 {
4661 msg =
4662 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4663 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4664 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004665 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004666 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004667 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004668 return false;
4669 }
4670 }
4671
4672 return true;
4673}
4674
Geoff Langc339c4e2016-11-29 10:37:36 -05004675bool ValidateGetString(Context *context, GLenum name)
4676{
4677 switch (name)
4678 {
4679 case GL_VENDOR:
4680 case GL_RENDERER:
4681 case GL_VERSION:
4682 case GL_SHADING_LANGUAGE_VERSION:
4683 case GL_EXTENSIONS:
4684 break;
4685
4686 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4687 if (!context->getExtensions().requestExtension)
4688 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004689 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004690 return false;
4691 }
4692 break;
4693
4694 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004695 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004696 return false;
4697 }
4698
4699 return true;
4700}
4701
Jamie Madill5b772312018-03-08 20:28:32 -05004702bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004703{
4704 if (width <= 0.0f || isNaN(width))
4705 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004706 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004707 return false;
4708 }
4709
4710 return true;
4711}
4712
Jamie Madill5b772312018-03-08 20:28:32 -05004713bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004714 GLuint index,
4715 GLint size,
4716 GLenum type,
4717 GLboolean normalized,
4718 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004719 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004720{
Shao80957d92017-02-20 21:25:59 +08004721 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004722 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004723 return false;
4724 }
4725
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004726 if (stride < 0)
4727 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004728 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004729 return false;
4730 }
4731
Shao80957d92017-02-20 21:25:59 +08004732 const Caps &caps = context->getCaps();
4733 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004734 {
Shao80957d92017-02-20 21:25:59 +08004735 if (stride > caps.maxVertexAttribStride)
4736 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004737 context->handleError(InvalidValue()
4738 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004739 return false;
4740 }
4741
4742 if (index >= caps.maxVertexAttribBindings)
4743 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004744 context->handleError(InvalidValue()
4745 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004746 return false;
4747 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004748 }
4749
4750 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4751 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4752 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4753 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004754 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4755 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004756 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4757 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004759 context
4760 ->handleError(InvalidOperation()
4761 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004762 return false;
4763 }
4764
4765 if (context->getExtensions().webglCompatibility)
4766 {
4767 // WebGL 1.0 [Section 6.14] Fixed point support
4768 // The WebGL API does not support the GL_FIXED data type.
4769 if (type == GL_FIXED)
4770 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004771 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004772 return false;
4773 }
4774
Geoff Lang2d62ab72017-03-23 16:54:40 -04004775 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004776 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004777 return false;
4778 }
4779 }
4780
4781 return true;
4782}
4783
Jamie Madill5b772312018-03-08 20:28:32 -05004784bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004785{
4786 if (context->getExtensions().webglCompatibility && zNear > zFar)
4787 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004788 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004789 return false;
4790 }
4791
4792 return true;
4793}
4794
Jamie Madill5b772312018-03-08 20:28:32 -05004795bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004796 GLenum target,
4797 GLenum internalformat,
4798 GLsizei width,
4799 GLsizei height)
4800{
4801 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4802 height);
4803}
4804
Jamie Madill5b772312018-03-08 20:28:32 -05004805bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004806 GLenum target,
4807 GLsizei samples,
4808 GLenum internalformat,
4809 GLsizei width,
4810 GLsizei height)
4811{
4812 if (!context->getExtensions().framebufferMultisample)
4813 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004814 context->handleError(InvalidOperation()
4815 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004816 return false;
4817 }
4818
4819 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4820 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4821 // generated.
4822 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4823 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004824 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004825 return false;
4826 }
4827
4828 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4829 // the specified storage. This is different than ES 3.0 in which a sample number higher
4830 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4831 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4832 if (context->getClientMajorVersion() >= 3)
4833 {
4834 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4835 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4836 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004837 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004838 return false;
4839 }
4840 }
4841
4842 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4843 width, height);
4844}
4845
Jamie Madill5b772312018-03-08 20:28:32 -05004846bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004847{
Geoff Lange8afa902017-09-27 15:00:43 -04004848 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004849 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004850 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004851 return false;
4852 }
4853
4854 return true;
4855}
4856
Jamie Madill5b772312018-03-08 20:28:32 -05004857bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004858{
4859 return true;
4860}
4861
Jamie Madill5b772312018-03-08 20:28:32 -05004862bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004863{
4864 return true;
4865}
4866
Jamie Madill5b772312018-03-08 20:28:32 -05004867bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004868{
4869 return true;
4870}
4871
Jamie Madill5b772312018-03-08 20:28:32 -05004872bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004873 GLboolean red,
4874 GLboolean green,
4875 GLboolean blue,
4876 GLboolean alpha)
4877{
4878 return true;
4879}
4880
Jamie Madill5b772312018-03-08 20:28:32 -05004881bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004882{
4883 return true;
4884}
4885
Jamie Madill5b772312018-03-08 20:28:32 -05004886bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004887{
4888 return true;
4889}
4890
Jamie Madill5b772312018-03-08 20:28:32 -05004891bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004892{
4893 switch (mode)
4894 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004895 case CullFaceMode::Front:
4896 case CullFaceMode::Back:
4897 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004898 break;
4899
4900 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004901 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004902 return false;
4903 }
4904
4905 return true;
4906}
4907
Jamie Madill5b772312018-03-08 20:28:32 -05004908bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004909{
4910 if (program == 0)
4911 {
4912 return false;
4913 }
4914
4915 if (!context->getProgram(program))
4916 {
4917 if (context->getShader(program))
4918 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004919 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004920 return false;
4921 }
4922 else
4923 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004924 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004925 return false;
4926 }
4927 }
4928
4929 return true;
4930}
4931
Jamie Madill5b772312018-03-08 20:28:32 -05004932bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004933{
4934 if (shader == 0)
4935 {
4936 return false;
4937 }
4938
4939 if (!context->getShader(shader))
4940 {
4941 if (context->getProgram(shader))
4942 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004943 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004944 return false;
4945 }
4946 else
4947 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004948 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004949 return false;
4950 }
4951 }
4952
4953 return true;
4954}
4955
Jamie Madill5b772312018-03-08 20:28:32 -05004956bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004957{
4958 switch (func)
4959 {
4960 case GL_NEVER:
4961 case GL_ALWAYS:
4962 case GL_LESS:
4963 case GL_LEQUAL:
4964 case GL_EQUAL:
4965 case GL_GREATER:
4966 case GL_GEQUAL:
4967 case GL_NOTEQUAL:
4968 break;
4969
4970 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004971 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004972 return false;
4973 }
4974
4975 return true;
4976}
4977
Jamie Madill5b772312018-03-08 20:28:32 -05004978bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004979{
4980 return true;
4981}
4982
Jamie Madill5b772312018-03-08 20:28:32 -05004983bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004984{
4985 Program *programObject = GetValidProgram(context, program);
4986 if (!programObject)
4987 {
4988 return false;
4989 }
4990
4991 Shader *shaderObject = GetValidShader(context, shader);
4992 if (!shaderObject)
4993 {
4994 return false;
4995 }
4996
Jiawei Shao385b3e02018-03-21 09:43:28 +08004997 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004998 if (attachedShader != shaderObject)
4999 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005000 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005001 return false;
5002 }
5003
5004 return true;
5005}
5006
Jamie Madill5b772312018-03-08 20:28:32 -05005007bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005008{
5009 if (index >= MAX_VERTEX_ATTRIBS)
5010 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005011 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005012 return false;
5013 }
5014
5015 return true;
5016}
5017
Jamie Madill5b772312018-03-08 20:28:32 -05005018bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005019{
5020 if (index >= MAX_VERTEX_ATTRIBS)
5021 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005022 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005023 return false;
5024 }
5025
5026 return true;
5027}
5028
Jamie Madill5b772312018-03-08 20:28:32 -05005029bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005030{
5031 return true;
5032}
5033
Jamie Madill5b772312018-03-08 20:28:32 -05005034bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005035{
5036 return true;
5037}
5038
Jamie Madill5b772312018-03-08 20:28:32 -05005039bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005040{
5041 switch (mode)
5042 {
5043 case GL_CW:
5044 case GL_CCW:
5045 break;
5046 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005047 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005048 return false;
5049 }
5050
5051 return true;
5052}
5053
Jamie Madill5b772312018-03-08 20:28:32 -05005054bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005055 GLuint program,
5056 GLuint index,
5057 GLsizei bufsize,
5058 GLsizei *length,
5059 GLint *size,
5060 GLenum *type,
5061 GLchar *name)
5062{
5063 if (bufsize < 0)
5064 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005065 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005066 return false;
5067 }
5068
5069 Program *programObject = GetValidProgram(context, program);
5070
5071 if (!programObject)
5072 {
5073 return false;
5074 }
5075
5076 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5077 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005078 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005079 return false;
5080 }
5081
5082 return true;
5083}
5084
Jamie Madill5b772312018-03-08 20:28:32 -05005085bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005086 GLuint program,
5087 GLuint index,
5088 GLsizei bufsize,
5089 GLsizei *length,
5090 GLint *size,
5091 GLenum *type,
5092 GLchar *name)
5093{
5094 if (bufsize < 0)
5095 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005096 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005097 return false;
5098 }
5099
5100 Program *programObject = GetValidProgram(context, program);
5101
5102 if (!programObject)
5103 {
5104 return false;
5105 }
5106
5107 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5108 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005109 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110 return false;
5111 }
5112
5113 return true;
5114}
5115
Jamie Madill5b772312018-03-08 20:28:32 -05005116bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005117 GLuint program,
5118 GLsizei maxcount,
5119 GLsizei *count,
5120 GLuint *shaders)
5121{
5122 if (maxcount < 0)
5123 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005124 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005125 return false;
5126 }
5127
5128 Program *programObject = GetValidProgram(context, program);
5129
5130 if (!programObject)
5131 {
5132 return false;
5133 }
5134
5135 return true;
5136}
5137
Jamie Madill5b772312018-03-08 20:28:32 -05005138bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005139{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005140 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5141 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005142 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005144 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005145 return false;
5146 }
5147
Jamie Madillc1d770e2017-04-13 17:31:24 -04005148 Program *programObject = GetValidProgram(context, program);
5149
5150 if (!programObject)
5151 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005152 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005153 return false;
5154 }
5155
5156 if (!programObject->isLinked())
5157 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005158 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005159 return false;
5160 }
5161
5162 return true;
5163}
5164
Jamie Madill5b772312018-03-08 20:28:32 -05005165bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005166{
5167 GLenum nativeType;
5168 unsigned int numParams = 0;
5169 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5170}
5171
Jamie Madill5b772312018-03-08 20:28:32 -05005172bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005173{
5174 return true;
5175}
5176
Jamie Madill5b772312018-03-08 20:28:32 -05005177bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005178{
5179 GLenum nativeType;
5180 unsigned int numParams = 0;
5181 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5182}
5183
Jamie Madill5b772312018-03-08 20:28:32 -05005184bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005185{
5186 GLenum nativeType;
5187 unsigned int numParams = 0;
5188 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5189}
5190
Jamie Madill5b772312018-03-08 20:28:32 -05005191bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005192 GLuint program,
5193 GLsizei bufsize,
5194 GLsizei *length,
5195 GLchar *infolog)
5196{
5197 if (bufsize < 0)
5198 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005199 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005200 return false;
5201 }
5202
5203 Program *programObject = GetValidProgram(context, program);
5204 if (!programObject)
5205 {
5206 return false;
5207 }
5208
5209 return true;
5210}
5211
Jamie Madill5b772312018-03-08 20:28:32 -05005212bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 GLuint shader,
5214 GLsizei bufsize,
5215 GLsizei *length,
5216 GLchar *infolog)
5217{
5218 if (bufsize < 0)
5219 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005220 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005221 return false;
5222 }
5223
5224 Shader *shaderObject = GetValidShader(context, shader);
5225 if (!shaderObject)
5226 {
5227 return false;
5228 }
5229
5230 return true;
5231}
5232
Jamie Madill5b772312018-03-08 20:28:32 -05005233bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005234 GLenum shadertype,
5235 GLenum precisiontype,
5236 GLint *range,
5237 GLint *precision)
5238{
5239 switch (shadertype)
5240 {
5241 case GL_VERTEX_SHADER:
5242 case GL_FRAGMENT_SHADER:
5243 break;
5244 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005245 context->handleError(InvalidOperation()
5246 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005247 return false;
5248 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005249 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005250 return false;
5251 }
5252
5253 switch (precisiontype)
5254 {
5255 case GL_LOW_FLOAT:
5256 case GL_MEDIUM_FLOAT:
5257 case GL_HIGH_FLOAT:
5258 case GL_LOW_INT:
5259 case GL_MEDIUM_INT:
5260 case GL_HIGH_INT:
5261 break;
5262
5263 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005264 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005265 return false;
5266 }
5267
5268 return true;
5269}
5270
Jamie Madill5b772312018-03-08 20:28:32 -05005271bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005272 GLuint shader,
5273 GLsizei bufsize,
5274 GLsizei *length,
5275 GLchar *source)
5276{
5277 if (bufsize < 0)
5278 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005279 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005280 return false;
5281 }
5282
5283 Shader *shaderObject = GetValidShader(context, shader);
5284 if (!shaderObject)
5285 {
5286 return false;
5287 }
5288
5289 return true;
5290}
5291
Jamie Madill5b772312018-03-08 20:28:32 -05005292bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293{
5294 if (strstr(name, "gl_") == name)
5295 {
5296 return false;
5297 }
5298
Geoff Langfc32e8b2017-05-31 14:16:59 -04005299 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5300 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005301 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005302 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005303 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005304 return false;
5305 }
5306
Jamie Madillc1d770e2017-04-13 17:31:24 -04005307 Program *programObject = GetValidProgram(context, program);
5308
5309 if (!programObject)
5310 {
5311 return false;
5312 }
5313
5314 if (!programObject->isLinked())
5315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005317 return false;
5318 }
5319
5320 return true;
5321}
5322
Jamie Madill5b772312018-03-08 20:28:32 -05005323bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005324{
5325 switch (mode)
5326 {
5327 case GL_FASTEST:
5328 case GL_NICEST:
5329 case GL_DONT_CARE:
5330 break;
5331
5332 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005333 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005334 return false;
5335 }
5336
5337 switch (target)
5338 {
5339 case GL_GENERATE_MIPMAP_HINT:
5340 break;
5341
Geoff Lange7bd2182017-06-16 16:13:13 -04005342 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5343 if (context->getClientVersion() < ES_3_0 &&
5344 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005346 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347 return false;
5348 }
5349 break;
5350
5351 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005352 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005353 return false;
5354 }
5355
5356 return true;
5357}
5358
Jamie Madill5b772312018-03-08 20:28:32 -05005359bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005360{
5361 return true;
5362}
5363
Jamie Madill5b772312018-03-08 20:28:32 -05005364bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005365{
5366 return true;
5367}
5368
Jamie Madill5b772312018-03-08 20:28:32 -05005369bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005370{
5371 return true;
5372}
5373
Jamie Madill5b772312018-03-08 20:28:32 -05005374bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005375{
5376 return true;
5377}
5378
Jamie Madill5b772312018-03-08 20:28:32 -05005379bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005380{
5381 return true;
5382}
5383
Jamie Madill5b772312018-03-08 20:28:32 -05005384bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385{
5386 return true;
5387}
5388
Jamie Madill5b772312018-03-08 20:28:32 -05005389bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005390{
5391 if (context->getClientMajorVersion() < 3)
5392 {
5393 switch (pname)
5394 {
5395 case GL_UNPACK_IMAGE_HEIGHT:
5396 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005397 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005398 return false;
5399
5400 case GL_UNPACK_ROW_LENGTH:
5401 case GL_UNPACK_SKIP_ROWS:
5402 case GL_UNPACK_SKIP_PIXELS:
5403 if (!context->getExtensions().unpackSubimage)
5404 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005405 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005406 return false;
5407 }
5408 break;
5409
5410 case GL_PACK_ROW_LENGTH:
5411 case GL_PACK_SKIP_ROWS:
5412 case GL_PACK_SKIP_PIXELS:
5413 if (!context->getExtensions().packSubimage)
5414 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005415 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005416 return false;
5417 }
5418 break;
5419 }
5420 }
5421
5422 if (param < 0)
5423 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005424 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005425 return false;
5426 }
5427
5428 switch (pname)
5429 {
5430 case GL_UNPACK_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_ALIGNMENT:
5439 if (param != 1 && param != 2 && param != 4 && param != 8)
5440 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005441 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005442 return false;
5443 }
5444 break;
5445
5446 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005447 if (!context->getExtensions().packReverseRowOrder)
5448 {
5449 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5450 }
5451 break;
5452
Jamie Madillc1d770e2017-04-13 17:31:24 -04005453 case GL_UNPACK_ROW_LENGTH:
5454 case GL_UNPACK_IMAGE_HEIGHT:
5455 case GL_UNPACK_SKIP_IMAGES:
5456 case GL_UNPACK_SKIP_ROWS:
5457 case GL_UNPACK_SKIP_PIXELS:
5458 case GL_PACK_ROW_LENGTH:
5459 case GL_PACK_SKIP_ROWS:
5460 case GL_PACK_SKIP_PIXELS:
5461 break;
5462
5463 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005464 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005465 return false;
5466 }
5467
5468 return true;
5469}
5470
Jamie Madill5b772312018-03-08 20:28:32 -05005471bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005472{
5473 return true;
5474}
5475
Jamie Madill5b772312018-03-08 20:28:32 -05005476bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477{
5478 return true;
5479}
5480
Jamie Madill5b772312018-03-08 20:28:32 -05005481bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005482{
5483 return true;
5484}
5485
Jamie Madill5b772312018-03-08 20:28:32 -05005486bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005487{
5488 if (width < 0 || height < 0)
5489 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005490 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005491 return false;
5492 }
5493
5494 return true;
5495}
5496
Jamie Madill5b772312018-03-08 20:28:32 -05005497bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005498 GLsizei n,
5499 const GLuint *shaders,
5500 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005501 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005502 GLsizei length)
5503{
5504 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5505 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5506 shaderBinaryFormats.end())
5507 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005508 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005509 return false;
5510 }
5511
5512 return true;
5513}
5514
Jamie Madill5b772312018-03-08 20:28:32 -05005515bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005516 GLuint shader,
5517 GLsizei count,
5518 const GLchar *const *string,
5519 const GLint *length)
5520{
5521 if (count < 0)
5522 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005523 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005524 return false;
5525 }
5526
Geoff Langfc32e8b2017-05-31 14:16:59 -04005527 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5528 // shader-related entry points
5529 if (context->getExtensions().webglCompatibility)
5530 {
5531 for (GLsizei i = 0; i < count; i++)
5532 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005533 size_t len =
5534 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005535
5536 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005537 if (!IsValidESSLShaderSourceString(string[i], len,
5538 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005539 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005540 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005541 return false;
5542 }
5543 }
5544 }
5545
Jamie Madillc1d770e2017-04-13 17:31:24 -04005546 Shader *shaderObject = GetValidShader(context, shader);
5547 if (!shaderObject)
5548 {
5549 return false;
5550 }
5551
5552 return true;
5553}
5554
Jamie Madill5b772312018-03-08 20:28:32 -05005555bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556{
5557 if (!IsValidStencilFunc(func))
5558 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005559 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005560 return false;
5561 }
5562
5563 return true;
5564}
5565
Jamie Madill5b772312018-03-08 20:28:32 -05005566bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005567{
5568 if (!IsValidStencilFace(face))
5569 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005570 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005571 return false;
5572 }
5573
5574 if (!IsValidStencilFunc(func))
5575 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005576 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005577 return false;
5578 }
5579
5580 return true;
5581}
5582
Jamie Madill5b772312018-03-08 20:28:32 -05005583bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005584{
5585 return true;
5586}
5587
Jamie Madill5b772312018-03-08 20:28:32 -05005588bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005589{
5590 if (!IsValidStencilFace(face))
5591 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005592 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005593 return false;
5594 }
5595
5596 return true;
5597}
5598
Jamie Madill5b772312018-03-08 20:28:32 -05005599bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005600{
5601 if (!IsValidStencilOp(fail))
5602 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005603 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005604 return false;
5605 }
5606
5607 if (!IsValidStencilOp(zfail))
5608 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005609 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005610 return false;
5611 }
5612
5613 if (!IsValidStencilOp(zpass))
5614 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005615 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005616 return false;
5617 }
5618
5619 return true;
5620}
5621
Jamie Madill5b772312018-03-08 20:28:32 -05005622bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005623 GLenum face,
5624 GLenum fail,
5625 GLenum zfail,
5626 GLenum zpass)
5627{
5628 if (!IsValidStencilFace(face))
5629 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005630 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005631 return false;
5632 }
5633
5634 return ValidateStencilOp(context, fail, zfail, zpass);
5635}
5636
Jamie Madill5b772312018-03-08 20:28:32 -05005637bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005638{
5639 return ValidateUniform(context, GL_FLOAT, location, 1);
5640}
5641
Jamie Madill5b772312018-03-08 20:28:32 -05005642bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005643{
5644 return ValidateUniform(context, GL_FLOAT, location, count);
5645}
5646
Jamie Madill5b772312018-03-08 20:28:32 -05005647bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005648{
5649 return ValidateUniform1iv(context, location, 1, &x);
5650}
5651
Jamie Madill5b772312018-03-08 20:28:32 -05005652bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005653{
5654 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5655}
5656
Jamie Madill5b772312018-03-08 20:28:32 -05005657bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005658{
5659 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5660}
5661
Jamie Madill5b772312018-03-08 20:28:32 -05005662bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005663{
5664 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5665}
5666
Jamie Madill5b772312018-03-08 20:28:32 -05005667bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005668{
5669 return ValidateUniform(context, GL_INT_VEC2, location, count);
5670}
5671
Jamie Madill5b772312018-03-08 20:28:32 -05005672bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005673{
5674 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5675}
5676
Jamie Madill5b772312018-03-08 20:28:32 -05005677bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005678{
5679 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5680}
5681
Jamie Madill5b772312018-03-08 20:28:32 -05005682bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005683{
5684 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5685}
5686
Jamie Madill5b772312018-03-08 20:28:32 -05005687bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005688{
5689 return ValidateUniform(context, GL_INT_VEC3, location, count);
5690}
5691
Jamie Madill5b772312018-03-08 20:28:32 -05005692bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005693{
5694 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5695}
5696
Jamie Madill5b772312018-03-08 20:28:32 -05005697bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005698{
5699 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5700}
5701
Jamie Madill5b772312018-03-08 20:28:32 -05005702bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005703{
5704 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5705}
5706
Jamie Madill5b772312018-03-08 20:28:32 -05005707bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005708{
5709 return ValidateUniform(context, GL_INT_VEC4, location, count);
5710}
5711
Jamie Madill5b772312018-03-08 20:28:32 -05005712bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005713 GLint location,
5714 GLsizei count,
5715 GLboolean transpose,
5716 const GLfloat *value)
5717{
5718 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5719}
5720
Jamie Madill5b772312018-03-08 20:28:32 -05005721bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005722 GLint location,
5723 GLsizei count,
5724 GLboolean transpose,
5725 const GLfloat *value)
5726{
5727 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5728}
5729
Jamie Madill5b772312018-03-08 20:28:32 -05005730bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005731 GLint location,
5732 GLsizei count,
5733 GLboolean transpose,
5734 const GLfloat *value)
5735{
5736 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5737}
5738
Jamie Madill5b772312018-03-08 20:28:32 -05005739bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005740{
5741 Program *programObject = GetValidProgram(context, program);
5742
5743 if (!programObject)
5744 {
5745 return false;
5746 }
5747
5748 return true;
5749}
5750
Jamie Madill5b772312018-03-08 20:28:32 -05005751bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005752{
5753 return ValidateVertexAttribIndex(context, index);
5754}
5755
Jamie Madill5b772312018-03-08 20:28:32 -05005756bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005757{
5758 return ValidateVertexAttribIndex(context, index);
5759}
5760
Jamie Madill5b772312018-03-08 20:28:32 -05005761bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005762{
5763 return ValidateVertexAttribIndex(context, index);
5764}
5765
Jamie Madill5b772312018-03-08 20:28:32 -05005766bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005767{
5768 return ValidateVertexAttribIndex(context, index);
5769}
5770
Jamie Madill5b772312018-03-08 20:28:32 -05005771bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005772{
5773 return ValidateVertexAttribIndex(context, index);
5774}
5775
Jamie Madill5b772312018-03-08 20:28:32 -05005776bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005777{
5778 return ValidateVertexAttribIndex(context, index);
5779}
5780
Jamie Madill5b772312018-03-08 20:28:32 -05005781bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005782 GLuint index,
5783 GLfloat x,
5784 GLfloat y,
5785 GLfloat z,
5786 GLfloat w)
5787{
5788 return ValidateVertexAttribIndex(context, index);
5789}
5790
Jamie Madill5b772312018-03-08 20:28:32 -05005791bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005792{
5793 return ValidateVertexAttribIndex(context, index);
5794}
5795
Jamie Madill5b772312018-03-08 20:28:32 -05005796bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005797{
5798 if (width < 0 || height < 0)
5799 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005800 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005801 return false;
5802 }
5803
5804 return true;
5805}
5806
Jamie Madill493f9572018-05-24 19:52:15 -04005807bool ValidateDrawArrays(Context *context, PrimitiveMode mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005808{
5809 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5810}
5811
Jamie Madill5b772312018-03-08 20:28:32 -05005812bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005813 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005814 GLsizei count,
5815 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005816 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005817{
5818 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5819}
5820
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005821bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005822 GLenum target,
5823 GLenum attachment,
5824 GLenum pname,
5825 GLint *params)
5826{
5827 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5828 nullptr);
5829}
5830
Jamie Madill5b772312018-03-08 20:28:32 -05005831bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005832{
5833 return ValidateGetProgramivBase(context, program, pname, nullptr);
5834}
5835
Jamie Madill5b772312018-03-08 20:28:32 -05005836bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005837 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005838 GLint level,
5839 GLenum internalformat,
5840 GLint x,
5841 GLint y,
5842 GLsizei width,
5843 GLsizei height,
5844 GLint border)
5845{
5846 if (context->getClientMajorVersion() < 3)
5847 {
5848 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5849 0, x, y, width, height, border);
5850 }
5851
5852 ASSERT(context->getClientMajorVersion() == 3);
5853 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5854 0, x, y, width, height, border);
5855}
5856
5857bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005858 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005859 GLint level,
5860 GLint xoffset,
5861 GLint yoffset,
5862 GLint x,
5863 GLint y,
5864 GLsizei width,
5865 GLsizei height)
5866{
5867 if (context->getClientMajorVersion() < 3)
5868 {
5869 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5870 yoffset, x, y, width, height, 0);
5871 }
5872
5873 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5874 yoffset, 0, x, y, width, height, 0);
5875}
5876
5877bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5878{
5879 return ValidateGenOrDelete(context, n);
5880}
5881
5882bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5883{
5884 return ValidateGenOrDelete(context, n);
5885}
5886
5887bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5888{
5889 return ValidateGenOrDelete(context, n);
5890}
5891
5892bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5893{
5894 return ValidateGenOrDelete(context, n);
5895}
5896
5897bool ValidateDisable(Context *context, GLenum cap)
5898{
5899 if (!ValidCap(context, cap, false))
5900 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005901 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005902 return false;
5903 }
5904
5905 return true;
5906}
5907
5908bool ValidateEnable(Context *context, GLenum cap)
5909{
5910 if (!ValidCap(context, cap, false))
5911 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005912 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005913 return false;
5914 }
5915
5916 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5917 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5918 {
5919 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005920 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005921
5922 // We also output an error message to the debugger window if tracing is active, so that
5923 // developers can see the error message.
5924 ERR() << errorMessage;
5925 return false;
5926 }
5927
5928 return true;
5929}
5930
5931bool ValidateFramebufferRenderbuffer(Context *context,
5932 GLenum target,
5933 GLenum attachment,
5934 GLenum renderbuffertarget,
5935 GLuint renderbuffer)
5936{
Geoff Lange8afa902017-09-27 15:00:43 -04005937 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005938 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005939 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5940 return false;
5941 }
5942
5943 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5944 {
5945 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005946 return false;
5947 }
5948
5949 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5950 renderbuffertarget, renderbuffer);
5951}
5952
5953bool ValidateFramebufferTexture2D(Context *context,
5954 GLenum target,
5955 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005956 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005957 GLuint texture,
5958 GLint level)
5959{
5960 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5961 // extension
5962 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5963 level != 0)
5964 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005965 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005966 return false;
5967 }
5968
5969 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5970 {
5971 return false;
5972 }
5973
5974 if (texture != 0)
5975 {
5976 gl::Texture *tex = context->getTexture(texture);
5977 ASSERT(tex);
5978
5979 const gl::Caps &caps = context->getCaps();
5980
5981 switch (textarget)
5982 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005983 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005984 {
5985 if (level > gl::log2(caps.max2DTextureSize))
5986 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005987 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005988 return false;
5989 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005990 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005991 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005992 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005993 return false;
5994 }
5995 }
5996 break;
5997
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005998 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005999 {
6000 if (level != 0)
6001 {
6002 context->handleError(InvalidValue());
6003 return false;
6004 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006005 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006006 {
6007 context->handleError(InvalidOperation()
6008 << "Textarget must match the texture target type.");
6009 return false;
6010 }
6011 }
6012 break;
6013
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006014 case TextureTarget::CubeMapNegativeX:
6015 case TextureTarget::CubeMapNegativeY:
6016 case TextureTarget::CubeMapNegativeZ:
6017 case TextureTarget::CubeMapPositiveX:
6018 case TextureTarget::CubeMapPositiveY:
6019 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006020 {
6021 if (level > gl::log2(caps.maxCubeMapTextureSize))
6022 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006023 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006024 return false;
6025 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006026 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006027 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006028 context->handleError(InvalidOperation()
6029 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006030 return false;
6031 }
6032 }
6033 break;
6034
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006035 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006036 {
6037 if (context->getClientVersion() < ES_3_1)
6038 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006039 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006040 return false;
6041 }
6042
6043 if (level != 0)
6044 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006045 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006046 return false;
6047 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006048 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006050 context->handleError(InvalidOperation()
6051 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006052 return false;
6053 }
6054 }
6055 break;
6056
6057 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006058 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006059 return false;
6060 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006061 }
6062
6063 return true;
6064}
6065
6066bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6067{
6068 return ValidateGenOrDelete(context, n);
6069}
6070
6071bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6072{
6073 return ValidateGenOrDelete(context, n);
6074}
6075
6076bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6077{
6078 return ValidateGenOrDelete(context, n);
6079}
6080
6081bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6082{
6083 return ValidateGenOrDelete(context, n);
6084}
6085
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006086bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006087{
6088 if (!ValidTextureTarget(context, target))
6089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006090 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006091 return false;
6092 }
6093
6094 Texture *texture = context->getTargetTexture(target);
6095
6096 if (texture == nullptr)
6097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006098 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006099 return false;
6100 }
6101
6102 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6103
6104 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6105 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6106 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6107 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006108 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006109 return false;
6110 }
6111
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006112 TextureTarget baseTarget = (target == TextureType::CubeMap)
6113 ? TextureTarget::CubeMapPositiveX
6114 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006115 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6116 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6117 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006118 {
6119 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6120 return false;
6121 }
6122
Geoff Lang536eca12017-09-13 11:23:35 -04006123 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6124 bool formatUnsized = !format.sized;
6125 bool formatColorRenderableAndFilterable =
6126 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006127 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006128 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006129 {
Geoff Lang536eca12017-09-13 11:23:35 -04006130 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006131 return false;
6132 }
6133
Geoff Lang536eca12017-09-13 11:23:35 -04006134 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6135 // generation
6136 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6137 {
6138 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6139 return false;
6140 }
6141
Jiange2c00842018-07-13 16:50:49 +08006142 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6143 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6144 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006145 {
Geoff Lang536eca12017-09-13 11:23:35 -04006146 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006147 return false;
6148 }
6149
6150 // Non-power of 2 ES2 check
6151 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6152 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6153 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6154 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006155 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6156 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006158 return false;
6159 }
6160
6161 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006162 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006163 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006164 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006165 return false;
6166 }
6167
6168 return true;
6169}
6170
Jamie Madill5b772312018-03-08 20:28:32 -05006171bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006172 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006173 GLenum pname,
6174 GLint *params)
6175{
6176 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6177}
6178
6179bool ValidateGetRenderbufferParameteriv(Context *context,
6180 GLenum target,
6181 GLenum pname,
6182 GLint *params)
6183{
6184 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6185}
6186
6187bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6188{
6189 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6190}
6191
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006192bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006193{
6194 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6195}
6196
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006197bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006198{
6199 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6200}
6201
6202bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6203{
6204 return ValidateGetUniformBase(context, program, location);
6205}
6206
6207bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6208{
6209 return ValidateGetUniformBase(context, program, location);
6210}
6211
6212bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6213{
6214 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6215}
6216
6217bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6218{
6219 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6220}
6221
6222bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6223{
6224 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6225}
6226
6227bool ValidateIsEnabled(Context *context, GLenum cap)
6228{
6229 if (!ValidCap(context, cap, true))
6230 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006231 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006232 return false;
6233 }
6234
6235 return true;
6236}
6237
6238bool ValidateLinkProgram(Context *context, GLuint program)
6239{
6240 if (context->hasActiveTransformFeedback(program))
6241 {
6242 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006243 context->handleError(InvalidOperation() << "Cannot link program while program is "
6244 "associated with an active transform "
6245 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006246 return false;
6247 }
6248
6249 Program *programObject = GetValidProgram(context, program);
6250 if (!programObject)
6251 {
6252 return false;
6253 }
6254
6255 return true;
6256}
6257
Jamie Madill4928b7c2017-06-20 12:57:39 -04006258bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006259 GLint x,
6260 GLint y,
6261 GLsizei width,
6262 GLsizei height,
6263 GLenum format,
6264 GLenum type,
6265 void *pixels)
6266{
6267 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6268 nullptr, pixels);
6269}
6270
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006271bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006272{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006273 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006274}
6275
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006276bool ValidateTexParameterfv(Context *context,
6277 TextureType target,
6278 GLenum pname,
6279 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006280{
6281 return ValidateTexParameterBase(context, target, pname, -1, params);
6282}
6283
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006284bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006285{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006286 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006287}
6288
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006289bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006290{
6291 return ValidateTexParameterBase(context, target, pname, -1, params);
6292}
6293
6294bool ValidateUseProgram(Context *context, GLuint program)
6295{
6296 if (program != 0)
6297 {
6298 Program *programObject = context->getProgram(program);
6299 if (!programObject)
6300 {
6301 // ES 3.1.0 section 7.3 page 72
6302 if (context->getShader(program))
6303 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006304 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006305 return false;
6306 }
6307 else
6308 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006309 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006310 return false;
6311 }
6312 }
6313 if (!programObject->isLinked())
6314 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006315 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006316 return false;
6317 }
6318 }
6319 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6320 {
6321 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006322 context
6323 ->handleError(InvalidOperation()
6324 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006325 return false;
6326 }
6327
6328 return true;
6329}
6330
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006331bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6332{
6333 if (!context->getExtensions().fence)
6334 {
6335 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6336 return false;
6337 }
6338
6339 if (n < 0)
6340 {
6341 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6342 return false;
6343 }
6344
6345 return true;
6346}
6347
6348bool ValidateFinishFenceNV(Context *context, GLuint fence)
6349{
6350 if (!context->getExtensions().fence)
6351 {
6352 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6353 return false;
6354 }
6355
6356 FenceNV *fenceObject = context->getFenceNV(fence);
6357
6358 if (fenceObject == nullptr)
6359 {
6360 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6361 return false;
6362 }
6363
6364 if (!fenceObject->isSet())
6365 {
6366 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6367 return false;
6368 }
6369
6370 return true;
6371}
6372
6373bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6374{
6375 if (!context->getExtensions().fence)
6376 {
6377 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6378 return false;
6379 }
6380
6381 if (n < 0)
6382 {
6383 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6384 return false;
6385 }
6386
6387 return true;
6388}
6389
6390bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6391{
6392 if (!context->getExtensions().fence)
6393 {
6394 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6395 return false;
6396 }
6397
6398 FenceNV *fenceObject = context->getFenceNV(fence);
6399
6400 if (fenceObject == nullptr)
6401 {
6402 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6403 return false;
6404 }
6405
6406 if (!fenceObject->isSet())
6407 {
6408 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6409 return false;
6410 }
6411
6412 switch (pname)
6413 {
6414 case GL_FENCE_STATUS_NV:
6415 case GL_FENCE_CONDITION_NV:
6416 break;
6417
6418 default:
6419 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6420 return false;
6421 }
6422
6423 return true;
6424}
6425
6426bool ValidateGetGraphicsResetStatusEXT(Context *context)
6427{
6428 if (!context->getExtensions().robustness)
6429 {
6430 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6431 return false;
6432 }
6433
6434 return true;
6435}
6436
6437bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6438 GLuint shader,
6439 GLsizei bufsize,
6440 GLsizei *length,
6441 GLchar *source)
6442{
6443 if (!context->getExtensions().translatedShaderSource)
6444 {
6445 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6446 return false;
6447 }
6448
6449 if (bufsize < 0)
6450 {
6451 context->handleError(InvalidValue());
6452 return false;
6453 }
6454
6455 Shader *shaderObject = context->getShader(shader);
6456
6457 if (!shaderObject)
6458 {
6459 context->handleError(InvalidOperation());
6460 return false;
6461 }
6462
6463 return true;
6464}
6465
6466bool ValidateIsFenceNV(Context *context, GLuint fence)
6467{
6468 if (!context->getExtensions().fence)
6469 {
6470 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6471 return false;
6472 }
6473
6474 return true;
6475}
6476
Jamie Madill007530e2017-12-28 14:27:04 -05006477bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6478{
6479 if (!context->getExtensions().fence)
6480 {
6481 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6482 return false;
6483 }
6484
6485 if (condition != GL_ALL_COMPLETED_NV)
6486 {
6487 context->handleError(InvalidEnum());
6488 return false;
6489 }
6490
6491 FenceNV *fenceObject = context->getFenceNV(fence);
6492
6493 if (fenceObject == nullptr)
6494 {
6495 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6496 return false;
6497 }
6498
6499 return true;
6500}
6501
6502bool ValidateTestFenceNV(Context *context, GLuint fence)
6503{
6504 if (!context->getExtensions().fence)
6505 {
6506 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6507 return false;
6508 }
6509
6510 FenceNV *fenceObject = context->getFenceNV(fence);
6511
6512 if (fenceObject == nullptr)
6513 {
6514 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6515 return false;
6516 }
6517
6518 if (fenceObject->isSet() != GL_TRUE)
6519 {
6520 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6521 return false;
6522 }
6523
6524 return true;
6525}
6526
6527bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006528 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006529 GLsizei levels,
6530 GLenum internalformat,
6531 GLsizei width,
6532 GLsizei height)
6533{
6534 if (!context->getExtensions().textureStorage)
6535 {
6536 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6537 return false;
6538 }
6539
6540 if (context->getClientMajorVersion() < 3)
6541 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006542 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006543 height);
6544 }
6545
6546 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006547 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006548 1);
6549}
6550
6551bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6552{
6553 if (!context->getExtensions().instancedArrays)
6554 {
6555 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6556 return false;
6557 }
6558
6559 if (index >= MAX_VERTEX_ATTRIBS)
6560 {
6561 context->handleError(InvalidValue());
6562 return false;
6563 }
6564
6565 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6566 {
6567 if (index == 0 && divisor != 0)
6568 {
6569 const char *errorMessage =
6570 "The current context doesn't support setting a non-zero divisor on the "
6571 "attribute with index zero. "
6572 "Please reorder the attributes in your vertex shader so that attribute zero "
6573 "can have a zero divisor.";
6574 context->handleError(InvalidOperation() << errorMessage);
6575
6576 // We also output an error message to the debugger window if tracing is active, so
6577 // that developers can see the error message.
6578 ERR() << errorMessage;
6579 return false;
6580 }
6581 }
6582
6583 return true;
6584}
6585
6586bool ValidateTexImage3DOES(Context *context,
6587 GLenum target,
6588 GLint level,
6589 GLenum internalformat,
6590 GLsizei width,
6591 GLsizei height,
6592 GLsizei depth,
6593 GLint border,
6594 GLenum format,
6595 GLenum type,
6596 const void *pixels)
6597{
6598 UNIMPLEMENTED(); // FIXME
6599 return false;
6600}
6601
6602bool ValidatePopGroupMarkerEXT(Context *context)
6603{
6604 if (!context->getExtensions().debugMarker)
6605 {
6606 // The debug marker calls should not set error state
6607 // However, it seems reasonable to set an error state if the extension is not enabled
6608 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6609 return false;
6610 }
6611
6612 return true;
6613}
6614
Jamie Madillfa920eb2018-01-04 11:45:50 -05006615bool ValidateTexStorage1DEXT(Context *context,
6616 GLenum target,
6617 GLsizei levels,
6618 GLenum internalformat,
6619 GLsizei width)
6620{
6621 UNIMPLEMENTED();
6622 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6623 return false;
6624}
6625
6626bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006627 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006628 GLsizei levels,
6629 GLenum internalformat,
6630 GLsizei width,
6631 GLsizei height,
6632 GLsizei depth)
6633{
6634 if (!context->getExtensions().textureStorage)
6635 {
6636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6637 return false;
6638 }
6639
6640 if (context->getClientMajorVersion() < 3)
6641 {
6642 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6643 return false;
6644 }
6645
6646 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6647 depth);
6648}
6649
jchen1082af6202018-06-22 10:59:52 +08006650bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6651{
6652 if (!context->getExtensions().parallelShaderCompile)
6653 {
6654 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6655 return false;
6656 }
6657 return true;
6658}
6659
Jamie Madillc29968b2016-01-20 11:17:23 -05006660} // namespace gl