blob: 88d775f2e109e711c5983ca26442f0248cb8792a [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 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002443 context->handleError(InvalidOperation() << "Blit extension not available.");
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.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002450 context->handleError(InvalidOperation() << "Scaling and flipping in "
2451 "BlitFramebufferANGLE not supported by this "
2452 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002453 return false;
2454 }
2455
2456 if (filter == GL_LINEAR)
2457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002458 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002459 return false;
2460 }
2461
Jamie Madill51f40ec2016-06-15 14:06:00 -04002462 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2463 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002464
2465 if (mask & GL_COLOR_BUFFER_BIT)
2466 {
2467 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2468 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2469
2470 if (readColorAttachment && drawColorAttachment)
2471 {
2472 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002473 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002474 readColorAttachment->type() != GL_RENDERBUFFER &&
2475 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2476 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002477 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002478 return false;
2479 }
2480
Geoff Langa15472a2015-08-11 11:48:03 -04002481 for (size_t drawbufferIdx = 0;
2482 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 {
Geoff Langa15472a2015-08-11 11:48:03 -04002484 const FramebufferAttachment *attachment =
2485 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2486 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002487 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002488 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002489 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002490 attachment->type() != GL_RENDERBUFFER &&
2491 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2492 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002493 context->handleError(InvalidOperation());
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 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002501 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002502 return false;
2503 }
2504 }
2505 }
2506
Jamie Madill427064d2018-04-13 16:20:34 -04002507 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002508 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002509 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2510 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2511 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002512 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002513 return false;
2514 }
2515 }
2516 }
2517
2518 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2519 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2520 for (size_t i = 0; i < 2; i++)
2521 {
2522 if (mask & masks[i])
2523 {
2524 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002525 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002526 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002527 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002528
2529 if (readBuffer && drawBuffer)
2530 {
2531 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2532 dstX0, dstY0, dstX1, dstY1))
2533 {
2534 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002535 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2536 "stencil blits are supported by "
2537 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 return false;
2539 }
2540
2541 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2542 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002543 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002544 return false;
2545 }
2546 }
2547 }
2548 }
2549
2550 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2551 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002552}
Jamie Madillc29968b2016-01-20 11:17:23 -05002553
Jamie Madill5b772312018-03-08 20:28:32 -05002554bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002555{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002556 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002557 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002558
Jamie Madill427064d2018-04-13 16:20:34 -04002559 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002560 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002561 return false;
2562 }
2563
2564 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2565 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002566 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002567 return false;
2568 }
2569
Olli Etuaho94c91a92018-07-19 15:10:24 +03002570 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002571 {
2572 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2573 GL_SIGNED_NORMALIZED};
2574
Corentin Wallez59c41592017-07-11 13:19:54 -04002575 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002576 drawBufferIdx++)
2577 {
2578 if (!ValidateWebGLFramebufferAttachmentClearType(
2579 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2580 {
2581 return false;
2582 }
2583 }
2584 }
2585
Olli Etuaho94c91a92018-07-19 15:10:24 +03002586 if (extensions.multiview && extensions.disjointTimerQuery)
2587 {
2588 const State &state = context->getGLState();
2589 Framebuffer *framebuffer = state.getDrawFramebuffer();
2590 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2591 {
2592 context->handleError(InvalidOperation() << "There is an active query for target "
2593 "GL_TIME_ELAPSED_EXT when the number of "
2594 "views in the active draw framebuffer is "
2595 "greater than 1.");
2596 return false;
2597 }
2598 }
2599
Jamie Madillc29968b2016-01-20 11:17:23 -05002600 return true;
2601}
2602
Jamie Madill5b772312018-03-08 20:28:32 -05002603bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002604{
2605 if (!context->getExtensions().drawBuffers)
2606 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002607 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002608 return false;
2609 }
2610
2611 return ValidateDrawBuffersBase(context, n, bufs);
2612}
2613
Jamie Madill73a84962016-02-12 09:27:23 -05002614bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002615 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002616 GLint level,
2617 GLint internalformat,
2618 GLsizei width,
2619 GLsizei height,
2620 GLint border,
2621 GLenum format,
2622 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002623 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002624{
Martin Radev1be913c2016-07-11 17:59:16 +03002625 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002626 {
2627 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002628 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002629 }
2630
Martin Radev1be913c2016-07-11 17:59:16 +03002631 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002632 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002633 0, 0, width, height, 1, border, format, type, -1,
2634 pixels);
2635}
2636
Brandon Jones416aaf92018-04-10 08:10:16 -07002637bool ValidateTexImage2DRobustANGLE(Context *context,
2638 TextureTarget target,
2639 GLint level,
2640 GLint internalformat,
2641 GLsizei width,
2642 GLsizei height,
2643 GLint border,
2644 GLenum format,
2645 GLenum type,
2646 GLsizei bufSize,
2647 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002648{
2649 if (!ValidateRobustEntryPoint(context, bufSize))
2650 {
2651 return false;
2652 }
2653
2654 if (context->getClientMajorVersion() < 3)
2655 {
2656 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2657 0, 0, width, height, border, format, type, bufSize,
2658 pixels);
2659 }
2660
2661 ASSERT(context->getClientMajorVersion() >= 3);
2662 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2663 0, 0, width, height, 1, border, format, type, bufSize,
2664 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002665}
2666
2667bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002668 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002669 GLint level,
2670 GLint xoffset,
2671 GLint yoffset,
2672 GLsizei width,
2673 GLsizei height,
2674 GLenum format,
2675 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002676 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002677{
2678
Martin Radev1be913c2016-07-11 17:59:16 +03002679 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002680 {
2681 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002682 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002683 }
2684
Martin Radev1be913c2016-07-11 17:59:16 +03002685 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002686 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002687 yoffset, 0, width, height, 1, 0, format, type, -1,
2688 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002689}
2690
Geoff Langc52f6f12016-10-14 10:18:00 -04002691bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002692 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002693 GLint level,
2694 GLint xoffset,
2695 GLint yoffset,
2696 GLsizei width,
2697 GLsizei height,
2698 GLenum format,
2699 GLenum type,
2700 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002701 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002702{
2703 if (!ValidateRobustEntryPoint(context, bufSize))
2704 {
2705 return false;
2706 }
2707
2708 if (context->getClientMajorVersion() < 3)
2709 {
2710 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2711 yoffset, width, height, 0, format, type, bufSize,
2712 pixels);
2713 }
2714
2715 ASSERT(context->getClientMajorVersion() >= 3);
2716 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2717 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2718 pixels);
2719}
2720
Jamie Madill73a84962016-02-12 09:27:23 -05002721bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002722 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002723 GLint level,
2724 GLenum internalformat,
2725 GLsizei width,
2726 GLsizei height,
2727 GLint border,
2728 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002729 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002730{
Martin Radev1be913c2016-07-11 17:59:16 +03002731 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002732 {
2733 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002734 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002735 {
2736 return false;
2737 }
2738 }
2739 else
2740 {
Martin Radev1be913c2016-07-11 17:59:16 +03002741 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002742 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002743 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002744 data))
2745 {
2746 return false;
2747 }
2748 }
2749
Geoff Langca271392017-04-05 12:30:00 -04002750 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002751
2752 GLuint blockSize = 0;
2753 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002754 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002755 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002756 return false;
2757 }
2758
Jamie Madillca2ff382018-07-11 09:01:17 -04002759 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002760 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002761 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002762 return false;
2763 }
2764
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002765 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002766 {
2767 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2768 return false;
2769 }
2770
Jamie Madill73a84962016-02-12 09:27:23 -05002771 return true;
2772}
2773
Corentin Wallezb2931602017-04-11 15:58:57 -04002774bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002775 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002776 GLint level,
2777 GLenum internalformat,
2778 GLsizei width,
2779 GLsizei height,
2780 GLint border,
2781 GLsizei imageSize,
2782 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002783 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002784{
2785 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2786 {
2787 return false;
2788 }
2789
2790 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2791 border, imageSize, data);
2792}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002793
Corentin Wallezb2931602017-04-11 15:58:57 -04002794bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002795 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002796 GLint level,
2797 GLint xoffset,
2798 GLint yoffset,
2799 GLsizei width,
2800 GLsizei height,
2801 GLenum format,
2802 GLsizei imageSize,
2803 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002804 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002805{
2806 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2807 {
2808 return false;
2809 }
2810
2811 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2812 format, imageSize, data);
2813}
2814
Jamie Madill73a84962016-02-12 09:27:23 -05002815bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002816 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002817 GLint level,
2818 GLint xoffset,
2819 GLint yoffset,
2820 GLsizei width,
2821 GLsizei height,
2822 GLenum format,
2823 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002824 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002825{
Martin Radev1be913c2016-07-11 17:59:16 +03002826 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002827 {
2828 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002829 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002830 {
2831 return false;
2832 }
2833 }
2834 else
2835 {
Martin Radev1be913c2016-07-11 17:59:16 +03002836 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002837 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002838 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002839 data))
2840 {
2841 return false;
2842 }
2843 }
2844
Geoff Langca271392017-04-05 12:30:00 -04002845 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002846 GLuint blockSize = 0;
2847 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002848 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002849 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002850 return false;
2851 }
2852
Jamie Madillca2ff382018-07-11 09:01:17 -04002853 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002854 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002855 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002856 return false;
2857 }
2858
2859 return true;
2860}
2861
Corentin Wallez336129f2017-10-17 15:55:40 -04002862bool ValidateGetBufferPointervOES(Context *context,
2863 BufferBinding target,
2864 GLenum pname,
2865 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002866{
Geoff Lang496c02d2016-10-20 11:38:11 -07002867 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002868}
2869
Corentin Wallez336129f2017-10-17 15:55:40 -04002870bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002871{
2872 if (!context->getExtensions().mapBuffer)
2873 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002874 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002875 return false;
2876 }
2877
Corentin Walleze4477002017-12-01 14:39:58 -05002878 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002879 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002880 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002881 return false;
2882 }
2883
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002884 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002885
2886 if (buffer == nullptr)
2887 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002888 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002889 return false;
2890 }
2891
2892 if (access != GL_WRITE_ONLY_OES)
2893 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002894 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002895 return false;
2896 }
2897
2898 if (buffer->isMapped())
2899 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002900 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002901 return false;
2902 }
2903
Geoff Lang79f71042017-08-14 16:43:43 -04002904 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002905}
2906
Corentin Wallez336129f2017-10-17 15:55:40 -04002907bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002908{
2909 if (!context->getExtensions().mapBuffer)
2910 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002911 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002912 return false;
2913 }
2914
2915 return ValidateUnmapBufferBase(context, target);
2916}
2917
2918bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002919 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002920 GLintptr offset,
2921 GLsizeiptr length,
2922 GLbitfield access)
2923{
2924 if (!context->getExtensions().mapBufferRange)
2925 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002926 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002927 return false;
2928 }
2929
2930 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2931}
2932
Corentin Wallez336129f2017-10-17 15:55:40 -04002933bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002934{
2935 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2936 ASSERT(buffer != nullptr);
2937
2938 // Check if this buffer is currently being used as a transform feedback output buffer
2939 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2940 if (transformFeedback != nullptr && transformFeedback->isActive())
2941 {
2942 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2943 {
2944 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2945 if (transformFeedbackBuffer.get() == buffer)
2946 {
2947 context->handleError(InvalidOperation()
2948 << "Buffer is currently bound for transform feedback.");
2949 return false;
2950 }
2951 }
2952 }
2953
James Darpiniane8a93c62018-01-04 18:02:24 -08002954 if (context->getExtensions().webglCompatibility &&
2955 buffer->isBoundForTransformFeedbackAndOtherUse())
2956 {
2957 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2958 return false;
2959 }
2960
Geoff Lang79f71042017-08-14 16:43:43 -04002961 return true;
2962}
2963
Olli Etuaho4f667482016-03-30 15:56:35 +03002964bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002965 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002966 GLintptr offset,
2967 GLsizeiptr length)
2968{
2969 if (!context->getExtensions().mapBufferRange)
2970 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002971 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002972 return false;
2973 }
2974
2975 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2976}
2977
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002978bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002979{
2980 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002981 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002982 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002983 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002984 return false;
2985 }
2986
Geoff Langf41a7152016-09-19 15:11:17 -04002987 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2988 !context->isTextureGenerated(texture))
2989 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002990 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002991 return false;
2992 }
2993
Ian Ewell54f87462016-03-10 13:47:21 -05002994 switch (target)
2995 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002996 case TextureType::_2D:
2997 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002998 break;
2999
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003000 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003001 if (!context->getExtensions().textureRectangle)
3002 {
3003 context->handleError(InvalidEnum()
3004 << "Context does not support GL_ANGLE_texture_rectangle");
3005 return false;
3006 }
3007 break;
3008
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003009 case TextureType::_3D:
3010 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03003011 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003012 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003013 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003014 return false;
3015 }
3016 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003017
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003018 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003019 if (context->getClientVersion() < Version(3, 1))
3020 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003021 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003022 return false;
3023 }
Geoff Lang3b573612016-10-31 14:08:10 -04003024 break;
3025
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003026 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003027 if (!context->getExtensions().eglImageExternal &&
3028 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003029 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003030 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003031 return false;
3032 }
3033 break;
3034 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003035 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003036 return false;
3037 }
3038
3039 return true;
3040}
3041
Geoff Langd8605522016-04-13 10:19:12 -04003042bool ValidateBindUniformLocationCHROMIUM(Context *context,
3043 GLuint program,
3044 GLint location,
3045 const GLchar *name)
3046{
3047 if (!context->getExtensions().bindUniformLocation)
3048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003049 context->handleError(InvalidOperation()
3050 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003051 return false;
3052 }
3053
3054 Program *programObject = GetValidProgram(context, program);
3055 if (!programObject)
3056 {
3057 return false;
3058 }
3059
3060 if (location < 0)
3061 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003062 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003063 return false;
3064 }
3065
3066 const Caps &caps = context->getCaps();
3067 if (static_cast<size_t>(location) >=
3068 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3069 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003070 context->handleError(InvalidValue() << "Location must be less than "
3071 "(MAX_VERTEX_UNIFORM_VECTORS + "
3072 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003073 return false;
3074 }
3075
Geoff Langfc32e8b2017-05-31 14:16:59 -04003076 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3077 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003078 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003079 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003080 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003081 return false;
3082 }
3083
Geoff Langd8605522016-04-13 10:19:12 -04003084 if (strncmp(name, "gl_", 3) == 0)
3085 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003086 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003087 return false;
3088 }
3089
3090 return true;
3091}
3092
Jamie Madille2e406c2016-06-02 13:04:10 -04003093bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003094{
3095 if (!context->getExtensions().framebufferMixedSamples)
3096 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003097 context->handleError(InvalidOperation()
3098 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003099 return false;
3100 }
3101 switch (components)
3102 {
3103 case GL_RGB:
3104 case GL_RGBA:
3105 case GL_ALPHA:
3106 case GL_NONE:
3107 break;
3108 default:
3109 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003110 InvalidEnum()
3111 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003112 return false;
3113 }
3114
3115 return true;
3116}
3117
Sami Väisänene45e53b2016-05-25 10:36:04 +03003118// CHROMIUM_path_rendering
3119
Jamie Madill007530e2017-12-28 14:27:04 -05003120bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003121{
Jamie Madill007530e2017-12-28 14:27:04 -05003122 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003123 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003124 return false;
3125 }
Jamie Madill007530e2017-12-28 14:27:04 -05003126
Sami Väisänene45e53b2016-05-25 10:36:04 +03003127 if (matrix == nullptr)
3128 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003129 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003130 return false;
3131 }
Jamie Madill007530e2017-12-28 14:27:04 -05003132
Sami Väisänene45e53b2016-05-25 10:36:04 +03003133 return true;
3134}
3135
Jamie Madill007530e2017-12-28 14:27:04 -05003136bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003137{
Jamie Madill007530e2017-12-28 14:27:04 -05003138 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003139}
3140
Jamie Madill007530e2017-12-28 14:27:04 -05003141bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003142{
3143 if (!context->getExtensions().pathRendering)
3144 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003145 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003146 return false;
3147 }
3148
3149 // range = 0 is undefined in NV_path_rendering.
3150 // we add stricter semantic check here and require a non zero positive range.
3151 if (range <= 0)
3152 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003153 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003154 return false;
3155 }
3156
3157 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003160 return false;
3161 }
3162
3163 return true;
3164}
3165
Jamie Madill007530e2017-12-28 14:27:04 -05003166bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003167{
3168 if (!context->getExtensions().pathRendering)
3169 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003170 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003171 return false;
3172 }
3173
3174 // range = 0 is undefined in NV_path_rendering.
3175 // we add stricter semantic check here and require a non zero positive range.
3176 if (range <= 0)
3177 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003178 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003179 return false;
3180 }
3181
3182 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3183 checkedRange += range;
3184
3185 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3186 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003187 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003188 return false;
3189 }
3190 return true;
3191}
3192
Jamie Madill007530e2017-12-28 14:27:04 -05003193bool ValidatePathCommandsCHROMIUM(Context *context,
3194 GLuint path,
3195 GLsizei numCommands,
3196 const GLubyte *commands,
3197 GLsizei numCoords,
3198 GLenum coordType,
3199 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003200{
3201 if (!context->getExtensions().pathRendering)
3202 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003203 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003204 return false;
3205 }
Brandon Jones59770802018-04-02 13:18:42 -07003206 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003207 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003208 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003209 return false;
3210 }
3211
3212 if (numCommands < 0)
3213 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003214 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003215 return false;
3216 }
3217 else if (numCommands > 0)
3218 {
3219 if (!commands)
3220 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003221 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003222 return false;
3223 }
3224 }
3225
3226 if (numCoords < 0)
3227 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003228 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003229 return false;
3230 }
3231 else if (numCoords > 0)
3232 {
3233 if (!coords)
3234 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003235 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003236 return false;
3237 }
3238 }
3239
3240 std::uint32_t coordTypeSize = 0;
3241 switch (coordType)
3242 {
3243 case GL_BYTE:
3244 coordTypeSize = sizeof(GLbyte);
3245 break;
3246
3247 case GL_UNSIGNED_BYTE:
3248 coordTypeSize = sizeof(GLubyte);
3249 break;
3250
3251 case GL_SHORT:
3252 coordTypeSize = sizeof(GLshort);
3253 break;
3254
3255 case GL_UNSIGNED_SHORT:
3256 coordTypeSize = sizeof(GLushort);
3257 break;
3258
3259 case GL_FLOAT:
3260 coordTypeSize = sizeof(GLfloat);
3261 break;
3262
3263 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003264 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003265 return false;
3266 }
3267
3268 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3269 checkedSize += (coordTypeSize * numCoords);
3270 if (!checkedSize.IsValid())
3271 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003272 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003273 return false;
3274 }
3275
3276 // early return skips command data validation when it doesn't exist.
3277 if (!commands)
3278 return true;
3279
3280 GLsizei expectedNumCoords = 0;
3281 for (GLsizei i = 0; i < numCommands; ++i)
3282 {
3283 switch (commands[i])
3284 {
3285 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3286 break;
3287 case GL_MOVE_TO_CHROMIUM:
3288 case GL_LINE_TO_CHROMIUM:
3289 expectedNumCoords += 2;
3290 break;
3291 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3292 expectedNumCoords += 4;
3293 break;
3294 case GL_CUBIC_CURVE_TO_CHROMIUM:
3295 expectedNumCoords += 6;
3296 break;
3297 case GL_CONIC_CURVE_TO_CHROMIUM:
3298 expectedNumCoords += 5;
3299 break;
3300 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003301 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003302 return false;
3303 }
3304 }
3305 if (expectedNumCoords != numCoords)
3306 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003307 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003308 return false;
3309 }
3310
3311 return true;
3312}
3313
Jamie Madill007530e2017-12-28 14:27:04 -05003314bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003315{
3316 if (!context->getExtensions().pathRendering)
3317 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003318 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003319 return false;
3320 }
Brandon Jones59770802018-04-02 13:18:42 -07003321 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003322 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003323 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003324 return false;
3325 }
3326
3327 switch (pname)
3328 {
3329 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3330 if (value < 0.0f)
3331 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003332 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003333 return false;
3334 }
3335 break;
3336 case GL_PATH_END_CAPS_CHROMIUM:
3337 switch (static_cast<GLenum>(value))
3338 {
3339 case GL_FLAT_CHROMIUM:
3340 case GL_SQUARE_CHROMIUM:
3341 case GL_ROUND_CHROMIUM:
3342 break;
3343 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003344 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003345 return false;
3346 }
3347 break;
3348 case GL_PATH_JOIN_STYLE_CHROMIUM:
3349 switch (static_cast<GLenum>(value))
3350 {
3351 case GL_MITER_REVERT_CHROMIUM:
3352 case GL_BEVEL_CHROMIUM:
3353 case GL_ROUND_CHROMIUM:
3354 break;
3355 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003356 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003357 return false;
3358 }
Nico Weber41b072b2018-02-09 10:01:32 -05003359 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003360 case GL_PATH_MITER_LIMIT_CHROMIUM:
3361 if (value < 0.0f)
3362 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003363 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003364 return false;
3365 }
3366 break;
3367
3368 case GL_PATH_STROKE_BOUND_CHROMIUM:
3369 // no errors, only clamping.
3370 break;
3371
3372 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003373 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003374 return false;
3375 }
3376 return true;
3377}
3378
Jamie Madill007530e2017-12-28 14:27:04 -05003379bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3380{
3381 // TODO(jmadill): Use proper clamping cast.
3382 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3383}
3384
3385bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003386{
3387 if (!context->getExtensions().pathRendering)
3388 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003389 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003390 return false;
3391 }
3392
Brandon Jones59770802018-04-02 13:18:42 -07003393 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003394 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003396 return false;
3397 }
3398 if (!value)
3399 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003400 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003401 return false;
3402 }
3403
3404 switch (pname)
3405 {
3406 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3407 case GL_PATH_END_CAPS_CHROMIUM:
3408 case GL_PATH_JOIN_STYLE_CHROMIUM:
3409 case GL_PATH_MITER_LIMIT_CHROMIUM:
3410 case GL_PATH_STROKE_BOUND_CHROMIUM:
3411 break;
3412
3413 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003414 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003415 return false;
3416 }
3417
3418 return true;
3419}
3420
Jamie Madill007530e2017-12-28 14:27:04 -05003421bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3422{
3423 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3424 reinterpret_cast<GLfloat *>(value));
3425}
3426
3427bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003428{
3429 if (!context->getExtensions().pathRendering)
3430 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003431 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003432 return false;
3433 }
3434
3435 switch (func)
3436 {
3437 case GL_NEVER:
3438 case GL_ALWAYS:
3439 case GL_LESS:
3440 case GL_LEQUAL:
3441 case GL_EQUAL:
3442 case GL_GEQUAL:
3443 case GL_GREATER:
3444 case GL_NOTEQUAL:
3445 break;
3446 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003447 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003448 return false;
3449 }
3450
3451 return true;
3452}
3453
3454// Note that the spec specifies that for the path drawing commands
3455// if the path object is not an existing path object the command
3456// does nothing and no error is generated.
3457// However if the path object exists but has not been specified any
3458// commands then an error is generated.
3459
Jamie Madill007530e2017-12-28 14:27:04 -05003460bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003461{
3462 if (!context->getExtensions().pathRendering)
3463 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003464 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003465 return false;
3466 }
Brandon Jones59770802018-04-02 13:18:42 -07003467 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003468 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003469 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003470 return false;
3471 }
3472
3473 switch (fillMode)
3474 {
3475 case GL_COUNT_UP_CHROMIUM:
3476 case GL_COUNT_DOWN_CHROMIUM:
3477 break;
3478 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003479 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003480 return false;
3481 }
3482
3483 if (!isPow2(mask + 1))
3484 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003485 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003486 return false;
3487 }
3488
3489 return true;
3490}
3491
Jamie Madill007530e2017-12-28 14:27:04 -05003492bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003493{
3494 if (!context->getExtensions().pathRendering)
3495 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003496 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003497 return false;
3498 }
Brandon Jones59770802018-04-02 13:18:42 -07003499 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003500 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003501 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003502 return false;
3503 }
3504
3505 return true;
3506}
3507
Brandon Jonesd1049182018-03-28 10:02:20 -07003508bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3509{
3510 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3511}
3512
3513bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3514{
3515 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3516}
3517
Jamie Madill007530e2017-12-28 14:27:04 -05003518bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003519{
3520 if (!context->getExtensions().pathRendering)
3521 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003522 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003523 return false;
3524 }
Brandon Jones59770802018-04-02 13:18:42 -07003525 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003526 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003527 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003528 return false;
3529 }
3530
3531 switch (coverMode)
3532 {
3533 case GL_CONVEX_HULL_CHROMIUM:
3534 case GL_BOUNDING_BOX_CHROMIUM:
3535 break;
3536 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003537 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003538 return false;
3539 }
3540 return true;
3541}
3542
Jamie Madill007530e2017-12-28 14:27:04 -05003543bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3544 GLuint path,
3545 GLenum fillMode,
3546 GLuint mask,
3547 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003548{
Jamie Madill007530e2017-12-28 14:27:04 -05003549 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3550 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003551}
3552
Jamie Madill007530e2017-12-28 14:27:04 -05003553bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3554 GLuint path,
3555 GLint reference,
3556 GLuint mask,
3557 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003558{
Jamie Madill007530e2017-12-28 14:27:04 -05003559 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3560 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003561}
3562
Brandon Jonesd1049182018-03-28 10:02:20 -07003563bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003564{
3565 if (!context->getExtensions().pathRendering)
3566 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003567 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003568 return false;
3569 }
3570 return true;
3571}
3572
Jamie Madill007530e2017-12-28 14:27:04 -05003573bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3574 GLsizei numPaths,
3575 GLenum pathNameType,
3576 const void *paths,
3577 GLuint pathBase,
3578 GLenum coverMode,
3579 GLenum transformType,
3580 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003581{
3582 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3583 transformType, transformValues))
3584 return false;
3585
3586 switch (coverMode)
3587 {
3588 case GL_CONVEX_HULL_CHROMIUM:
3589 case GL_BOUNDING_BOX_CHROMIUM:
3590 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3591 break;
3592 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003593 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003594 return false;
3595 }
3596
3597 return true;
3598}
3599
Jamie Madill007530e2017-12-28 14:27:04 -05003600bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3601 GLsizei numPaths,
3602 GLenum pathNameType,
3603 const void *paths,
3604 GLuint pathBase,
3605 GLenum coverMode,
3606 GLenum transformType,
3607 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003608{
3609 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3610 transformType, transformValues))
3611 return false;
3612
3613 switch (coverMode)
3614 {
3615 case GL_CONVEX_HULL_CHROMIUM:
3616 case GL_BOUNDING_BOX_CHROMIUM:
3617 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3618 break;
3619 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003620 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003621 return false;
3622 }
3623
3624 return true;
3625}
3626
Jamie Madill007530e2017-12-28 14:27:04 -05003627bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3628 GLsizei numPaths,
3629 GLenum pathNameType,
3630 const void *paths,
3631 GLuint pathBase,
3632 GLenum fillMode,
3633 GLuint mask,
3634 GLenum transformType,
3635 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003636{
3637
3638 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3639 transformType, transformValues))
3640 return false;
3641
3642 switch (fillMode)
3643 {
3644 case GL_COUNT_UP_CHROMIUM:
3645 case GL_COUNT_DOWN_CHROMIUM:
3646 break;
3647 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003648 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003649 return false;
3650 }
3651 if (!isPow2(mask + 1))
3652 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003653 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003654 return false;
3655 }
3656 return true;
3657}
3658
Jamie Madill007530e2017-12-28 14:27:04 -05003659bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3660 GLsizei numPaths,
3661 GLenum pathNameType,
3662 const void *paths,
3663 GLuint pathBase,
3664 GLint reference,
3665 GLuint mask,
3666 GLenum transformType,
3667 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003668{
3669 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3670 transformType, transformValues))
3671 return false;
3672
3673 // no more validation here.
3674
3675 return true;
3676}
3677
Jamie Madill007530e2017-12-28 14:27:04 -05003678bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3679 GLsizei numPaths,
3680 GLenum pathNameType,
3681 const void *paths,
3682 GLuint pathBase,
3683 GLenum fillMode,
3684 GLuint mask,
3685 GLenum coverMode,
3686 GLenum transformType,
3687 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003688{
3689 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3690 transformType, transformValues))
3691 return false;
3692
3693 switch (coverMode)
3694 {
3695 case GL_CONVEX_HULL_CHROMIUM:
3696 case GL_BOUNDING_BOX_CHROMIUM:
3697 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3698 break;
3699 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003700 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003701 return false;
3702 }
3703
3704 switch (fillMode)
3705 {
3706 case GL_COUNT_UP_CHROMIUM:
3707 case GL_COUNT_DOWN_CHROMIUM:
3708 break;
3709 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003710 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003711 return false;
3712 }
3713 if (!isPow2(mask + 1))
3714 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003715 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003716 return false;
3717 }
3718
3719 return true;
3720}
3721
Jamie Madill007530e2017-12-28 14:27:04 -05003722bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3723 GLsizei numPaths,
3724 GLenum pathNameType,
3725 const void *paths,
3726 GLuint pathBase,
3727 GLint reference,
3728 GLuint mask,
3729 GLenum coverMode,
3730 GLenum transformType,
3731 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003732{
3733 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3734 transformType, transformValues))
3735 return false;
3736
3737 switch (coverMode)
3738 {
3739 case GL_CONVEX_HULL_CHROMIUM:
3740 case GL_BOUNDING_BOX_CHROMIUM:
3741 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3742 break;
3743 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003744 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003745 return false;
3746 }
3747
3748 return true;
3749}
3750
Jamie Madill007530e2017-12-28 14:27:04 -05003751bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3752 GLuint program,
3753 GLint location,
3754 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003755{
3756 if (!context->getExtensions().pathRendering)
3757 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003758 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003759 return false;
3760 }
3761
3762 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3763 if (location >= MaxLocation)
3764 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003765 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003766 return false;
3767 }
3768
3769 const auto *programObject = context->getProgram(program);
3770 if (!programObject)
3771 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003772 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003773 return false;
3774 }
3775
3776 if (!name)
3777 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003778 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003779 return false;
3780 }
3781
3782 if (angle::BeginsWith(name, "gl_"))
3783 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003784 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003785 return false;
3786 }
3787
3788 return true;
3789}
3790
Jamie Madill007530e2017-12-28 14:27:04 -05003791bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3792 GLuint program,
3793 GLint location,
3794 GLenum genMode,
3795 GLint components,
3796 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003797{
3798 if (!context->getExtensions().pathRendering)
3799 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003800 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003801 return false;
3802 }
3803
3804 const auto *programObject = context->getProgram(program);
3805 if (!programObject || programObject->isFlaggedForDeletion())
3806 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003807 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003808 return false;
3809 }
3810
3811 if (!programObject->isLinked())
3812 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003813 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003814 return false;
3815 }
3816
3817 switch (genMode)
3818 {
3819 case GL_NONE:
3820 if (components != 0)
3821 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003822 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003823 return false;
3824 }
3825 break;
3826
3827 case GL_OBJECT_LINEAR_CHROMIUM:
3828 case GL_EYE_LINEAR_CHROMIUM:
3829 case GL_CONSTANT_CHROMIUM:
3830 if (components < 1 || components > 4)
3831 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003832 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003833 return false;
3834 }
3835 if (!coeffs)
3836 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003837 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003838 return false;
3839 }
3840 break;
3841
3842 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003843 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003844 return false;
3845 }
3846
3847 // If the location is -1 then the command is silently ignored
3848 // and no further validation is needed.
3849 if (location == -1)
3850 return true;
3851
jchen103fd614d2018-08-13 12:21:58 +08003852 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003853
3854 if (!binding.valid)
3855 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003856 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003857 return false;
3858 }
3859
3860 if (binding.type != GL_NONE)
3861 {
3862 GLint expectedComponents = 0;
3863 switch (binding.type)
3864 {
3865 case GL_FLOAT:
3866 expectedComponents = 1;
3867 break;
3868 case GL_FLOAT_VEC2:
3869 expectedComponents = 2;
3870 break;
3871 case GL_FLOAT_VEC3:
3872 expectedComponents = 3;
3873 break;
3874 case GL_FLOAT_VEC4:
3875 expectedComponents = 4;
3876 break;
3877 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003878 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003879 InvalidOperation()
3880 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003881 return false;
3882 }
3883 if (expectedComponents != components && genMode != GL_NONE)
3884 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003885 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003886 return false;
3887 }
3888 }
3889 return true;
3890}
3891
Geoff Lang97073d12016-04-20 10:42:34 -07003892bool ValidateCopyTextureCHROMIUM(Context *context,
3893 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003894 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003895 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003896 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003897 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003898 GLint internalFormat,
3899 GLenum destType,
3900 GLboolean unpackFlipY,
3901 GLboolean unpackPremultiplyAlpha,
3902 GLboolean unpackUnmultiplyAlpha)
3903{
3904 if (!context->getExtensions().copyTexture)
3905 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003906 context->handleError(InvalidOperation()
3907 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003908 return false;
3909 }
3910
Geoff Lang4f0e0032017-05-01 16:04:35 -04003911 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003912 if (source == nullptr)
3913 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003914 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003915 return false;
3916 }
3917
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003918 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003919 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003920 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003921 return false;
3922 }
3923
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003924 TextureType sourceType = source->getType();
3925 ASSERT(sourceType != TextureType::CubeMap);
3926 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003927
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003928 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003929 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003930 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003931 return false;
3932 }
3933
Geoff Lang4f0e0032017-05-01 16:04:35 -04003934 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3935 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3936 if (sourceWidth == 0 || sourceHeight == 0)
3937 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003938 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003939 return false;
3940 }
3941
3942 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3943 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003944 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003945 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003946 return false;
3947 }
3948
Geoff Lang63458a32017-10-30 15:16:53 -04003949 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3950 {
3951 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3952 return false;
3953 }
3954
Geoff Lang4f0e0032017-05-01 16:04:35 -04003955 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003956 if (dest == nullptr)
3957 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003958 context->handleError(InvalidValue()
3959 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003960 return false;
3961 }
3962
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003963 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003964 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003965 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003966 return false;
3967 }
3968
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003969 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003970 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003971 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003972 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003973 return false;
3974 }
3975
Geoff Lang97073d12016-04-20 10:42:34 -07003976 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3977 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003978 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003979 return false;
3980 }
3981
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003982 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003984 context->handleError(
3985 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003986 return false;
3987 }
3988
Geoff Lang97073d12016-04-20 10:42:34 -07003989 if (dest->getImmutableFormat())
3990 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003991 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003992 return false;
3993 }
3994
3995 return true;
3996}
3997
3998bool ValidateCopySubTextureCHROMIUM(Context *context,
3999 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004000 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004001 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004002 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004003 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004004 GLint xoffset,
4005 GLint yoffset,
4006 GLint x,
4007 GLint y,
4008 GLsizei width,
4009 GLsizei height,
4010 GLboolean unpackFlipY,
4011 GLboolean unpackPremultiplyAlpha,
4012 GLboolean unpackUnmultiplyAlpha)
4013{
4014 if (!context->getExtensions().copyTexture)
4015 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004016 context->handleError(InvalidOperation()
4017 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004018 return false;
4019 }
4020
Geoff Lang4f0e0032017-05-01 16:04:35 -04004021 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004022 if (source == nullptr)
4023 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004024 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004025 return false;
4026 }
4027
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004028 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004029 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004030 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004031 return false;
4032 }
4033
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004034 TextureType sourceType = source->getType();
4035 ASSERT(sourceType != TextureType::CubeMap);
4036 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004037
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004038 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004039 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004040 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004041 return false;
4042 }
4043
4044 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4045 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004046 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004047 context->handleError(InvalidValue()
4048 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004049 return false;
4050 }
4051
4052 if (x < 0 || y < 0)
4053 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004054 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004055 return false;
4056 }
4057
4058 if (width < 0 || height < 0)
4059 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004060 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004061 return false;
4062 }
4063
Geoff Lang4f0e0032017-05-01 16:04:35 -04004064 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4065 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004066 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004067 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004068 return false;
4069 }
4070
Geoff Lang4f0e0032017-05-01 16:04:35 -04004071 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4072 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004073 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004074 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004075 return false;
4076 }
4077
Geoff Lang63458a32017-10-30 15:16:53 -04004078 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4079 {
4080 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4081 return false;
4082 }
4083
Geoff Lang4f0e0032017-05-01 16:04:35 -04004084 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004085 if (dest == nullptr)
4086 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004087 context->handleError(InvalidValue()
4088 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004089 return false;
4090 }
4091
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004092 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004093 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004094 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004095 return false;
4096 }
4097
Brandon Jones28783792018-03-05 09:37:32 -08004098 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4099 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004101 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004102 return false;
4103 }
4104
Geoff Lang4f0e0032017-05-01 16:04:35 -04004105 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4106 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004107 context
4108 ->handleError(InvalidOperation()
4109 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004110 return false;
4111 }
4112
4113 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4114 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004115 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004116 context->handleError(InvalidOperation()
4117 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004118 return false;
4119 }
4120
4121 if (xoffset < 0 || yoffset < 0)
4122 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004123 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004124 return false;
4125 }
4126
Geoff Lang4f0e0032017-05-01 16:04:35 -04004127 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4128 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004129 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004130 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004131 return false;
4132 }
4133
4134 return true;
4135}
4136
Geoff Lang47110bf2016-04-20 11:13:22 -07004137bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4138{
4139 if (!context->getExtensions().copyCompressedTexture)
4140 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004141 context->handleError(InvalidOperation()
4142 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004143 return false;
4144 }
4145
4146 const gl::Texture *source = context->getTexture(sourceId);
4147 if (source == nullptr)
4148 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004149 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004150 return false;
4151 }
4152
Corentin Wallez99d492c2018-02-27 15:17:10 -05004153 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004155 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004156 return false;
4157 }
4158
Corentin Wallez99d492c2018-02-27 15:17:10 -05004159 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4160 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004161 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004162 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004163 return false;
4164 }
4165
Corentin Wallez99d492c2018-02-27 15:17:10 -05004166 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004167 if (!sourceFormat.info->compressed)
4168 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004169 context->handleError(InvalidOperation()
4170 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004171 return false;
4172 }
4173
4174 const gl::Texture *dest = context->getTexture(destId);
4175 if (dest == nullptr)
4176 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004177 context->handleError(InvalidValue()
4178 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004179 return false;
4180 }
4181
Corentin Wallez99d492c2018-02-27 15:17:10 -05004182 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004183 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004184 context->handleError(InvalidValue()
4185 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004186 return false;
4187 }
4188
4189 if (dest->getImmutableFormat())
4190 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004191 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004192 return false;
4193 }
4194
4195 return true;
4196}
4197
Jiawei Shao385b3e02018-03-21 09:43:28 +08004198bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004199{
4200 switch (type)
4201 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004202 case ShaderType::Vertex:
4203 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004204 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004205
Jiawei Shao385b3e02018-03-21 09:43:28 +08004206 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004207 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004208 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004209 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004210 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004211 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004212 break;
4213
Jiawei Shao385b3e02018-03-21 09:43:28 +08004214 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004215 if (!context->getExtensions().geometryShader)
4216 {
4217 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4218 return false;
4219 }
4220 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004221 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004222 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004223 return false;
4224 }
Jamie Madill29639852016-09-02 15:00:09 -04004225
4226 return true;
4227}
4228
Jamie Madill5b772312018-03-08 20:28:32 -05004229bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004230 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004231 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004232 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004233 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004234{
4235 if (size < 0)
4236 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004237 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004238 return false;
4239 }
4240
4241 switch (usage)
4242 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004243 case BufferUsage::StreamDraw:
4244 case BufferUsage::StaticDraw:
4245 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004246 break;
4247
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004248 case BufferUsage::StreamRead:
4249 case BufferUsage::StaticRead:
4250 case BufferUsage::DynamicRead:
4251 case BufferUsage::StreamCopy:
4252 case BufferUsage::StaticCopy:
4253 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004254 if (context->getClientMajorVersion() < 3)
4255 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004256 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004257 return false;
4258 }
4259 break;
4260
4261 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004262 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004263 return false;
4264 }
4265
Corentin Walleze4477002017-12-01 14:39:58 -05004266 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004267 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004268 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004269 return false;
4270 }
4271
4272 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4273
4274 if (!buffer)
4275 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004276 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004277 return false;
4278 }
4279
James Darpiniane8a93c62018-01-04 18:02:24 -08004280 if (context->getExtensions().webglCompatibility &&
4281 buffer->isBoundForTransformFeedbackAndOtherUse())
4282 {
4283 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4284 return false;
4285 }
4286
Jamie Madill29639852016-09-02 15:00:09 -04004287 return true;
4288}
4289
Jamie Madill5b772312018-03-08 20:28:32 -05004290bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004291 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004292 GLintptr offset,
4293 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004294 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004295{
Brandon Jones6cad5662017-06-14 13:25:13 -07004296 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004297 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004298 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4299 return false;
4300 }
4301
4302 if (offset < 0)
4303 {
4304 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004305 return false;
4306 }
4307
Corentin Walleze4477002017-12-01 14:39:58 -05004308 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004309 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004310 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004311 return false;
4312 }
4313
4314 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4315
4316 if (!buffer)
4317 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004318 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004319 return false;
4320 }
4321
4322 if (buffer->isMapped())
4323 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004324 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004325 return false;
4326 }
4327
James Darpiniane8a93c62018-01-04 18:02:24 -08004328 if (context->getExtensions().webglCompatibility &&
4329 buffer->isBoundForTransformFeedbackAndOtherUse())
4330 {
4331 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4332 return false;
4333 }
4334
Jamie Madill29639852016-09-02 15:00:09 -04004335 // Check for possible overflow of size + offset
4336 angle::CheckedNumeric<size_t> checkedSize(size);
4337 checkedSize += offset;
4338 if (!checkedSize.IsValid())
4339 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004340 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004341 return false;
4342 }
4343
4344 if (size + offset > buffer->getSize())
4345 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004346 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004347 return false;
4348 }
4349
Martin Radev4c4c8e72016-08-04 12:25:34 +03004350 return true;
4351}
4352
Geoff Lang111a99e2017-10-17 10:58:41 -04004353bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004354{
Geoff Langc339c4e2016-11-29 10:37:36 -05004355 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004356 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004357 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004358 return false;
4359 }
4360
Geoff Lang111a99e2017-10-17 10:58:41 -04004361 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004362 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004363 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004364 return false;
4365 }
4366
4367 return true;
4368}
4369
Jamie Madill5b772312018-03-08 20:28:32 -05004370bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004371{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004372 if (context->getClientMajorVersion() < 2)
4373 {
4374 return ValidateMultitextureUnit(context, texture);
4375 }
4376
Jamie Madillef300b12016-10-07 15:12:09 -04004377 if (texture < GL_TEXTURE0 ||
4378 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4379 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004380 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004381 return false;
4382 }
4383
4384 return true;
4385}
4386
Jamie Madill5b772312018-03-08 20:28:32 -05004387bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004388{
4389 Program *programObject = GetValidProgram(context, program);
4390 if (!programObject)
4391 {
4392 return false;
4393 }
4394
4395 Shader *shaderObject = GetValidShader(context, shader);
4396 if (!shaderObject)
4397 {
4398 return false;
4399 }
4400
Jiawei Shao385b3e02018-03-21 09:43:28 +08004401 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004402 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004403 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4404 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004405 }
4406
4407 return true;
4408}
4409
Jamie Madill5b772312018-03-08 20:28:32 -05004410bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004411{
4412 if (index >= MAX_VERTEX_ATTRIBS)
4413 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004414 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004415 return false;
4416 }
4417
4418 if (strncmp(name, "gl_", 3) == 0)
4419 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004420 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004421 return false;
4422 }
4423
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004424 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004425 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004426 const size_t length = strlen(name);
4427
4428 if (!IsValidESSLString(name, length))
4429 {
4430 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4431 // for shader-related entry points
4432 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4433 return false;
4434 }
4435
4436 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4437 {
4438 return false;
4439 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004440 }
4441
Jamie Madill01a80ee2016-11-07 12:06:18 -05004442 return GetValidProgram(context, program) != nullptr;
4443}
4444
Jamie Madill5b772312018-03-08 20:28:32 -05004445bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004446{
Corentin Walleze4477002017-12-01 14:39:58 -05004447 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004448 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004449 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004450 return false;
4451 }
4452
4453 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4454 !context->isBufferGenerated(buffer))
4455 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004456 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004457 return false;
4458 }
4459
4460 return true;
4461}
4462
Jamie Madill5b772312018-03-08 20:28:32 -05004463bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004464{
Geoff Lange8afa902017-09-27 15:00:43 -04004465 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004466 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004467 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004468 return false;
4469 }
4470
4471 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4472 !context->isFramebufferGenerated(framebuffer))
4473 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004474 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004475 return false;
4476 }
4477
4478 return true;
4479}
4480
Jamie Madill5b772312018-03-08 20:28:32 -05004481bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004482{
4483 if (target != GL_RENDERBUFFER)
4484 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004485 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004486 return false;
4487 }
4488
4489 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4490 !context->isRenderbufferGenerated(renderbuffer))
4491 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004492 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004493 return false;
4494 }
4495
4496 return true;
4497}
4498
Jamie Madill5b772312018-03-08 20:28:32 -05004499static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004500{
4501 switch (mode)
4502 {
4503 case GL_FUNC_ADD:
4504 case GL_FUNC_SUBTRACT:
4505 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004506 return true;
4507
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004508 case GL_MIN:
4509 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004510 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004511
4512 default:
4513 return false;
4514 }
4515}
4516
Jamie Madill5b772312018-03-08 20:28:32 -05004517bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004518{
4519 return true;
4520}
4521
Jamie Madill5b772312018-03-08 20:28:32 -05004522bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004523{
Geoff Lang50cac572017-09-26 17:37:43 -04004524 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004525 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004526 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004527 return false;
4528 }
4529
4530 return true;
4531}
4532
Jamie Madill5b772312018-03-08 20:28:32 -05004533bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004534{
Geoff Lang50cac572017-09-26 17:37:43 -04004535 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004537 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004538 return false;
4539 }
4540
Geoff Lang50cac572017-09-26 17:37:43 -04004541 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004542 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004543 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004544 return false;
4545 }
4546
4547 return true;
4548}
4549
Jamie Madill5b772312018-03-08 20:28:32 -05004550bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004551{
4552 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4553}
4554
4555static bool ValidSrcBlendFunc(GLenum srcBlend)
4556{
4557 switch (srcBlend)
4558 {
4559 case GL_ZERO:
4560 case GL_ONE:
4561 case GL_SRC_COLOR:
4562 case GL_ONE_MINUS_SRC_COLOR:
4563 case GL_DST_COLOR:
4564 case GL_ONE_MINUS_DST_COLOR:
4565 case GL_SRC_ALPHA:
4566 case GL_ONE_MINUS_SRC_ALPHA:
4567 case GL_DST_ALPHA:
4568 case GL_ONE_MINUS_DST_ALPHA:
4569 case GL_CONSTANT_COLOR:
4570 case GL_ONE_MINUS_CONSTANT_COLOR:
4571 case GL_CONSTANT_ALPHA:
4572 case GL_ONE_MINUS_CONSTANT_ALPHA:
4573 case GL_SRC_ALPHA_SATURATE:
4574 return true;
4575
4576 default:
4577 return false;
4578 }
4579}
4580
4581static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4582{
4583 switch (dstBlend)
4584 {
4585 case GL_ZERO:
4586 case GL_ONE:
4587 case GL_SRC_COLOR:
4588 case GL_ONE_MINUS_SRC_COLOR:
4589 case GL_DST_COLOR:
4590 case GL_ONE_MINUS_DST_COLOR:
4591 case GL_SRC_ALPHA:
4592 case GL_ONE_MINUS_SRC_ALPHA:
4593 case GL_DST_ALPHA:
4594 case GL_ONE_MINUS_DST_ALPHA:
4595 case GL_CONSTANT_COLOR:
4596 case GL_ONE_MINUS_CONSTANT_COLOR:
4597 case GL_CONSTANT_ALPHA:
4598 case GL_ONE_MINUS_CONSTANT_ALPHA:
4599 return true;
4600
4601 case GL_SRC_ALPHA_SATURATE:
4602 return (contextMajorVersion >= 3);
4603
4604 default:
4605 return false;
4606 }
4607}
4608
Jamie Madill5b772312018-03-08 20:28:32 -05004609bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004610 GLenum srcRGB,
4611 GLenum dstRGB,
4612 GLenum srcAlpha,
4613 GLenum dstAlpha)
4614{
4615 if (!ValidSrcBlendFunc(srcRGB))
4616 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004617 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004618 return false;
4619 }
4620
4621 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4622 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004623 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004624 return false;
4625 }
4626
4627 if (!ValidSrcBlendFunc(srcAlpha))
4628 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004629 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004630 return false;
4631 }
4632
4633 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4634 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004635 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004636 return false;
4637 }
4638
Frank Henigman146e8a12017-03-02 23:22:37 -05004639 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4640 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004641 {
4642 bool constantColorUsed =
4643 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4644 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4645
4646 bool constantAlphaUsed =
4647 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4648 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4649
4650 if (constantColorUsed && constantAlphaUsed)
4651 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004652 const char *msg;
4653 if (context->getExtensions().webglCompatibility)
4654 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004655 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004656 }
4657 else
4658 {
4659 msg =
4660 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4661 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4662 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004663 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004664 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004665 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004666 return false;
4667 }
4668 }
4669
4670 return true;
4671}
4672
Geoff Langc339c4e2016-11-29 10:37:36 -05004673bool ValidateGetString(Context *context, GLenum name)
4674{
4675 switch (name)
4676 {
4677 case GL_VENDOR:
4678 case GL_RENDERER:
4679 case GL_VERSION:
4680 case GL_SHADING_LANGUAGE_VERSION:
4681 case GL_EXTENSIONS:
4682 break;
4683
4684 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4685 if (!context->getExtensions().requestExtension)
4686 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004687 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004688 return false;
4689 }
4690 break;
4691
4692 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004694 return false;
4695 }
4696
4697 return true;
4698}
4699
Jamie Madill5b772312018-03-08 20:28:32 -05004700bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004701{
4702 if (width <= 0.0f || isNaN(width))
4703 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004704 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004705 return false;
4706 }
4707
4708 return true;
4709}
4710
Jamie Madill5b772312018-03-08 20:28:32 -05004711bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004712 GLuint index,
4713 GLint size,
4714 GLenum type,
4715 GLboolean normalized,
4716 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004717 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004718{
Shao80957d92017-02-20 21:25:59 +08004719 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004720 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004721 return false;
4722 }
4723
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004724 if (stride < 0)
4725 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004726 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004727 return false;
4728 }
4729
Shao80957d92017-02-20 21:25:59 +08004730 const Caps &caps = context->getCaps();
4731 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004732 {
Shao80957d92017-02-20 21:25:59 +08004733 if (stride > caps.maxVertexAttribStride)
4734 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004735 context->handleError(InvalidValue()
4736 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004737 return false;
4738 }
4739
4740 if (index >= caps.maxVertexAttribBindings)
4741 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004742 context->handleError(InvalidValue()
4743 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004744 return false;
4745 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004746 }
4747
4748 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4749 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4750 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4751 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004752 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4753 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004754 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4755 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004756 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004757 context
4758 ->handleError(InvalidOperation()
4759 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004760 return false;
4761 }
4762
4763 if (context->getExtensions().webglCompatibility)
4764 {
4765 // WebGL 1.0 [Section 6.14] Fixed point support
4766 // The WebGL API does not support the GL_FIXED data type.
4767 if (type == GL_FIXED)
4768 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004769 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004770 return false;
4771 }
4772
Geoff Lang2d62ab72017-03-23 16:54:40 -04004773 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004774 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004775 return false;
4776 }
4777 }
4778
4779 return true;
4780}
4781
Jamie Madill5b772312018-03-08 20:28:32 -05004782bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004783{
4784 if (context->getExtensions().webglCompatibility && zNear > zFar)
4785 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004786 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004787 return false;
4788 }
4789
4790 return true;
4791}
4792
Jamie Madill5b772312018-03-08 20:28:32 -05004793bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004794 GLenum target,
4795 GLenum internalformat,
4796 GLsizei width,
4797 GLsizei height)
4798{
4799 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4800 height);
4801}
4802
Jamie Madill5b772312018-03-08 20:28:32 -05004803bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004804 GLenum target,
4805 GLsizei samples,
4806 GLenum internalformat,
4807 GLsizei width,
4808 GLsizei height)
4809{
4810 if (!context->getExtensions().framebufferMultisample)
4811 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004812 context->handleError(InvalidOperation()
4813 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004814 return false;
4815 }
4816
4817 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4818 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4819 // generated.
4820 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4821 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004822 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004823 return false;
4824 }
4825
4826 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4827 // the specified storage. This is different than ES 3.0 in which a sample number higher
4828 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4829 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4830 if (context->getClientMajorVersion() >= 3)
4831 {
4832 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4833 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4834 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004835 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004836 return false;
4837 }
4838 }
4839
4840 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4841 width, height);
4842}
4843
Jamie Madill5b772312018-03-08 20:28:32 -05004844bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004845{
Geoff Lange8afa902017-09-27 15:00:43 -04004846 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004847 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004848 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004849 return false;
4850 }
4851
4852 return true;
4853}
4854
Jamie Madill5b772312018-03-08 20:28:32 -05004855bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004856{
4857 return true;
4858}
4859
Jamie Madill5b772312018-03-08 20:28:32 -05004860bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004861{
4862 return true;
4863}
4864
Jamie Madill5b772312018-03-08 20:28:32 -05004865bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004866{
4867 return true;
4868}
4869
Jamie Madill5b772312018-03-08 20:28:32 -05004870bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004871 GLboolean red,
4872 GLboolean green,
4873 GLboolean blue,
4874 GLboolean alpha)
4875{
4876 return true;
4877}
4878
Jamie Madill5b772312018-03-08 20:28:32 -05004879bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004880{
4881 return true;
4882}
4883
Jamie Madill5b772312018-03-08 20:28:32 -05004884bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004885{
4886 return true;
4887}
4888
Jamie Madill5b772312018-03-08 20:28:32 -05004889bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004890{
4891 switch (mode)
4892 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004893 case CullFaceMode::Front:
4894 case CullFaceMode::Back:
4895 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004896 break;
4897
4898 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004899 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004900 return false;
4901 }
4902
4903 return true;
4904}
4905
Jamie Madill5b772312018-03-08 20:28:32 -05004906bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004907{
4908 if (program == 0)
4909 {
4910 return false;
4911 }
4912
4913 if (!context->getProgram(program))
4914 {
4915 if (context->getShader(program))
4916 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004917 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004918 return false;
4919 }
4920 else
4921 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004922 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004923 return false;
4924 }
4925 }
4926
4927 return true;
4928}
4929
Jamie Madill5b772312018-03-08 20:28:32 -05004930bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004931{
4932 if (shader == 0)
4933 {
4934 return false;
4935 }
4936
4937 if (!context->getShader(shader))
4938 {
4939 if (context->getProgram(shader))
4940 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004941 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004942 return false;
4943 }
4944 else
4945 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004946 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004947 return false;
4948 }
4949 }
4950
4951 return true;
4952}
4953
Jamie Madill5b772312018-03-08 20:28:32 -05004954bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004955{
4956 switch (func)
4957 {
4958 case GL_NEVER:
4959 case GL_ALWAYS:
4960 case GL_LESS:
4961 case GL_LEQUAL:
4962 case GL_EQUAL:
4963 case GL_GREATER:
4964 case GL_GEQUAL:
4965 case GL_NOTEQUAL:
4966 break;
4967
4968 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004969 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004970 return false;
4971 }
4972
4973 return true;
4974}
4975
Jamie Madill5b772312018-03-08 20:28:32 -05004976bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004977{
4978 return true;
4979}
4980
Jamie Madill5b772312018-03-08 20:28:32 -05004981bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004982{
4983 Program *programObject = GetValidProgram(context, program);
4984 if (!programObject)
4985 {
4986 return false;
4987 }
4988
4989 Shader *shaderObject = GetValidShader(context, shader);
4990 if (!shaderObject)
4991 {
4992 return false;
4993 }
4994
Jiawei Shao385b3e02018-03-21 09:43:28 +08004995 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004996 if (attachedShader != shaderObject)
4997 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004998 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004999 return false;
5000 }
5001
5002 return true;
5003}
5004
Jamie Madill5b772312018-03-08 20:28:32 -05005005bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005006{
5007 if (index >= MAX_VERTEX_ATTRIBS)
5008 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005009 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005010 return false;
5011 }
5012
5013 return true;
5014}
5015
Jamie Madill5b772312018-03-08 20:28:32 -05005016bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005017{
5018 if (index >= MAX_VERTEX_ATTRIBS)
5019 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005020 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005021 return false;
5022 }
5023
5024 return true;
5025}
5026
Jamie Madill5b772312018-03-08 20:28:32 -05005027bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005028{
5029 return true;
5030}
5031
Jamie Madill5b772312018-03-08 20:28:32 -05005032bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005033{
5034 return true;
5035}
5036
Jamie Madill5b772312018-03-08 20:28:32 -05005037bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005038{
5039 switch (mode)
5040 {
5041 case GL_CW:
5042 case GL_CCW:
5043 break;
5044 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005045 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005046 return false;
5047 }
5048
5049 return true;
5050}
5051
Jamie Madill5b772312018-03-08 20:28:32 -05005052bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005053 GLuint program,
5054 GLuint index,
5055 GLsizei bufsize,
5056 GLsizei *length,
5057 GLint *size,
5058 GLenum *type,
5059 GLchar *name)
5060{
5061 if (bufsize < 0)
5062 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005063 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005064 return false;
5065 }
5066
5067 Program *programObject = GetValidProgram(context, program);
5068
5069 if (!programObject)
5070 {
5071 return false;
5072 }
5073
5074 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5075 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005076 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005077 return false;
5078 }
5079
5080 return true;
5081}
5082
Jamie Madill5b772312018-03-08 20:28:32 -05005083bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005084 GLuint program,
5085 GLuint index,
5086 GLsizei bufsize,
5087 GLsizei *length,
5088 GLint *size,
5089 GLenum *type,
5090 GLchar *name)
5091{
5092 if (bufsize < 0)
5093 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005094 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005095 return false;
5096 }
5097
5098 Program *programObject = GetValidProgram(context, program);
5099
5100 if (!programObject)
5101 {
5102 return false;
5103 }
5104
5105 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5106 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005107 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005108 return false;
5109 }
5110
5111 return true;
5112}
5113
Jamie Madill5b772312018-03-08 20:28:32 -05005114bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005115 GLuint program,
5116 GLsizei maxcount,
5117 GLsizei *count,
5118 GLuint *shaders)
5119{
5120 if (maxcount < 0)
5121 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005122 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005123 return false;
5124 }
5125
5126 Program *programObject = GetValidProgram(context, program);
5127
5128 if (!programObject)
5129 {
5130 return false;
5131 }
5132
5133 return true;
5134}
5135
Jamie Madill5b772312018-03-08 20:28:32 -05005136bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005137{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005138 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5139 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005140 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005141 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005142 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005143 return false;
5144 }
5145
Jamie Madillc1d770e2017-04-13 17:31:24 -04005146 Program *programObject = GetValidProgram(context, program);
5147
5148 if (!programObject)
5149 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005150 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005151 return false;
5152 }
5153
5154 if (!programObject->isLinked())
5155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005156 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005157 return false;
5158 }
5159
5160 return true;
5161}
5162
Jamie Madill5b772312018-03-08 20:28:32 -05005163bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005164{
5165 GLenum nativeType;
5166 unsigned int numParams = 0;
5167 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5168}
5169
Jamie Madill5b772312018-03-08 20:28:32 -05005170bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005171{
5172 return true;
5173}
5174
Jamie Madill5b772312018-03-08 20:28:32 -05005175bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005176{
5177 GLenum nativeType;
5178 unsigned int numParams = 0;
5179 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5180}
5181
Jamie Madill5b772312018-03-08 20:28:32 -05005182bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005183{
5184 GLenum nativeType;
5185 unsigned int numParams = 0;
5186 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5187}
5188
Jamie Madill5b772312018-03-08 20:28:32 -05005189bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005190 GLuint program,
5191 GLsizei bufsize,
5192 GLsizei *length,
5193 GLchar *infolog)
5194{
5195 if (bufsize < 0)
5196 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005197 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005198 return false;
5199 }
5200
5201 Program *programObject = GetValidProgram(context, program);
5202 if (!programObject)
5203 {
5204 return false;
5205 }
5206
5207 return true;
5208}
5209
Jamie Madill5b772312018-03-08 20:28:32 -05005210bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005211 GLuint shader,
5212 GLsizei bufsize,
5213 GLsizei *length,
5214 GLchar *infolog)
5215{
5216 if (bufsize < 0)
5217 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005218 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005219 return false;
5220 }
5221
5222 Shader *shaderObject = GetValidShader(context, shader);
5223 if (!shaderObject)
5224 {
5225 return false;
5226 }
5227
5228 return true;
5229}
5230
Jamie Madill5b772312018-03-08 20:28:32 -05005231bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005232 GLenum shadertype,
5233 GLenum precisiontype,
5234 GLint *range,
5235 GLint *precision)
5236{
5237 switch (shadertype)
5238 {
5239 case GL_VERTEX_SHADER:
5240 case GL_FRAGMENT_SHADER:
5241 break;
5242 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005243 context->handleError(InvalidOperation()
5244 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005245 return false;
5246 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005247 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005248 return false;
5249 }
5250
5251 switch (precisiontype)
5252 {
5253 case GL_LOW_FLOAT:
5254 case GL_MEDIUM_FLOAT:
5255 case GL_HIGH_FLOAT:
5256 case GL_LOW_INT:
5257 case GL_MEDIUM_INT:
5258 case GL_HIGH_INT:
5259 break;
5260
5261 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005262 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005263 return false;
5264 }
5265
5266 return true;
5267}
5268
Jamie Madill5b772312018-03-08 20:28:32 -05005269bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005270 GLuint shader,
5271 GLsizei bufsize,
5272 GLsizei *length,
5273 GLchar *source)
5274{
5275 if (bufsize < 0)
5276 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005277 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005278 return false;
5279 }
5280
5281 Shader *shaderObject = GetValidShader(context, shader);
5282 if (!shaderObject)
5283 {
5284 return false;
5285 }
5286
5287 return true;
5288}
5289
Jamie Madill5b772312018-03-08 20:28:32 -05005290bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005291{
5292 if (strstr(name, "gl_") == name)
5293 {
5294 return false;
5295 }
5296
Geoff Langfc32e8b2017-05-31 14:16:59 -04005297 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5298 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005299 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005300 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005301 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005302 return false;
5303 }
5304
Jamie Madillc1d770e2017-04-13 17:31:24 -04005305 Program *programObject = GetValidProgram(context, program);
5306
5307 if (!programObject)
5308 {
5309 return false;
5310 }
5311
5312 if (!programObject->isLinked())
5313 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005314 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005315 return false;
5316 }
5317
5318 return true;
5319}
5320
Jamie Madill5b772312018-03-08 20:28:32 -05005321bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005322{
5323 switch (mode)
5324 {
5325 case GL_FASTEST:
5326 case GL_NICEST:
5327 case GL_DONT_CARE:
5328 break;
5329
5330 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005331 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005332 return false;
5333 }
5334
5335 switch (target)
5336 {
5337 case GL_GENERATE_MIPMAP_HINT:
5338 break;
5339
Geoff Lange7bd2182017-06-16 16:13:13 -04005340 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5341 if (context->getClientVersion() < ES_3_0 &&
5342 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005343 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005344 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345 return false;
5346 }
5347 break;
5348
5349 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005350 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005351 return false;
5352 }
5353
5354 return true;
5355}
5356
Jamie Madill5b772312018-03-08 20:28:32 -05005357bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005358{
5359 return true;
5360}
5361
Jamie Madill5b772312018-03-08 20:28:32 -05005362bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005363{
5364 return true;
5365}
5366
Jamie Madill5b772312018-03-08 20:28:32 -05005367bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368{
5369 return true;
5370}
5371
Jamie Madill5b772312018-03-08 20:28:32 -05005372bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005373{
5374 return true;
5375}
5376
Jamie Madill5b772312018-03-08 20:28:32 -05005377bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378{
5379 return true;
5380}
5381
Jamie Madill5b772312018-03-08 20:28:32 -05005382bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005383{
5384 return true;
5385}
5386
Jamie Madill5b772312018-03-08 20:28:32 -05005387bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005388{
5389 if (context->getClientMajorVersion() < 3)
5390 {
5391 switch (pname)
5392 {
5393 case GL_UNPACK_IMAGE_HEIGHT:
5394 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005395 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005396 return false;
5397
5398 case GL_UNPACK_ROW_LENGTH:
5399 case GL_UNPACK_SKIP_ROWS:
5400 case GL_UNPACK_SKIP_PIXELS:
5401 if (!context->getExtensions().unpackSubimage)
5402 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005403 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005404 return false;
5405 }
5406 break;
5407
5408 case GL_PACK_ROW_LENGTH:
5409 case GL_PACK_SKIP_ROWS:
5410 case GL_PACK_SKIP_PIXELS:
5411 if (!context->getExtensions().packSubimage)
5412 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005413 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005414 return false;
5415 }
5416 break;
5417 }
5418 }
5419
5420 if (param < 0)
5421 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005422 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005423 return false;
5424 }
5425
5426 switch (pname)
5427 {
5428 case GL_UNPACK_ALIGNMENT:
5429 if (param != 1 && param != 2 && param != 4 && param != 8)
5430 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005431 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005432 return false;
5433 }
5434 break;
5435
5436 case GL_PACK_ALIGNMENT:
5437 if (param != 1 && param != 2 && param != 4 && param != 8)
5438 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005439 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005440 return false;
5441 }
5442 break;
5443
5444 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005445 if (!context->getExtensions().packReverseRowOrder)
5446 {
5447 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5448 }
5449 break;
5450
Jamie Madillc1d770e2017-04-13 17:31:24 -04005451 case GL_UNPACK_ROW_LENGTH:
5452 case GL_UNPACK_IMAGE_HEIGHT:
5453 case GL_UNPACK_SKIP_IMAGES:
5454 case GL_UNPACK_SKIP_ROWS:
5455 case GL_UNPACK_SKIP_PIXELS:
5456 case GL_PACK_ROW_LENGTH:
5457 case GL_PACK_SKIP_ROWS:
5458 case GL_PACK_SKIP_PIXELS:
5459 break;
5460
5461 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005462 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005463 return false;
5464 }
5465
5466 return true;
5467}
5468
Jamie Madill5b772312018-03-08 20:28:32 -05005469bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005470{
5471 return true;
5472}
5473
Jamie Madill5b772312018-03-08 20:28:32 -05005474bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005475{
5476 return true;
5477}
5478
Jamie Madill5b772312018-03-08 20:28:32 -05005479bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005480{
5481 return true;
5482}
5483
Jamie Madill5b772312018-03-08 20:28:32 -05005484bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485{
5486 if (width < 0 || height < 0)
5487 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005488 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005489 return false;
5490 }
5491
5492 return true;
5493}
5494
Jamie Madill5b772312018-03-08 20:28:32 -05005495bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005496 GLsizei n,
5497 const GLuint *shaders,
5498 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005499 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005500 GLsizei length)
5501{
5502 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5503 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5504 shaderBinaryFormats.end())
5505 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005506 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005507 return false;
5508 }
5509
5510 return true;
5511}
5512
Jamie Madill5b772312018-03-08 20:28:32 -05005513bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005514 GLuint shader,
5515 GLsizei count,
5516 const GLchar *const *string,
5517 const GLint *length)
5518{
5519 if (count < 0)
5520 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005521 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005522 return false;
5523 }
5524
Geoff Langfc32e8b2017-05-31 14:16:59 -04005525 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5526 // shader-related entry points
5527 if (context->getExtensions().webglCompatibility)
5528 {
5529 for (GLsizei i = 0; i < count; i++)
5530 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005531 size_t len =
5532 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005533
5534 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005535 if (!IsValidESSLShaderSourceString(string[i], len,
5536 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005537 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005538 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005539 return false;
5540 }
5541 }
5542 }
5543
Jamie Madillc1d770e2017-04-13 17:31:24 -04005544 Shader *shaderObject = GetValidShader(context, shader);
5545 if (!shaderObject)
5546 {
5547 return false;
5548 }
5549
5550 return true;
5551}
5552
Jamie Madill5b772312018-03-08 20:28:32 -05005553bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005554{
5555 if (!IsValidStencilFunc(func))
5556 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005557 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005558 return false;
5559 }
5560
5561 return true;
5562}
5563
Jamie Madill5b772312018-03-08 20:28:32 -05005564bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005565{
5566 if (!IsValidStencilFace(face))
5567 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005568 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005569 return false;
5570 }
5571
5572 if (!IsValidStencilFunc(func))
5573 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005574 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005575 return false;
5576 }
5577
5578 return true;
5579}
5580
Jamie Madill5b772312018-03-08 20:28:32 -05005581bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005582{
5583 return true;
5584}
5585
Jamie Madill5b772312018-03-08 20:28:32 -05005586bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005587{
5588 if (!IsValidStencilFace(face))
5589 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005590 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005591 return false;
5592 }
5593
5594 return true;
5595}
5596
Jamie Madill5b772312018-03-08 20:28:32 -05005597bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005598{
5599 if (!IsValidStencilOp(fail))
5600 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602 return false;
5603 }
5604
5605 if (!IsValidStencilOp(zfail))
5606 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005607 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005608 return false;
5609 }
5610
5611 if (!IsValidStencilOp(zpass))
5612 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005613 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005614 return false;
5615 }
5616
5617 return true;
5618}
5619
Jamie Madill5b772312018-03-08 20:28:32 -05005620bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005621 GLenum face,
5622 GLenum fail,
5623 GLenum zfail,
5624 GLenum zpass)
5625{
5626 if (!IsValidStencilFace(face))
5627 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005628 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629 return false;
5630 }
5631
5632 return ValidateStencilOp(context, fail, zfail, zpass);
5633}
5634
Jamie Madill5b772312018-03-08 20:28:32 -05005635bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005636{
5637 return ValidateUniform(context, GL_FLOAT, location, 1);
5638}
5639
Jamie Madill5b772312018-03-08 20:28:32 -05005640bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005641{
5642 return ValidateUniform(context, GL_FLOAT, location, count);
5643}
5644
Jamie Madill5b772312018-03-08 20:28:32 -05005645bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005646{
5647 return ValidateUniform1iv(context, location, 1, &x);
5648}
5649
Jamie Madill5b772312018-03-08 20:28:32 -05005650bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005651{
5652 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5653}
5654
Jamie Madill5b772312018-03-08 20:28:32 -05005655bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005656{
5657 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5658}
5659
Jamie Madill5b772312018-03-08 20:28:32 -05005660bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005661{
5662 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5663}
5664
Jamie Madill5b772312018-03-08 20:28:32 -05005665bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005666{
5667 return ValidateUniform(context, GL_INT_VEC2, location, count);
5668}
5669
Jamie Madill5b772312018-03-08 20:28:32 -05005670bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005671{
5672 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5673}
5674
Jamie Madill5b772312018-03-08 20:28:32 -05005675bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005676{
5677 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5678}
5679
Jamie Madill5b772312018-03-08 20:28:32 -05005680bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005681{
5682 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5683}
5684
Jamie Madill5b772312018-03-08 20:28:32 -05005685bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005686{
5687 return ValidateUniform(context, GL_INT_VEC3, location, count);
5688}
5689
Jamie Madill5b772312018-03-08 20:28:32 -05005690bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005691{
5692 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5693}
5694
Jamie Madill5b772312018-03-08 20:28:32 -05005695bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005696{
5697 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5698}
5699
Jamie Madill5b772312018-03-08 20:28:32 -05005700bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005701{
5702 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5703}
5704
Jamie Madill5b772312018-03-08 20:28:32 -05005705bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005706{
5707 return ValidateUniform(context, GL_INT_VEC4, location, count);
5708}
5709
Jamie Madill5b772312018-03-08 20:28:32 -05005710bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005711 GLint location,
5712 GLsizei count,
5713 GLboolean transpose,
5714 const GLfloat *value)
5715{
5716 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5717}
5718
Jamie Madill5b772312018-03-08 20:28:32 -05005719bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005720 GLint location,
5721 GLsizei count,
5722 GLboolean transpose,
5723 const GLfloat *value)
5724{
5725 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5726}
5727
Jamie Madill5b772312018-03-08 20:28:32 -05005728bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005729 GLint location,
5730 GLsizei count,
5731 GLboolean transpose,
5732 const GLfloat *value)
5733{
5734 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5735}
5736
Jamie Madill5b772312018-03-08 20:28:32 -05005737bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005738{
5739 Program *programObject = GetValidProgram(context, program);
5740
5741 if (!programObject)
5742 {
5743 return false;
5744 }
5745
5746 return true;
5747}
5748
Jamie Madill5b772312018-03-08 20:28:32 -05005749bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005750{
5751 return ValidateVertexAttribIndex(context, index);
5752}
5753
Jamie Madill5b772312018-03-08 20:28:32 -05005754bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005755{
5756 return ValidateVertexAttribIndex(context, index);
5757}
5758
Jamie Madill5b772312018-03-08 20:28:32 -05005759bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005760{
5761 return ValidateVertexAttribIndex(context, index);
5762}
5763
Jamie Madill5b772312018-03-08 20:28:32 -05005764bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005765{
5766 return ValidateVertexAttribIndex(context, index);
5767}
5768
Jamie Madill5b772312018-03-08 20:28:32 -05005769bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005770{
5771 return ValidateVertexAttribIndex(context, index);
5772}
5773
Jamie Madill5b772312018-03-08 20:28:32 -05005774bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005775{
5776 return ValidateVertexAttribIndex(context, index);
5777}
5778
Jamie Madill5b772312018-03-08 20:28:32 -05005779bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005780 GLuint index,
5781 GLfloat x,
5782 GLfloat y,
5783 GLfloat z,
5784 GLfloat w)
5785{
5786 return ValidateVertexAttribIndex(context, index);
5787}
5788
Jamie Madill5b772312018-03-08 20:28:32 -05005789bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005790{
5791 return ValidateVertexAttribIndex(context, index);
5792}
5793
Jamie Madill5b772312018-03-08 20:28:32 -05005794bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005795{
5796 if (width < 0 || height < 0)
5797 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005798 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005799 return false;
5800 }
5801
5802 return true;
5803}
5804
Jamie Madill493f9572018-05-24 19:52:15 -04005805bool ValidateDrawArrays(Context *context, PrimitiveMode mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005806{
5807 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5808}
5809
Jamie Madill5b772312018-03-08 20:28:32 -05005810bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005811 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005812 GLsizei count,
5813 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005814 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005815{
5816 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5817}
5818
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005819bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005820 GLenum target,
5821 GLenum attachment,
5822 GLenum pname,
5823 GLint *params)
5824{
5825 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5826 nullptr);
5827}
5828
Jamie Madill5b772312018-03-08 20:28:32 -05005829bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005830{
5831 return ValidateGetProgramivBase(context, program, pname, nullptr);
5832}
5833
Jamie Madill5b772312018-03-08 20:28:32 -05005834bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005835 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005836 GLint level,
5837 GLenum internalformat,
5838 GLint x,
5839 GLint y,
5840 GLsizei width,
5841 GLsizei height,
5842 GLint border)
5843{
5844 if (context->getClientMajorVersion() < 3)
5845 {
5846 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5847 0, x, y, width, height, border);
5848 }
5849
5850 ASSERT(context->getClientMajorVersion() == 3);
5851 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5852 0, x, y, width, height, border);
5853}
5854
5855bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005856 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005857 GLint level,
5858 GLint xoffset,
5859 GLint yoffset,
5860 GLint x,
5861 GLint y,
5862 GLsizei width,
5863 GLsizei height)
5864{
5865 if (context->getClientMajorVersion() < 3)
5866 {
5867 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5868 yoffset, x, y, width, height, 0);
5869 }
5870
5871 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5872 yoffset, 0, x, y, width, height, 0);
5873}
5874
5875bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5876{
5877 return ValidateGenOrDelete(context, n);
5878}
5879
5880bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5881{
5882 return ValidateGenOrDelete(context, n);
5883}
5884
5885bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5886{
5887 return ValidateGenOrDelete(context, n);
5888}
5889
5890bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5891{
5892 return ValidateGenOrDelete(context, n);
5893}
5894
5895bool ValidateDisable(Context *context, GLenum cap)
5896{
5897 if (!ValidCap(context, cap, false))
5898 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005899 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005900 return false;
5901 }
5902
5903 return true;
5904}
5905
5906bool ValidateEnable(Context *context, GLenum cap)
5907{
5908 if (!ValidCap(context, cap, false))
5909 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005910 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005911 return false;
5912 }
5913
5914 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5915 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5916 {
5917 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005918 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005919
5920 // We also output an error message to the debugger window if tracing is active, so that
5921 // developers can see the error message.
5922 ERR() << errorMessage;
5923 return false;
5924 }
5925
5926 return true;
5927}
5928
5929bool ValidateFramebufferRenderbuffer(Context *context,
5930 GLenum target,
5931 GLenum attachment,
5932 GLenum renderbuffertarget,
5933 GLuint renderbuffer)
5934{
Geoff Lange8afa902017-09-27 15:00:43 -04005935 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005936 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005937 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5938 return false;
5939 }
5940
5941 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5942 {
5943 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005944 return false;
5945 }
5946
5947 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5948 renderbuffertarget, renderbuffer);
5949}
5950
5951bool ValidateFramebufferTexture2D(Context *context,
5952 GLenum target,
5953 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005954 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005955 GLuint texture,
5956 GLint level)
5957{
5958 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5959 // extension
5960 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5961 level != 0)
5962 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005963 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005964 return false;
5965 }
5966
5967 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5968 {
5969 return false;
5970 }
5971
5972 if (texture != 0)
5973 {
5974 gl::Texture *tex = context->getTexture(texture);
5975 ASSERT(tex);
5976
5977 const gl::Caps &caps = context->getCaps();
5978
5979 switch (textarget)
5980 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005981 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005982 {
5983 if (level > gl::log2(caps.max2DTextureSize))
5984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005985 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005986 return false;
5987 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005988 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005989 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005990 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005991 return false;
5992 }
5993 }
5994 break;
5995
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005996 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005997 {
5998 if (level != 0)
5999 {
6000 context->handleError(InvalidValue());
6001 return false;
6002 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006003 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006004 {
6005 context->handleError(InvalidOperation()
6006 << "Textarget must match the texture target type.");
6007 return false;
6008 }
6009 }
6010 break;
6011
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006012 case TextureTarget::CubeMapNegativeX:
6013 case TextureTarget::CubeMapNegativeY:
6014 case TextureTarget::CubeMapNegativeZ:
6015 case TextureTarget::CubeMapPositiveX:
6016 case TextureTarget::CubeMapPositiveY:
6017 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006018 {
6019 if (level > gl::log2(caps.maxCubeMapTextureSize))
6020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006021 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006022 return false;
6023 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006024 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006025 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006026 context->handleError(InvalidOperation()
6027 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006028 return false;
6029 }
6030 }
6031 break;
6032
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006033 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006034 {
6035 if (context->getClientVersion() < ES_3_1)
6036 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006037 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006038 return false;
6039 }
6040
6041 if (level != 0)
6042 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006043 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006044 return false;
6045 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006046 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006047 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006048 context->handleError(InvalidOperation()
6049 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006050 return false;
6051 }
6052 }
6053 break;
6054
6055 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006056 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006057 return false;
6058 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006059 }
6060
6061 return true;
6062}
6063
6064bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6065{
6066 return ValidateGenOrDelete(context, n);
6067}
6068
6069bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6070{
6071 return ValidateGenOrDelete(context, n);
6072}
6073
6074bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6075{
6076 return ValidateGenOrDelete(context, n);
6077}
6078
6079bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6080{
6081 return ValidateGenOrDelete(context, n);
6082}
6083
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006084bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006085{
6086 if (!ValidTextureTarget(context, target))
6087 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006088 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006089 return false;
6090 }
6091
6092 Texture *texture = context->getTargetTexture(target);
6093
6094 if (texture == nullptr)
6095 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006096 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006097 return false;
6098 }
6099
6100 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6101
6102 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6103 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6104 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6105 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006106 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006107 return false;
6108 }
6109
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006110 TextureTarget baseTarget = (target == TextureType::CubeMap)
6111 ? TextureTarget::CubeMapPositiveX
6112 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006113 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6114 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6115 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006116 {
6117 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6118 return false;
6119 }
6120
Geoff Lang536eca12017-09-13 11:23:35 -04006121 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6122 bool formatUnsized = !format.sized;
6123 bool formatColorRenderableAndFilterable =
6124 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006125 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006126 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006127 {
Geoff Lang536eca12017-09-13 11:23:35 -04006128 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006129 return false;
6130 }
6131
Geoff Lang536eca12017-09-13 11:23:35 -04006132 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6133 // generation
6134 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6135 {
6136 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6137 return false;
6138 }
6139
Jiange2c00842018-07-13 16:50:49 +08006140 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6141 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6142 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006143 {
Geoff Lang536eca12017-09-13 11:23:35 -04006144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006145 return false;
6146 }
6147
6148 // Non-power of 2 ES2 check
6149 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6150 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6151 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6152 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006153 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6154 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006155 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006156 return false;
6157 }
6158
6159 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006160 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006161 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006162 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006163 return false;
6164 }
6165
6166 return true;
6167}
6168
Jamie Madill5b772312018-03-08 20:28:32 -05006169bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006170 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006171 GLenum pname,
6172 GLint *params)
6173{
6174 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6175}
6176
6177bool ValidateGetRenderbufferParameteriv(Context *context,
6178 GLenum target,
6179 GLenum pname,
6180 GLint *params)
6181{
6182 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6183}
6184
6185bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6186{
6187 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6188}
6189
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006190bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006191{
6192 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6193}
6194
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006195bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006196{
6197 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6198}
6199
6200bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6201{
6202 return ValidateGetUniformBase(context, program, location);
6203}
6204
6205bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6206{
6207 return ValidateGetUniformBase(context, program, location);
6208}
6209
6210bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6211{
6212 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6213}
6214
6215bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6216{
6217 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6218}
6219
6220bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6221{
6222 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6223}
6224
6225bool ValidateIsEnabled(Context *context, GLenum cap)
6226{
6227 if (!ValidCap(context, cap, true))
6228 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006229 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006230 return false;
6231 }
6232
6233 return true;
6234}
6235
6236bool ValidateLinkProgram(Context *context, GLuint program)
6237{
6238 if (context->hasActiveTransformFeedback(program))
6239 {
6240 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006241 context->handleError(InvalidOperation() << "Cannot link program while program is "
6242 "associated with an active transform "
6243 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006244 return false;
6245 }
6246
6247 Program *programObject = GetValidProgram(context, program);
6248 if (!programObject)
6249 {
6250 return false;
6251 }
6252
6253 return true;
6254}
6255
Jamie Madill4928b7c2017-06-20 12:57:39 -04006256bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006257 GLint x,
6258 GLint y,
6259 GLsizei width,
6260 GLsizei height,
6261 GLenum format,
6262 GLenum type,
6263 void *pixels)
6264{
6265 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6266 nullptr, pixels);
6267}
6268
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006269bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006270{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006271 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006272}
6273
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006274bool ValidateTexParameterfv(Context *context,
6275 TextureType target,
6276 GLenum pname,
6277 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006278{
6279 return ValidateTexParameterBase(context, target, pname, -1, params);
6280}
6281
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006282bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006283{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006284 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006285}
6286
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006287bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006288{
6289 return ValidateTexParameterBase(context, target, pname, -1, params);
6290}
6291
6292bool ValidateUseProgram(Context *context, GLuint program)
6293{
6294 if (program != 0)
6295 {
6296 Program *programObject = context->getProgram(program);
6297 if (!programObject)
6298 {
6299 // ES 3.1.0 section 7.3 page 72
6300 if (context->getShader(program))
6301 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006302 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006303 return false;
6304 }
6305 else
6306 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006307 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006308 return false;
6309 }
6310 }
6311 if (!programObject->isLinked())
6312 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006313 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006314 return false;
6315 }
6316 }
6317 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6318 {
6319 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006320 context
6321 ->handleError(InvalidOperation()
6322 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006323 return false;
6324 }
6325
6326 return true;
6327}
6328
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006329bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6330{
6331 if (!context->getExtensions().fence)
6332 {
6333 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6334 return false;
6335 }
6336
6337 if (n < 0)
6338 {
6339 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6340 return false;
6341 }
6342
6343 return true;
6344}
6345
6346bool ValidateFinishFenceNV(Context *context, GLuint fence)
6347{
6348 if (!context->getExtensions().fence)
6349 {
6350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6351 return false;
6352 }
6353
6354 FenceNV *fenceObject = context->getFenceNV(fence);
6355
6356 if (fenceObject == nullptr)
6357 {
6358 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6359 return false;
6360 }
6361
6362 if (!fenceObject->isSet())
6363 {
6364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6365 return false;
6366 }
6367
6368 return true;
6369}
6370
6371bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6372{
6373 if (!context->getExtensions().fence)
6374 {
6375 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6376 return false;
6377 }
6378
6379 if (n < 0)
6380 {
6381 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6382 return false;
6383 }
6384
6385 return true;
6386}
6387
6388bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6389{
6390 if (!context->getExtensions().fence)
6391 {
6392 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6393 return false;
6394 }
6395
6396 FenceNV *fenceObject = context->getFenceNV(fence);
6397
6398 if (fenceObject == nullptr)
6399 {
6400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6401 return false;
6402 }
6403
6404 if (!fenceObject->isSet())
6405 {
6406 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6407 return false;
6408 }
6409
6410 switch (pname)
6411 {
6412 case GL_FENCE_STATUS_NV:
6413 case GL_FENCE_CONDITION_NV:
6414 break;
6415
6416 default:
6417 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6418 return false;
6419 }
6420
6421 return true;
6422}
6423
6424bool ValidateGetGraphicsResetStatusEXT(Context *context)
6425{
6426 if (!context->getExtensions().robustness)
6427 {
6428 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6429 return false;
6430 }
6431
6432 return true;
6433}
6434
6435bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6436 GLuint shader,
6437 GLsizei bufsize,
6438 GLsizei *length,
6439 GLchar *source)
6440{
6441 if (!context->getExtensions().translatedShaderSource)
6442 {
6443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6444 return false;
6445 }
6446
6447 if (bufsize < 0)
6448 {
6449 context->handleError(InvalidValue());
6450 return false;
6451 }
6452
6453 Shader *shaderObject = context->getShader(shader);
6454
6455 if (!shaderObject)
6456 {
6457 context->handleError(InvalidOperation());
6458 return false;
6459 }
6460
6461 return true;
6462}
6463
6464bool ValidateIsFenceNV(Context *context, GLuint fence)
6465{
6466 if (!context->getExtensions().fence)
6467 {
6468 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6469 return false;
6470 }
6471
6472 return true;
6473}
6474
Jamie Madill007530e2017-12-28 14:27:04 -05006475bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6476{
6477 if (!context->getExtensions().fence)
6478 {
6479 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6480 return false;
6481 }
6482
6483 if (condition != GL_ALL_COMPLETED_NV)
6484 {
6485 context->handleError(InvalidEnum());
6486 return false;
6487 }
6488
6489 FenceNV *fenceObject = context->getFenceNV(fence);
6490
6491 if (fenceObject == nullptr)
6492 {
6493 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6494 return false;
6495 }
6496
6497 return true;
6498}
6499
6500bool ValidateTestFenceNV(Context *context, GLuint fence)
6501{
6502 if (!context->getExtensions().fence)
6503 {
6504 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6505 return false;
6506 }
6507
6508 FenceNV *fenceObject = context->getFenceNV(fence);
6509
6510 if (fenceObject == nullptr)
6511 {
6512 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6513 return false;
6514 }
6515
6516 if (fenceObject->isSet() != GL_TRUE)
6517 {
6518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6519 return false;
6520 }
6521
6522 return true;
6523}
6524
6525bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006526 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006527 GLsizei levels,
6528 GLenum internalformat,
6529 GLsizei width,
6530 GLsizei height)
6531{
6532 if (!context->getExtensions().textureStorage)
6533 {
6534 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6535 return false;
6536 }
6537
6538 if (context->getClientMajorVersion() < 3)
6539 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006540 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006541 height);
6542 }
6543
6544 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006545 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006546 1);
6547}
6548
6549bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6550{
6551 if (!context->getExtensions().instancedArrays)
6552 {
6553 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6554 return false;
6555 }
6556
6557 if (index >= MAX_VERTEX_ATTRIBS)
6558 {
6559 context->handleError(InvalidValue());
6560 return false;
6561 }
6562
6563 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6564 {
6565 if (index == 0 && divisor != 0)
6566 {
6567 const char *errorMessage =
6568 "The current context doesn't support setting a non-zero divisor on the "
6569 "attribute with index zero. "
6570 "Please reorder the attributes in your vertex shader so that attribute zero "
6571 "can have a zero divisor.";
6572 context->handleError(InvalidOperation() << errorMessage);
6573
6574 // We also output an error message to the debugger window if tracing is active, so
6575 // that developers can see the error message.
6576 ERR() << errorMessage;
6577 return false;
6578 }
6579 }
6580
6581 return true;
6582}
6583
6584bool ValidateTexImage3DOES(Context *context,
6585 GLenum target,
6586 GLint level,
6587 GLenum internalformat,
6588 GLsizei width,
6589 GLsizei height,
6590 GLsizei depth,
6591 GLint border,
6592 GLenum format,
6593 GLenum type,
6594 const void *pixels)
6595{
6596 UNIMPLEMENTED(); // FIXME
6597 return false;
6598}
6599
6600bool ValidatePopGroupMarkerEXT(Context *context)
6601{
6602 if (!context->getExtensions().debugMarker)
6603 {
6604 // The debug marker calls should not set error state
6605 // However, it seems reasonable to set an error state if the extension is not enabled
6606 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6607 return false;
6608 }
6609
6610 return true;
6611}
6612
Jamie Madillfa920eb2018-01-04 11:45:50 -05006613bool ValidateTexStorage1DEXT(Context *context,
6614 GLenum target,
6615 GLsizei levels,
6616 GLenum internalformat,
6617 GLsizei width)
6618{
6619 UNIMPLEMENTED();
6620 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6621 return false;
6622}
6623
6624bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006625 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006626 GLsizei levels,
6627 GLenum internalformat,
6628 GLsizei width,
6629 GLsizei height,
6630 GLsizei depth)
6631{
6632 if (!context->getExtensions().textureStorage)
6633 {
6634 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6635 return false;
6636 }
6637
6638 if (context->getClientMajorVersion() < 3)
6639 {
6640 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6641 return false;
6642 }
6643
6644 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6645 depth);
6646}
6647
jchen1082af6202018-06-22 10:59:52 +08006648bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6649{
6650 if (!context->getExtensions().parallelShaderCompile)
6651 {
6652 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6653 return false;
6654 }
6655 return true;
6656}
6657
Jamie Madillc29968b2016-01-20 11:17:23 -05006658} // namespace gl