blob: 7b261d195cde0d609f6722d6bf0c397454039b2e [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;
78 if (context->hasPath(pathName) && !context->hasPathData(pathName))
79 {
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 Jones22026802018-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 Jones22026802018-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 Madillbe849e42017-05-02 15:49:00 -0400458bool ValidateES2CopyTexImageParameters(ValidationContext *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
795 default:
796 return false;
797 }
798}
799
Geoff Langfc32e8b2017-05-31 14:16:59 -0400800// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
801// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400802bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400803{
804 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400805 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
806 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400807 {
808 return true;
809 }
810
811 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
812 if (c >= 9 && c <= 13)
813 {
814 return true;
815 }
816
817 return false;
818}
819
Geoff Langcab92ee2017-07-19 17:32:07 -0400820bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400821{
Geoff Langa71a98e2017-06-19 15:15:00 -0400822 for (size_t i = 0; i < len; i++)
823 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400824 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400825 {
826 return false;
827 }
828 }
829
830 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400831}
832
Geoff Langcab92ee2017-07-19 17:32:07 -0400833bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
834{
835 enum class ParseState
836 {
837 // Have not seen an ASCII non-whitespace character yet on
838 // this line. Possible that we might see a preprocessor
839 // directive.
840 BEGINING_OF_LINE,
841
842 // Have seen at least one ASCII non-whitespace character
843 // on this line.
844 MIDDLE_OF_LINE,
845
846 // Handling a preprocessor directive. Passes through all
847 // characters up to the end of the line. Disables comment
848 // processing.
849 IN_PREPROCESSOR_DIRECTIVE,
850
851 // Handling a single-line comment. The comment text is
852 // replaced with a single space.
853 IN_SINGLE_LINE_COMMENT,
854
855 // Handling a multi-line comment. Newlines are passed
856 // through to preserve line numbers.
857 IN_MULTI_LINE_COMMENT
858 };
859
860 ParseState state = ParseState::BEGINING_OF_LINE;
861 size_t pos = 0;
862
863 while (pos < len)
864 {
865 char c = str[pos];
866 char next = pos + 1 < len ? str[pos + 1] : 0;
867
868 // Check for newlines
869 if (c == '\n' || c == '\r')
870 {
871 if (state != ParseState::IN_MULTI_LINE_COMMENT)
872 {
873 state = ParseState::BEGINING_OF_LINE;
874 }
875
876 pos++;
877 continue;
878 }
879
880 switch (state)
881 {
882 case ParseState::BEGINING_OF_LINE:
883 if (c == ' ')
884 {
885 // Maintain the BEGINING_OF_LINE state until a non-space is seen
886 pos++;
887 }
888 else if (c == '#')
889 {
890 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
891 pos++;
892 }
893 else
894 {
895 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
896 state = ParseState::MIDDLE_OF_LINE;
897 }
898 break;
899
900 case ParseState::MIDDLE_OF_LINE:
901 if (c == '/' && next == '/')
902 {
903 state = ParseState::IN_SINGLE_LINE_COMMENT;
904 pos++;
905 }
906 else if (c == '/' && next == '*')
907 {
908 state = ParseState::IN_MULTI_LINE_COMMENT;
909 pos++;
910 }
911 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
912 {
913 // Skip line continuation characters
914 }
915 else if (!IsValidESSLCharacter(c))
916 {
917 return false;
918 }
919 pos++;
920 break;
921
922 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700923 // Line-continuation characters may not be permitted.
924 // Otherwise, just pass it through. Do not parse comments in this state.
925 if (!lineContinuationAllowed && c == '\\')
926 {
927 return false;
928 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400929 pos++;
930 break;
931
932 case ParseState::IN_SINGLE_LINE_COMMENT:
933 // Line-continuation characters are processed before comment processing.
934 // Advance string if a new line character is immediately behind
935 // line-continuation character.
936 if (c == '\\' && (next == '\n' || next == '\r'))
937 {
938 pos++;
939 }
940 pos++;
941 break;
942
943 case ParseState::IN_MULTI_LINE_COMMENT:
944 if (c == '*' && next == '/')
945 {
946 state = ParseState::MIDDLE_OF_LINE;
947 pos++;
948 }
949 pos++;
950 break;
951 }
952 }
953
954 return true;
955}
956
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700957bool ValidateWebGLNamePrefix(ValidationContext *context, const GLchar *name)
958{
959 ASSERT(context->isWebGL());
960
961 // WebGL 1.0 [Section 6.16] GLSL Constructs
962 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
963 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
964 {
965 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
966 return false;
967 }
968
969 return true;
970}
971
972bool ValidateWebGLNameLength(ValidationContext *context, size_t length)
973{
974 ASSERT(context->isWebGL());
975
976 if (context->isWebGL1() && length > 256)
977 {
978 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
979 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
980 // locations.
981 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
982
983 return false;
984 }
985 else if (length > 1024)
986 {
987 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
988 // uniform and attribute locations.
989 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
990 return false;
991 }
992
993 return true;
994}
995
Jamie Madill007530e2017-12-28 14:27:04 -0500996bool ValidateMatrixMode(Context *context, GLenum matrixMode)
997{
998 if (!context->getExtensions().pathRendering)
999 {
1000 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1001 return false;
1002 }
1003
1004 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1005 {
1006 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1007 return false;
1008 }
1009 return true;
1010}
Jamie Madillc29968b2016-01-20 11:17:23 -05001011} // anonymous namespace
1012
Geoff Langff5b2d52016-09-07 11:32:23 -04001013bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001014 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001015 GLint level,
1016 GLenum internalformat,
1017 bool isCompressed,
1018 bool isSubImage,
1019 GLint xoffset,
1020 GLint yoffset,
1021 GLsizei width,
1022 GLsizei height,
1023 GLint border,
1024 GLenum format,
1025 GLenum type,
1026 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001027 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001028{
Jamie Madill6f38f822014-06-06 17:12:20 -04001029 if (!ValidTexture2DDestinationTarget(context, target))
1030 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001031 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001032 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001033 }
1034
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001035 TextureType texType = TextureTargetToType(target);
1036 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001037 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001038 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001039 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001040 }
1041
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001042 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001043 {
1044 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1045 return false;
1046 }
1047
1048 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001049 std::numeric_limits<GLsizei>::max() - yoffset < height)
1050 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001051 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001052 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001053 }
1054
Geoff Lang6e898aa2017-06-02 11:17:26 -04001055 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1056 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1057 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1058 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1059 // case.
1060 bool nonEqualFormatsAllowed =
1061 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1062 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1063
1064 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001065 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001066 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001067 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001068 }
1069
Geoff Langaae65a42014-05-26 12:43:44 -04001070 const gl::Caps &caps = context->getCaps();
1071
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001072 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001073 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001074 case TextureType::_2D:
1075 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1076 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1077 {
1078 context->handleError(InvalidValue());
1079 return false;
1080 }
1081 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001082
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001083 case TextureType::Rectangle:
1084 ASSERT(level == 0);
1085 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1086 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1087 {
1088 context->handleError(InvalidValue());
1089 return false;
1090 }
1091 if (isCompressed)
1092 {
1093 context->handleError(InvalidEnum()
1094 << "Rectangle texture cannot have a compressed format.");
1095 return false;
1096 }
1097 break;
1098
1099 case TextureType::CubeMap:
1100 if (!isSubImage && width != height)
1101 {
1102 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1103 return false;
1104 }
1105
1106 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1107 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1108 {
1109 context->handleError(InvalidValue());
1110 return false;
1111 }
1112 break;
1113
1114 default:
1115 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001116 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001117 }
1118
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001119 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001120 if (!texture)
1121 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001122 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001123 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001124 }
1125
Geoff Langa9be0dc2014-12-17 12:34:40 -05001126 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001127 {
Geoff Langca271392017-04-05 12:30:00 -04001128 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1129 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001131 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001132 return false;
1133 }
1134
Geoff Langa9be0dc2014-12-17 12:34:40 -05001135 if (format != GL_NONE)
1136 {
Geoff Langca271392017-04-05 12:30:00 -04001137 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1138 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001139 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001140 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001141 return false;
1142 }
1143 }
1144
1145 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1146 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001148 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001149 return false;
1150 }
Geoff Langfb052642017-10-24 13:42:09 -04001151
1152 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001153 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001154 {
1155 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1156 return false;
1157 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001158 }
1159 else
1160 {
Geoff Lang69cce582015-09-17 13:20:36 -04001161 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001163 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001164 return false;
1165 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001166 }
1167
1168 // Verify zero border
1169 if (border != 0)
1170 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001171 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001172 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001173 }
1174
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001175 if (isCompressed)
1176 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001177 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001178 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1179 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001180 switch (actualInternalFormat)
1181 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001182 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1183 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1184 if (!context->getExtensions().textureCompressionDXT1)
1185 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001186 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001187 return false;
1188 }
1189 break;
1190 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001191 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001192 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001193 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001194 return false;
1195 }
1196 break;
1197 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1198 if (!context->getExtensions().textureCompressionDXT5)
1199 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001201 return false;
1202 }
1203 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001204 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1205 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1206 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1207 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1208 if (!context->getExtensions().textureCompressionS3TCsRGB)
1209 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001210 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001211 return false;
1212 }
1213 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001214 case GL_ETC1_RGB8_OES:
1215 if (!context->getExtensions().compressedETC1RGB8Texture)
1216 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001217 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001218 return false;
1219 }
Geoff Lang86f81162017-10-30 15:10:45 -04001220 if (isSubImage)
1221 {
1222 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1223 return false;
1224 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001225 break;
1226 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001227 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1228 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1229 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1230 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001231 if (!context->getExtensions().lossyETCDecode)
1232 {
Geoff Lang86f81162017-10-30 15:10:45 -04001233 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001234 return false;
1235 }
1236 break;
1237 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001238 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001239 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001240 }
Geoff Lang966c9402017-04-18 12:38:27 -04001241
1242 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001243 {
Geoff Lang966c9402017-04-18 12:38:27 -04001244 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1245 height, texture->getWidth(target, level),
1246 texture->getHeight(target, level)))
1247 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001248 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001249 return false;
1250 }
1251
1252 if (format != actualInternalFormat)
1253 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001254 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001255 return false;
1256 }
1257 }
1258 else
1259 {
1260 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1261 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001262 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001263 return false;
1264 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001265 }
1266 }
1267 else
1268 {
1269 // validate <type> by itself (used as secondary key below)
1270 switch (type)
1271 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001272 case GL_UNSIGNED_BYTE:
1273 case GL_UNSIGNED_SHORT_5_6_5:
1274 case GL_UNSIGNED_SHORT_4_4_4_4:
1275 case GL_UNSIGNED_SHORT_5_5_5_1:
1276 case GL_UNSIGNED_SHORT:
1277 case GL_UNSIGNED_INT:
1278 case GL_UNSIGNED_INT_24_8_OES:
1279 case GL_HALF_FLOAT_OES:
1280 case GL_FLOAT:
1281 break;
1282 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001283 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001284 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001285 }
1286
1287 // validate <format> + <type> combinations
1288 // - invalid <format> -> sets INVALID_ENUM
1289 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1290 switch (format)
1291 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001292 case GL_ALPHA:
1293 case GL_LUMINANCE:
1294 case GL_LUMINANCE_ALPHA:
1295 switch (type)
1296 {
1297 case GL_UNSIGNED_BYTE:
1298 case GL_FLOAT:
1299 case GL_HALF_FLOAT_OES:
1300 break;
1301 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001302 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 return false;
1304 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001305 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001306 case GL_RED:
1307 case GL_RG:
1308 if (!context->getExtensions().textureRG)
1309 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001310 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001311 return false;
1312 }
1313 switch (type)
1314 {
1315 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001316 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001317 case GL_FLOAT:
1318 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001319 if (!context->getExtensions().textureFloat)
1320 {
1321 context->handleError(InvalidEnum());
1322 return false;
1323 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001324 break;
1325 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001326 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001327 return false;
1328 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001330 case GL_RGB:
1331 switch (type)
1332 {
1333 case GL_UNSIGNED_BYTE:
1334 case GL_UNSIGNED_SHORT_5_6_5:
1335 case GL_FLOAT:
1336 case GL_HALF_FLOAT_OES:
1337 break;
1338 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001339 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001340 return false;
1341 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001342 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001343 case GL_RGBA:
1344 switch (type)
1345 {
1346 case GL_UNSIGNED_BYTE:
1347 case GL_UNSIGNED_SHORT_4_4_4_4:
1348 case GL_UNSIGNED_SHORT_5_5_5_1:
1349 case GL_FLOAT:
1350 case GL_HALF_FLOAT_OES:
1351 break;
1352 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001354 return false;
1355 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001356 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001357 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001358 if (!context->getExtensions().textureFormatBGRA8888)
1359 {
1360 context->handleError(InvalidEnum());
1361 return false;
1362 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001363 switch (type)
1364 {
1365 case GL_UNSIGNED_BYTE:
1366 break;
1367 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 return false;
1370 }
1371 break;
1372 case GL_SRGB_EXT:
1373 case GL_SRGB_ALPHA_EXT:
1374 if (!context->getExtensions().sRGB)
1375 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001376 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001377 return false;
1378 }
1379 switch (type)
1380 {
1381 case GL_UNSIGNED_BYTE:
1382 break;
1383 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001384 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001385 return false;
1386 }
1387 break;
1388 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1389 // handled below
1390 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1391 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1392 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1393 break;
1394 case GL_DEPTH_COMPONENT:
1395 switch (type)
1396 {
1397 case GL_UNSIGNED_SHORT:
1398 case GL_UNSIGNED_INT:
1399 break;
1400 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001401 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001402 return false;
1403 }
1404 break;
1405 case GL_DEPTH_STENCIL_OES:
1406 switch (type)
1407 {
1408 case GL_UNSIGNED_INT_24_8_OES:
1409 break;
1410 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001411 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001412 return false;
1413 }
1414 break;
1415 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001416 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001417 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001418 }
1419
1420 switch (format)
1421 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001422 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1423 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1424 if (context->getExtensions().textureCompressionDXT1)
1425 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001426 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001427 return false;
1428 }
1429 else
1430 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001431 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001432 return false;
1433 }
1434 break;
1435 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1436 if (context->getExtensions().textureCompressionDXT3)
1437 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001438 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001439 return false;
1440 }
1441 else
1442 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001443 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001444 return false;
1445 }
1446 break;
1447 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1448 if (context->getExtensions().textureCompressionDXT5)
1449 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001450 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 return false;
1452 }
1453 else
1454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001455 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001456 return false;
1457 }
1458 break;
1459 case GL_ETC1_RGB8_OES:
1460 if (context->getExtensions().compressedETC1RGB8Texture)
1461 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001462 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001463 return false;
1464 }
1465 else
1466 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001467 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 return false;
1469 }
1470 break;
1471 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001472 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1473 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1474 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1475 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001476 if (context->getExtensions().lossyETCDecode)
1477 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001478 context->handleError(InvalidOperation()
1479 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001480 return false;
1481 }
1482 else
1483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001484 context->handleError(InvalidEnum()
1485 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001486 return false;
1487 }
1488 break;
1489 case GL_DEPTH_COMPONENT:
1490 case GL_DEPTH_STENCIL_OES:
1491 if (!context->getExtensions().depthTextures)
1492 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001493 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001494 return false;
1495 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001496 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001498 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001499 return false;
1500 }
1501 // OES_depth_texture supports loading depth data and multiple levels,
1502 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001503 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001504 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1506 return false;
1507 }
1508 if (level != 0)
1509 {
1510 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001511 return false;
1512 }
1513 break;
1514 default:
1515 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001516 }
1517
Geoff Lang6e898aa2017-06-02 11:17:26 -04001518 if (!isSubImage)
1519 {
1520 switch (internalformat)
1521 {
1522 case GL_RGBA32F:
1523 if (!context->getExtensions().colorBufferFloatRGBA)
1524 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001525 context->handleError(InvalidValue()
1526 << "Sized GL_RGBA32F internal format requires "
1527 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001528 return false;
1529 }
1530 if (type != GL_FLOAT)
1531 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001532 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001533 return false;
1534 }
1535 if (format != GL_RGBA)
1536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001537 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001538 return false;
1539 }
1540 break;
1541
1542 case GL_RGB32F:
1543 if (!context->getExtensions().colorBufferFloatRGB)
1544 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001545 context->handleError(InvalidValue()
1546 << "Sized GL_RGB32F internal format requires "
1547 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001548 return false;
1549 }
1550 if (type != GL_FLOAT)
1551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001552 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001553 return false;
1554 }
1555 if (format != GL_RGB)
1556 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001557 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001558 return false;
1559 }
1560 break;
1561
1562 default:
1563 break;
1564 }
1565 }
1566
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001567 if (type == GL_FLOAT)
1568 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001569 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001570 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001571 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001572 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001573 }
1574 }
1575 else if (type == GL_HALF_FLOAT_OES)
1576 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001577 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001578 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001579 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001580 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001581 }
1582 }
1583 }
1584
Geoff Langdbcced82017-06-06 15:55:54 -04001585 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001586 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001587 imageSize))
1588 {
1589 return false;
1590 }
1591
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001592 return true;
1593}
1594
He Yunchaoced53ae2016-11-29 15:00:51 +08001595bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001596 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001597 GLsizei levels,
1598 GLenum internalformat,
1599 GLsizei width,
1600 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001601{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001602 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1603 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001604 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001605 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001606 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001607 }
1608
1609 if (width < 1 || height < 1 || levels < 1)
1610 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001611 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001612 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001613 }
1614
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001615 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001616 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001617 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001618 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001619 }
1620
1621 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1622 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001623 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001624 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001625 }
1626
Geoff Langca271392017-04-05 12:30:00 -04001627 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001628 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001629 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001630 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001631 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001632 }
1633
Geoff Langaae65a42014-05-26 12:43:44 -04001634 const gl::Caps &caps = context->getCaps();
1635
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 switch (target)
1637 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001638 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001639 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1640 static_cast<GLuint>(height) > caps.max2DTextureSize)
1641 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001642 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001643 return false;
1644 }
1645 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001646 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001647 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1648 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1649 {
1650 context->handleError(InvalidValue());
1651 return false;
1652 }
1653 if (formatInfo.compressed)
1654 {
1655 context->handleError(InvalidEnum()
1656 << "Rectangle texture cannot have a compressed format.");
1657 return false;
1658 }
1659 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001660 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001661 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1662 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1663 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001664 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001665 return false;
1666 }
1667 break;
1668 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001669 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001670 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001671 }
1672
Geoff Langc0b9ef42014-07-02 10:02:37 -04001673 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001674 {
1675 if (!gl::isPow2(width) || !gl::isPow2(height))
1676 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001677 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001678 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001679 }
1680 }
1681
1682 switch (internalformat)
1683 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001684 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1685 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1686 if (!context->getExtensions().textureCompressionDXT1)
1687 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001688 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001689 return false;
1690 }
1691 break;
1692 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1693 if (!context->getExtensions().textureCompressionDXT3)
1694 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001695 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001696 return false;
1697 }
1698 break;
1699 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1700 if (!context->getExtensions().textureCompressionDXT5)
1701 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001702 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001703 return false;
1704 }
1705 break;
1706 case GL_ETC1_RGB8_OES:
1707 if (!context->getExtensions().compressedETC1RGB8Texture)
1708 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001709 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001710 return false;
1711 }
1712 break;
1713 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001714 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1715 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1716 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1717 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001718 if (!context->getExtensions().lossyETCDecode)
1719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001720 context->handleError(InvalidEnum()
1721 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001722 return false;
1723 }
1724 break;
1725 case GL_RGBA32F_EXT:
1726 case GL_RGB32F_EXT:
1727 case GL_ALPHA32F_EXT:
1728 case GL_LUMINANCE32F_EXT:
1729 case GL_LUMINANCE_ALPHA32F_EXT:
1730 if (!context->getExtensions().textureFloat)
1731 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001732 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001733 return false;
1734 }
1735 break;
1736 case GL_RGBA16F_EXT:
1737 case GL_RGB16F_EXT:
1738 case GL_ALPHA16F_EXT:
1739 case GL_LUMINANCE16F_EXT:
1740 case GL_LUMINANCE_ALPHA16F_EXT:
1741 if (!context->getExtensions().textureHalfFloat)
1742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001743 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001744 return false;
1745 }
1746 break;
1747 case GL_R8_EXT:
1748 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001749 if (!context->getExtensions().textureRG)
1750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001751 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001752 return false;
1753 }
1754 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001755 case GL_R16F_EXT:
1756 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001757 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001759 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001760 return false;
1761 }
1762 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001763 case GL_R32F_EXT:
1764 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001765 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001767 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001768 return false;
1769 }
1770 break;
1771 case GL_DEPTH_COMPONENT16:
1772 case GL_DEPTH_COMPONENT32_OES:
1773 case GL_DEPTH24_STENCIL8_OES:
1774 if (!context->getExtensions().depthTextures)
1775 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001776 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001777 return false;
1778 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001779 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001781 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001782 return false;
1783 }
1784 // ANGLE_depth_texture only supports 1-level textures
1785 if (levels != 1)
1786 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001787 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001788 return false;
1789 }
1790 break;
1791 default:
1792 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001793 }
1794
Geoff Lang691e58c2014-12-19 17:03:25 -05001795 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001796 if (!texture || texture->id() == 0)
1797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001798 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001799 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001800 }
1801
Geoff Lang69cce582015-09-17 13:20:36 -04001802 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001803 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001804 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001805 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001806 }
1807
1808 return true;
1809}
1810
He Yunchaoced53ae2016-11-29 15:00:51 +08001811bool ValidateDiscardFramebufferEXT(Context *context,
1812 GLenum target,
1813 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001814 const GLenum *attachments)
1815{
Jamie Madillc29968b2016-01-20 11:17:23 -05001816 if (!context->getExtensions().discardFramebuffer)
1817 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001818 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001819 return false;
1820 }
1821
Austin Kinross08332632015-05-05 13:35:47 -07001822 bool defaultFramebuffer = false;
1823
1824 switch (target)
1825 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001826 case GL_FRAMEBUFFER:
1827 defaultFramebuffer =
1828 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1829 break;
1830 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001831 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001832 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001833 }
1834
He Yunchaoced53ae2016-11-29 15:00:51 +08001835 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1836 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001837}
1838
Austin Kinrossbc781f32015-10-26 09:27:38 -07001839bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1840{
1841 if (!context->getExtensions().vertexArrayObject)
1842 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001843 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001844 return false;
1845 }
1846
1847 return ValidateBindVertexArrayBase(context, array);
1848}
1849
Jamie Madilld7576732017-08-26 18:49:50 -04001850bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001851{
1852 if (!context->getExtensions().vertexArrayObject)
1853 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001854 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001855 return false;
1856 }
1857
Olli Etuaho41997e72016-03-10 13:38:39 +02001858 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001859}
1860
Jamie Madilld7576732017-08-26 18:49:50 -04001861bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001862{
1863 if (!context->getExtensions().vertexArrayObject)
1864 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001865 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001866 return false;
1867 }
1868
Olli Etuaho41997e72016-03-10 13:38:39 +02001869 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870}
1871
Jamie Madilld7576732017-08-26 18:49:50 -04001872bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001873{
1874 if (!context->getExtensions().vertexArrayObject)
1875 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001876 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001877 return false;
1878 }
1879
1880 return true;
1881}
Geoff Langc5629752015-12-07 16:29:04 -05001882
1883bool ValidateProgramBinaryOES(Context *context,
1884 GLuint program,
1885 GLenum binaryFormat,
1886 const void *binary,
1887 GLint length)
1888{
1889 if (!context->getExtensions().getProgramBinary)
1890 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001891 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001892 return false;
1893 }
1894
1895 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1896}
1897
1898bool ValidateGetProgramBinaryOES(Context *context,
1899 GLuint program,
1900 GLsizei bufSize,
1901 GLsizei *length,
1902 GLenum *binaryFormat,
1903 void *binary)
1904{
1905 if (!context->getExtensions().getProgramBinary)
1906 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001907 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001908 return false;
1909 }
1910
1911 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1912}
Geoff Lange102fee2015-12-10 11:23:30 -05001913
Geoff Lang70d0f492015-12-10 17:45:46 -05001914static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1915{
1916 switch (source)
1917 {
1918 case GL_DEBUG_SOURCE_API:
1919 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1920 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1921 case GL_DEBUG_SOURCE_OTHER:
1922 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1923 return !mustBeThirdPartyOrApplication;
1924
1925 case GL_DEBUG_SOURCE_THIRD_PARTY:
1926 case GL_DEBUG_SOURCE_APPLICATION:
1927 return true;
1928
1929 default:
1930 return false;
1931 }
1932}
1933
1934static bool ValidDebugType(GLenum type)
1935{
1936 switch (type)
1937 {
1938 case GL_DEBUG_TYPE_ERROR:
1939 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1940 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1941 case GL_DEBUG_TYPE_PERFORMANCE:
1942 case GL_DEBUG_TYPE_PORTABILITY:
1943 case GL_DEBUG_TYPE_OTHER:
1944 case GL_DEBUG_TYPE_MARKER:
1945 case GL_DEBUG_TYPE_PUSH_GROUP:
1946 case GL_DEBUG_TYPE_POP_GROUP:
1947 return true;
1948
1949 default:
1950 return false;
1951 }
1952}
1953
1954static bool ValidDebugSeverity(GLenum severity)
1955{
1956 switch (severity)
1957 {
1958 case GL_DEBUG_SEVERITY_HIGH:
1959 case GL_DEBUG_SEVERITY_MEDIUM:
1960 case GL_DEBUG_SEVERITY_LOW:
1961 case GL_DEBUG_SEVERITY_NOTIFICATION:
1962 return true;
1963
1964 default:
1965 return false;
1966 }
1967}
1968
Geoff Lange102fee2015-12-10 11:23:30 -05001969bool ValidateDebugMessageControlKHR(Context *context,
1970 GLenum source,
1971 GLenum type,
1972 GLenum severity,
1973 GLsizei count,
1974 const GLuint *ids,
1975 GLboolean enabled)
1976{
1977 if (!context->getExtensions().debug)
1978 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001979 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001980 return false;
1981 }
1982
Geoff Lang70d0f492015-12-10 17:45:46 -05001983 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1984 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001986 return false;
1987 }
1988
1989 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1990 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001991 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001992 return false;
1993 }
1994
1995 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1996 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001997 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001998 return false;
1999 }
2000
2001 if (count > 0)
2002 {
2003 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2004 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002005 context->handleError(
2006 InvalidOperation()
2007 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002008 return false;
2009 }
2010
2011 if (severity != GL_DONT_CARE)
2012 {
Jamie Madill437fa652016-05-03 15:13:24 -04002013 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002014 InvalidOperation()
2015 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002016 return false;
2017 }
2018 }
2019
Geoff Lange102fee2015-12-10 11:23:30 -05002020 return true;
2021}
2022
2023bool ValidateDebugMessageInsertKHR(Context *context,
2024 GLenum source,
2025 GLenum type,
2026 GLuint id,
2027 GLenum severity,
2028 GLsizei length,
2029 const GLchar *buf)
2030{
2031 if (!context->getExtensions().debug)
2032 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002033 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002034 return false;
2035 }
2036
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002037 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002038 {
2039 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2040 // not generate an error.
2041 return false;
2042 }
2043
2044 if (!ValidDebugSeverity(severity))
2045 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002046 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002047 return false;
2048 }
2049
2050 if (!ValidDebugType(type))
2051 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002052 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002053 return false;
2054 }
2055
2056 if (!ValidDebugSource(source, true))
2057 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002058 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002059 return false;
2060 }
2061
2062 size_t messageLength = (length < 0) ? strlen(buf) : length;
2063 if (messageLength > context->getExtensions().maxDebugMessageLength)
2064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002065 context->handleError(InvalidValue()
2066 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002067 return false;
2068 }
2069
Geoff Lange102fee2015-12-10 11:23:30 -05002070 return true;
2071}
2072
2073bool ValidateDebugMessageCallbackKHR(Context *context,
2074 GLDEBUGPROCKHR callback,
2075 const void *userParam)
2076{
2077 if (!context->getExtensions().debug)
2078 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002079 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002080 return false;
2081 }
2082
Geoff Lange102fee2015-12-10 11:23:30 -05002083 return true;
2084}
2085
2086bool ValidateGetDebugMessageLogKHR(Context *context,
2087 GLuint count,
2088 GLsizei bufSize,
2089 GLenum *sources,
2090 GLenum *types,
2091 GLuint *ids,
2092 GLenum *severities,
2093 GLsizei *lengths,
2094 GLchar *messageLog)
2095{
2096 if (!context->getExtensions().debug)
2097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002098 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002099 return false;
2100 }
2101
Geoff Lang70d0f492015-12-10 17:45:46 -05002102 if (bufSize < 0 && messageLog != nullptr)
2103 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002104 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002105 return false;
2106 }
2107
Geoff Lange102fee2015-12-10 11:23:30 -05002108 return true;
2109}
2110
2111bool ValidatePushDebugGroupKHR(Context *context,
2112 GLenum source,
2113 GLuint id,
2114 GLsizei length,
2115 const GLchar *message)
2116{
2117 if (!context->getExtensions().debug)
2118 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002119 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002120 return false;
2121 }
2122
Geoff Lang70d0f492015-12-10 17:45:46 -05002123 if (!ValidDebugSource(source, true))
2124 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002125 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 return false;
2127 }
2128
2129 size_t messageLength = (length < 0) ? strlen(message) : length;
2130 if (messageLength > context->getExtensions().maxDebugMessageLength)
2131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002132 context->handleError(InvalidValue()
2133 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002134 return false;
2135 }
2136
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002137 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002138 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002140 context
2141 ->handleError(StackOverflow()
2142 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002143 return false;
2144 }
2145
Geoff Lange102fee2015-12-10 11:23:30 -05002146 return true;
2147}
2148
2149bool ValidatePopDebugGroupKHR(Context *context)
2150{
2151 if (!context->getExtensions().debug)
2152 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002153 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002154 return false;
2155 }
2156
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002157 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002158 if (currentStackSize <= 1)
2159 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002160 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002161 return false;
2162 }
2163
2164 return true;
2165}
2166
2167static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2168{
2169 switch (identifier)
2170 {
2171 case GL_BUFFER:
2172 if (context->getBuffer(name) == nullptr)
2173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002174 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002175 return false;
2176 }
2177 return true;
2178
2179 case GL_SHADER:
2180 if (context->getShader(name) == nullptr)
2181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002182 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002183 return false;
2184 }
2185 return true;
2186
2187 case GL_PROGRAM:
2188 if (context->getProgram(name) == nullptr)
2189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002190 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002191 return false;
2192 }
2193 return true;
2194
2195 case GL_VERTEX_ARRAY:
2196 if (context->getVertexArray(name) == nullptr)
2197 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002198 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 return false;
2200 }
2201 return true;
2202
2203 case GL_QUERY:
2204 if (context->getQuery(name) == nullptr)
2205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002206 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002207 return false;
2208 }
2209 return true;
2210
2211 case GL_TRANSFORM_FEEDBACK:
2212 if (context->getTransformFeedback(name) == nullptr)
2213 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002214 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002215 return false;
2216 }
2217 return true;
2218
2219 case GL_SAMPLER:
2220 if (context->getSampler(name) == nullptr)
2221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002222 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002223 return false;
2224 }
2225 return true;
2226
2227 case GL_TEXTURE:
2228 if (context->getTexture(name) == nullptr)
2229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002230 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 return false;
2232 }
2233 return true;
2234
2235 case GL_RENDERBUFFER:
2236 if (context->getRenderbuffer(name) == nullptr)
2237 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002238 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002239 return false;
2240 }
2241 return true;
2242
2243 case GL_FRAMEBUFFER:
2244 if (context->getFramebuffer(name) == nullptr)
2245 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002246 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002247 return false;
2248 }
2249 return true;
2250
2251 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002252 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002253 return false;
2254 }
Geoff Lange102fee2015-12-10 11:23:30 -05002255}
2256
Martin Radev9d901792016-07-15 15:58:58 +03002257static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2258{
2259 size_t labelLength = 0;
2260
2261 if (length < 0)
2262 {
2263 if (label != nullptr)
2264 {
2265 labelLength = strlen(label);
2266 }
2267 }
2268 else
2269 {
2270 labelLength = static_cast<size_t>(length);
2271 }
2272
2273 if (labelLength > context->getExtensions().maxLabelLength)
2274 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002275 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002276 return false;
2277 }
2278
2279 return true;
2280}
2281
Geoff Lange102fee2015-12-10 11:23:30 -05002282bool ValidateObjectLabelKHR(Context *context,
2283 GLenum identifier,
2284 GLuint name,
2285 GLsizei length,
2286 const GLchar *label)
2287{
2288 if (!context->getExtensions().debug)
2289 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002290 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002291 return false;
2292 }
2293
Geoff Lang70d0f492015-12-10 17:45:46 -05002294 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2295 {
2296 return false;
2297 }
2298
Martin Radev9d901792016-07-15 15:58:58 +03002299 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002300 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002301 return false;
2302 }
2303
Geoff Lange102fee2015-12-10 11:23:30 -05002304 return true;
2305}
2306
2307bool ValidateGetObjectLabelKHR(Context *context,
2308 GLenum identifier,
2309 GLuint name,
2310 GLsizei bufSize,
2311 GLsizei *length,
2312 GLchar *label)
2313{
2314 if (!context->getExtensions().debug)
2315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002317 return false;
2318 }
2319
Geoff Lang70d0f492015-12-10 17:45:46 -05002320 if (bufSize < 0)
2321 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002322 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002323 return false;
2324 }
2325
2326 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2327 {
2328 return false;
2329 }
2330
Martin Radev9d901792016-07-15 15:58:58 +03002331 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002332}
2333
2334static bool ValidateObjectPtrName(Context *context, const void *ptr)
2335{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002336 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002337 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002338 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002339 return false;
2340 }
2341
Geoff Lange102fee2015-12-10 11:23:30 -05002342 return true;
2343}
2344
2345bool ValidateObjectPtrLabelKHR(Context *context,
2346 const void *ptr,
2347 GLsizei length,
2348 const GLchar *label)
2349{
2350 if (!context->getExtensions().debug)
2351 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002352 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002353 return false;
2354 }
2355
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 if (!ValidateObjectPtrName(context, ptr))
2357 {
2358 return false;
2359 }
2360
Martin Radev9d901792016-07-15 15:58:58 +03002361 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002362 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002363 return false;
2364 }
2365
Geoff Lange102fee2015-12-10 11:23:30 -05002366 return true;
2367}
2368
2369bool ValidateGetObjectPtrLabelKHR(Context *context,
2370 const void *ptr,
2371 GLsizei bufSize,
2372 GLsizei *length,
2373 GLchar *label)
2374{
2375 if (!context->getExtensions().debug)
2376 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002377 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002378 return false;
2379 }
2380
Geoff Lang70d0f492015-12-10 17:45:46 -05002381 if (bufSize < 0)
2382 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002383 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002384 return false;
2385 }
2386
2387 if (!ValidateObjectPtrName(context, ptr))
2388 {
2389 return false;
2390 }
2391
Martin Radev9d901792016-07-15 15:58:58 +03002392 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002393}
2394
2395bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2396{
2397 if (!context->getExtensions().debug)
2398 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002400 return false;
2401 }
2402
Geoff Lang70d0f492015-12-10 17:45:46 -05002403 // TODO: represent this in Context::getQueryParameterInfo.
2404 switch (pname)
2405 {
2406 case GL_DEBUG_CALLBACK_FUNCTION:
2407 case GL_DEBUG_CALLBACK_USER_PARAM:
2408 break;
2409
2410 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002411 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002412 return false;
2413 }
2414
Geoff Lange102fee2015-12-10 11:23:30 -05002415 return true;
2416}
Jamie Madillc29968b2016-01-20 11:17:23 -05002417
2418bool ValidateBlitFramebufferANGLE(Context *context,
2419 GLint srcX0,
2420 GLint srcY0,
2421 GLint srcX1,
2422 GLint srcY1,
2423 GLint dstX0,
2424 GLint dstY0,
2425 GLint dstX1,
2426 GLint dstY1,
2427 GLbitfield mask,
2428 GLenum filter)
2429{
2430 if (!context->getExtensions().framebufferBlit)
2431 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002432 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002433 return false;
2434 }
2435
2436 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2437 {
2438 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002439 context->handleError(InvalidOperation() << "Scaling and flipping in "
2440 "BlitFramebufferANGLE not supported by this "
2441 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002442 return false;
2443 }
2444
2445 if (filter == GL_LINEAR)
2446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002447 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002448 return false;
2449 }
2450
Jamie Madill51f40ec2016-06-15 14:06:00 -04002451 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2452 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002453
2454 if (mask & GL_COLOR_BUFFER_BIT)
2455 {
2456 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2457 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2458
2459 if (readColorAttachment && drawColorAttachment)
2460 {
2461 if (!(readColorAttachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002462 readColorAttachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002463 readColorAttachment->type() != GL_RENDERBUFFER &&
2464 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002466 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002467 return false;
2468 }
2469
Geoff Langa15472a2015-08-11 11:48:03 -04002470 for (size_t drawbufferIdx = 0;
2471 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002472 {
Geoff Langa15472a2015-08-11 11:48:03 -04002473 const FramebufferAttachment *attachment =
2474 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2475 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002476 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002477 if (!(attachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002478 attachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002479 attachment->type() != GL_RENDERBUFFER &&
2480 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002482 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 return false;
2484 }
2485
2486 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002487 if (!Format::EquivalentForBlit(attachment->getFormat(),
2488 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002490 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 return false;
2492 }
2493 }
2494 }
2495
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002496 if (readFramebuffer->getSamples(context) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002497 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2498 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2499 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002500 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002501 return false;
2502 }
2503 }
2504 }
2505
2506 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2507 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2508 for (size_t i = 0; i < 2; i++)
2509 {
2510 if (mask & masks[i])
2511 {
2512 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002513 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002514 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002515 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002516
2517 if (readBuffer && drawBuffer)
2518 {
2519 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2520 dstX0, dstY0, dstX1, dstY1))
2521 {
2522 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002523 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2524 "stencil blits are supported by "
2525 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002526 return false;
2527 }
2528
2529 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2530 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002531 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002532 return false;
2533 }
2534 }
2535 }
2536 }
2537
2538 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2539 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002540}
Jamie Madillc29968b2016-01-20 11:17:23 -05002541
2542bool ValidateClear(ValidationContext *context, GLbitfield mask)
2543{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002544 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002545 if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002546 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002547 context->handleError(InvalidFramebufferOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002548 return false;
2549 }
2550
2551 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002553 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002554 return false;
2555 }
2556
Geoff Lang76e65652017-03-27 14:58:02 -04002557 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2558 {
2559 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2560 GL_SIGNED_NORMALIZED};
2561
Corentin Wallez59c41592017-07-11 13:19:54 -04002562 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002563 drawBufferIdx++)
2564 {
2565 if (!ValidateWebGLFramebufferAttachmentClearType(
2566 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2567 {
2568 return false;
2569 }
2570 }
2571 }
2572
Jamie Madillc29968b2016-01-20 11:17:23 -05002573 return true;
2574}
2575
2576bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
2577{
2578 if (!context->getExtensions().drawBuffers)
2579 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002580 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002581 return false;
2582 }
2583
2584 return ValidateDrawBuffersBase(context, n, bufs);
2585}
2586
Jamie Madill73a84962016-02-12 09:27:23 -05002587bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002588 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002589 GLint level,
2590 GLint internalformat,
2591 GLsizei width,
2592 GLsizei height,
2593 GLint border,
2594 GLenum format,
2595 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002596 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002597{
Martin Radev1be913c2016-07-11 17:59:16 +03002598 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002599 {
2600 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002601 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002602 }
2603
Martin Radev1be913c2016-07-11 17:59:16 +03002604 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002605 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002606 0, 0, width, height, 1, border, format, type, -1,
2607 pixels);
2608}
2609
2610bool ValidateTexImage2DRobust(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002611 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04002612 GLint level,
2613 GLint internalformat,
2614 GLsizei width,
2615 GLsizei height,
2616 GLint border,
2617 GLenum format,
2618 GLenum type,
2619 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002620 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002621{
2622 if (!ValidateRobustEntryPoint(context, bufSize))
2623 {
2624 return false;
2625 }
2626
2627 if (context->getClientMajorVersion() < 3)
2628 {
2629 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2630 0, 0, width, height, border, format, type, bufSize,
2631 pixels);
2632 }
2633
2634 ASSERT(context->getClientMajorVersion() >= 3);
2635 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2636 0, 0, width, height, 1, border, format, type, bufSize,
2637 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002638}
2639
2640bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002641 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002642 GLint level,
2643 GLint xoffset,
2644 GLint yoffset,
2645 GLsizei width,
2646 GLsizei height,
2647 GLenum format,
2648 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002649 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002650{
2651
Martin Radev1be913c2016-07-11 17:59:16 +03002652 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002653 {
2654 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002655 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002656 }
2657
Martin Radev1be913c2016-07-11 17:59:16 +03002658 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002659 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002660 yoffset, 0, width, height, 1, 0, format, type, -1,
2661 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002662}
2663
Geoff Langc52f6f12016-10-14 10:18:00 -04002664bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002665 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002666 GLint level,
2667 GLint xoffset,
2668 GLint yoffset,
2669 GLsizei width,
2670 GLsizei height,
2671 GLenum format,
2672 GLenum type,
2673 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002674 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002675{
2676 if (!ValidateRobustEntryPoint(context, bufSize))
2677 {
2678 return false;
2679 }
2680
2681 if (context->getClientMajorVersion() < 3)
2682 {
2683 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2684 yoffset, width, height, 0, format, type, bufSize,
2685 pixels);
2686 }
2687
2688 ASSERT(context->getClientMajorVersion() >= 3);
2689 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2690 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2691 pixels);
2692}
2693
Jamie Madill73a84962016-02-12 09:27:23 -05002694bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002695 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002696 GLint level,
2697 GLenum internalformat,
2698 GLsizei width,
2699 GLsizei height,
2700 GLint border,
2701 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002702 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002703{
Martin Radev1be913c2016-07-11 17:59:16 +03002704 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002705 {
2706 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002707 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002708 {
2709 return false;
2710 }
2711 }
2712 else
2713 {
Martin Radev1be913c2016-07-11 17:59:16 +03002714 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002715 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002716 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002717 data))
2718 {
2719 return false;
2720 }
2721 }
2722
Geoff Langca271392017-04-05 12:30:00 -04002723 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002724 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002725 if (blockSizeOrErr.isError())
2726 {
2727 context->handleError(blockSizeOrErr.getError());
2728 return false;
2729 }
2730
2731 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002732 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002733 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002734 return false;
2735 }
2736
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002737 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002738 {
2739 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2740 return false;
2741 }
2742
Jamie Madill73a84962016-02-12 09:27:23 -05002743 return true;
2744}
2745
Corentin Wallezb2931602017-04-11 15:58:57 -04002746bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002747 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002748 GLint level,
2749 GLenum internalformat,
2750 GLsizei width,
2751 GLsizei height,
2752 GLint border,
2753 GLsizei imageSize,
2754 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002755 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002756{
2757 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2758 {
2759 return false;
2760 }
2761
2762 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2763 border, imageSize, data);
2764}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002765
Corentin Wallezb2931602017-04-11 15:58:57 -04002766bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002767 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002768 GLint level,
2769 GLint xoffset,
2770 GLint yoffset,
2771 GLsizei width,
2772 GLsizei height,
2773 GLenum format,
2774 GLsizei imageSize,
2775 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002776 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002777{
2778 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2779 {
2780 return false;
2781 }
2782
2783 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2784 format, imageSize, data);
2785}
2786
Jamie Madill73a84962016-02-12 09:27:23 -05002787bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002788 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002789 GLint level,
2790 GLint xoffset,
2791 GLint yoffset,
2792 GLsizei width,
2793 GLsizei height,
2794 GLenum format,
2795 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002796 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002797{
Martin Radev1be913c2016-07-11 17:59:16 +03002798 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002799 {
2800 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002801 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002802 {
2803 return false;
2804 }
2805 }
2806 else
2807 {
Martin Radev1be913c2016-07-11 17:59:16 +03002808 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002809 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002810 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002811 data))
2812 {
2813 return false;
2814 }
2815 }
2816
Geoff Langca271392017-04-05 12:30:00 -04002817 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002818 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002819 if (blockSizeOrErr.isError())
2820 {
2821 context->handleError(blockSizeOrErr.getError());
2822 return false;
2823 }
2824
2825 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002826 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002827 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002828 return false;
2829 }
2830
2831 return true;
2832}
2833
Corentin Wallez336129f2017-10-17 15:55:40 -04002834bool ValidateGetBufferPointervOES(Context *context,
2835 BufferBinding target,
2836 GLenum pname,
2837 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002838{
Geoff Lang496c02d2016-10-20 11:38:11 -07002839 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002840}
2841
Corentin Wallez336129f2017-10-17 15:55:40 -04002842bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002843{
2844 if (!context->getExtensions().mapBuffer)
2845 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002846 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002847 return false;
2848 }
2849
Corentin Walleze4477002017-12-01 14:39:58 -05002850 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002851 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002852 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002853 return false;
2854 }
2855
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002856 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002857
2858 if (buffer == nullptr)
2859 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002860 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002861 return false;
2862 }
2863
2864 if (access != GL_WRITE_ONLY_OES)
2865 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002866 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002867 return false;
2868 }
2869
2870 if (buffer->isMapped())
2871 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002872 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002873 return false;
2874 }
2875
Geoff Lang79f71042017-08-14 16:43:43 -04002876 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002877}
2878
Corentin Wallez336129f2017-10-17 15:55:40 -04002879bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002880{
2881 if (!context->getExtensions().mapBuffer)
2882 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002883 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002884 return false;
2885 }
2886
2887 return ValidateUnmapBufferBase(context, target);
2888}
2889
2890bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002891 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002892 GLintptr offset,
2893 GLsizeiptr length,
2894 GLbitfield access)
2895{
2896 if (!context->getExtensions().mapBufferRange)
2897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002898 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002899 return false;
2900 }
2901
2902 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2903}
2904
Corentin Wallez336129f2017-10-17 15:55:40 -04002905bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002906{
2907 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2908 ASSERT(buffer != nullptr);
2909
2910 // Check if this buffer is currently being used as a transform feedback output buffer
2911 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2912 if (transformFeedback != nullptr && transformFeedback->isActive())
2913 {
2914 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2915 {
2916 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2917 if (transformFeedbackBuffer.get() == buffer)
2918 {
2919 context->handleError(InvalidOperation()
2920 << "Buffer is currently bound for transform feedback.");
2921 return false;
2922 }
2923 }
2924 }
2925
2926 return true;
2927}
2928
Olli Etuaho4f667482016-03-30 15:56:35 +03002929bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002930 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002931 GLintptr offset,
2932 GLsizeiptr length)
2933{
2934 if (!context->getExtensions().mapBufferRange)
2935 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002936 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002937 return false;
2938 }
2939
2940 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2941}
2942
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002943bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002944{
2945 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002946 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002947 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002948 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002949 return false;
2950 }
2951
Geoff Langf41a7152016-09-19 15:11:17 -04002952 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2953 !context->isTextureGenerated(texture))
2954 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002955 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002956 return false;
2957 }
2958
Ian Ewell54f87462016-03-10 13:47:21 -05002959 switch (target)
2960 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002961 case TextureType::_2D:
2962 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002963 break;
2964
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002965 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002966 if (!context->getExtensions().textureRectangle)
2967 {
2968 context->handleError(InvalidEnum()
2969 << "Context does not support GL_ANGLE_texture_rectangle");
2970 return false;
2971 }
2972 break;
2973
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002974 case TextureType::_3D:
2975 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002976 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002977 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002978 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002979 return false;
2980 }
2981 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002982
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002983 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04002984 if (context->getClientVersion() < Version(3, 1))
2985 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002986 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002987 return false;
2988 }
Geoff Lang3b573612016-10-31 14:08:10 -04002989 break;
2990
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002991 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04002992 if (!context->getExtensions().eglImageExternal &&
2993 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05002994 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002995 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05002996 return false;
2997 }
2998 break;
2999 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003000 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003001 return false;
3002 }
3003
3004 return true;
3005}
3006
Geoff Langd8605522016-04-13 10:19:12 -04003007bool ValidateBindUniformLocationCHROMIUM(Context *context,
3008 GLuint program,
3009 GLint location,
3010 const GLchar *name)
3011{
3012 if (!context->getExtensions().bindUniformLocation)
3013 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003014 context->handleError(InvalidOperation()
3015 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003016 return false;
3017 }
3018
3019 Program *programObject = GetValidProgram(context, program);
3020 if (!programObject)
3021 {
3022 return false;
3023 }
3024
3025 if (location < 0)
3026 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003027 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003028 return false;
3029 }
3030
3031 const Caps &caps = context->getCaps();
3032 if (static_cast<size_t>(location) >=
3033 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3034 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003035 context->handleError(InvalidValue() << "Location must be less than "
3036 "(MAX_VERTEX_UNIFORM_VECTORS + "
3037 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003038 return false;
3039 }
3040
Geoff Langfc32e8b2017-05-31 14:16:59 -04003041 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3042 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003043 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003044 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003045 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003046 return false;
3047 }
3048
Geoff Langd8605522016-04-13 10:19:12 -04003049 if (strncmp(name, "gl_", 3) == 0)
3050 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003051 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003052 return false;
3053 }
3054
3055 return true;
3056}
3057
Jamie Madille2e406c2016-06-02 13:04:10 -04003058bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003059{
3060 if (!context->getExtensions().framebufferMixedSamples)
3061 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003062 context->handleError(InvalidOperation()
3063 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003064 return false;
3065 }
3066 switch (components)
3067 {
3068 case GL_RGB:
3069 case GL_RGBA:
3070 case GL_ALPHA:
3071 case GL_NONE:
3072 break;
3073 default:
3074 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003075 InvalidEnum()
3076 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003077 return false;
3078 }
3079
3080 return true;
3081}
3082
Sami Väisänene45e53b2016-05-25 10:36:04 +03003083// CHROMIUM_path_rendering
3084
Jamie Madill007530e2017-12-28 14:27:04 -05003085bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003086{
Jamie Madill007530e2017-12-28 14:27:04 -05003087 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003088 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003089 return false;
3090 }
Jamie Madill007530e2017-12-28 14:27:04 -05003091
Sami Väisänene45e53b2016-05-25 10:36:04 +03003092 if (matrix == nullptr)
3093 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003094 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003095 return false;
3096 }
Jamie Madill007530e2017-12-28 14:27:04 -05003097
Sami Väisänene45e53b2016-05-25 10:36:04 +03003098 return true;
3099}
3100
Jamie Madill007530e2017-12-28 14:27:04 -05003101bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003102{
Jamie Madill007530e2017-12-28 14:27:04 -05003103 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003104}
3105
Jamie Madill007530e2017-12-28 14:27:04 -05003106bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003107{
3108 if (!context->getExtensions().pathRendering)
3109 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003110 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111 return false;
3112 }
3113
3114 // range = 0 is undefined in NV_path_rendering.
3115 // we add stricter semantic check here and require a non zero positive range.
3116 if (range <= 0)
3117 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003118 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003119 return false;
3120 }
3121
3122 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3123 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003124 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003125 return false;
3126 }
3127
3128 return true;
3129}
3130
Jamie Madill007530e2017-12-28 14:27:04 -05003131bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003132{
3133 if (!context->getExtensions().pathRendering)
3134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003135 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003136 return false;
3137 }
3138
3139 // range = 0 is undefined in NV_path_rendering.
3140 // we add stricter semantic check here and require a non zero positive range.
3141 if (range <= 0)
3142 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003143 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003144 return false;
3145 }
3146
3147 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3148 checkedRange += range;
3149
3150 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3151 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003152 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003153 return false;
3154 }
3155 return true;
3156}
3157
Jamie Madill007530e2017-12-28 14:27:04 -05003158bool ValidatePathCommandsCHROMIUM(Context *context,
3159 GLuint path,
3160 GLsizei numCommands,
3161 const GLubyte *commands,
3162 GLsizei numCoords,
3163 GLenum coordType,
3164 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003165{
3166 if (!context->getExtensions().pathRendering)
3167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003168 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003169 return false;
3170 }
3171 if (!context->hasPath(path))
3172 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003173 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003174 return false;
3175 }
3176
3177 if (numCommands < 0)
3178 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003179 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003180 return false;
3181 }
3182 else if (numCommands > 0)
3183 {
3184 if (!commands)
3185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003186 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003187 return false;
3188 }
3189 }
3190
3191 if (numCoords < 0)
3192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003193 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003194 return false;
3195 }
3196 else if (numCoords > 0)
3197 {
3198 if (!coords)
3199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003200 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003201 return false;
3202 }
3203 }
3204
3205 std::uint32_t coordTypeSize = 0;
3206 switch (coordType)
3207 {
3208 case GL_BYTE:
3209 coordTypeSize = sizeof(GLbyte);
3210 break;
3211
3212 case GL_UNSIGNED_BYTE:
3213 coordTypeSize = sizeof(GLubyte);
3214 break;
3215
3216 case GL_SHORT:
3217 coordTypeSize = sizeof(GLshort);
3218 break;
3219
3220 case GL_UNSIGNED_SHORT:
3221 coordTypeSize = sizeof(GLushort);
3222 break;
3223
3224 case GL_FLOAT:
3225 coordTypeSize = sizeof(GLfloat);
3226 break;
3227
3228 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003229 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003230 return false;
3231 }
3232
3233 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3234 checkedSize += (coordTypeSize * numCoords);
3235 if (!checkedSize.IsValid())
3236 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003237 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003238 return false;
3239 }
3240
3241 // early return skips command data validation when it doesn't exist.
3242 if (!commands)
3243 return true;
3244
3245 GLsizei expectedNumCoords = 0;
3246 for (GLsizei i = 0; i < numCommands; ++i)
3247 {
3248 switch (commands[i])
3249 {
3250 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3251 break;
3252 case GL_MOVE_TO_CHROMIUM:
3253 case GL_LINE_TO_CHROMIUM:
3254 expectedNumCoords += 2;
3255 break;
3256 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3257 expectedNumCoords += 4;
3258 break;
3259 case GL_CUBIC_CURVE_TO_CHROMIUM:
3260 expectedNumCoords += 6;
3261 break;
3262 case GL_CONIC_CURVE_TO_CHROMIUM:
3263 expectedNumCoords += 5;
3264 break;
3265 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003266 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003267 return false;
3268 }
3269 }
3270 if (expectedNumCoords != numCoords)
3271 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003272 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003273 return false;
3274 }
3275
3276 return true;
3277}
3278
Jamie Madill007530e2017-12-28 14:27:04 -05003279bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280{
3281 if (!context->getExtensions().pathRendering)
3282 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003283 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003284 return false;
3285 }
3286 if (!context->hasPath(path))
3287 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003288 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003289 return false;
3290 }
3291
3292 switch (pname)
3293 {
3294 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3295 if (value < 0.0f)
3296 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003297 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003298 return false;
3299 }
3300 break;
3301 case GL_PATH_END_CAPS_CHROMIUM:
3302 switch (static_cast<GLenum>(value))
3303 {
3304 case GL_FLAT_CHROMIUM:
3305 case GL_SQUARE_CHROMIUM:
3306 case GL_ROUND_CHROMIUM:
3307 break;
3308 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003309 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003310 return false;
3311 }
3312 break;
3313 case GL_PATH_JOIN_STYLE_CHROMIUM:
3314 switch (static_cast<GLenum>(value))
3315 {
3316 case GL_MITER_REVERT_CHROMIUM:
3317 case GL_BEVEL_CHROMIUM:
3318 case GL_ROUND_CHROMIUM:
3319 break;
3320 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003321 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003322 return false;
3323 }
Nico Weber41b072b2018-02-09 10:01:32 -05003324 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003325 case GL_PATH_MITER_LIMIT_CHROMIUM:
3326 if (value < 0.0f)
3327 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003328 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003329 return false;
3330 }
3331 break;
3332
3333 case GL_PATH_STROKE_BOUND_CHROMIUM:
3334 // no errors, only clamping.
3335 break;
3336
3337 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003338 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003339 return false;
3340 }
3341 return true;
3342}
3343
Jamie Madill007530e2017-12-28 14:27:04 -05003344bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3345{
3346 // TODO(jmadill): Use proper clamping cast.
3347 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3348}
3349
3350bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003351{
3352 if (!context->getExtensions().pathRendering)
3353 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003354 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003355 return false;
3356 }
3357
3358 if (!context->hasPath(path))
3359 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003360 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003361 return false;
3362 }
3363 if (!value)
3364 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003365 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003366 return false;
3367 }
3368
3369 switch (pname)
3370 {
3371 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3372 case GL_PATH_END_CAPS_CHROMIUM:
3373 case GL_PATH_JOIN_STYLE_CHROMIUM:
3374 case GL_PATH_MITER_LIMIT_CHROMIUM:
3375 case GL_PATH_STROKE_BOUND_CHROMIUM:
3376 break;
3377
3378 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003379 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003380 return false;
3381 }
3382
3383 return true;
3384}
3385
Jamie Madill007530e2017-12-28 14:27:04 -05003386bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3387{
3388 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3389 reinterpret_cast<GLfloat *>(value));
3390}
3391
3392bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003393{
3394 if (!context->getExtensions().pathRendering)
3395 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003396 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003397 return false;
3398 }
3399
3400 switch (func)
3401 {
3402 case GL_NEVER:
3403 case GL_ALWAYS:
3404 case GL_LESS:
3405 case GL_LEQUAL:
3406 case GL_EQUAL:
3407 case GL_GEQUAL:
3408 case GL_GREATER:
3409 case GL_NOTEQUAL:
3410 break;
3411 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003412 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003413 return false;
3414 }
3415
3416 return true;
3417}
3418
3419// Note that the spec specifies that for the path drawing commands
3420// if the path object is not an existing path object the command
3421// does nothing and no error is generated.
3422// However if the path object exists but has not been specified any
3423// commands then an error is generated.
3424
Jamie Madill007530e2017-12-28 14:27:04 -05003425bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003426{
3427 if (!context->getExtensions().pathRendering)
3428 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003429 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003430 return false;
3431 }
3432 if (context->hasPath(path) && !context->hasPathData(path))
3433 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003434 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003435 return false;
3436 }
3437
3438 switch (fillMode)
3439 {
3440 case GL_COUNT_UP_CHROMIUM:
3441 case GL_COUNT_DOWN_CHROMIUM:
3442 break;
3443 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003444 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003445 return false;
3446 }
3447
3448 if (!isPow2(mask + 1))
3449 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003450 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003451 return false;
3452 }
3453
3454 return true;
3455}
3456
Jamie Madill007530e2017-12-28 14:27:04 -05003457bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458{
3459 if (!context->getExtensions().pathRendering)
3460 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003461 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003462 return false;
3463 }
3464 if (context->hasPath(path) && !context->hasPathData(path))
3465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003466 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003467 return false;
3468 }
3469
3470 return true;
3471}
3472
Jamie Madill007530e2017-12-28 14:27:04 -05003473bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474{
3475 if (!context->getExtensions().pathRendering)
3476 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003477 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003478 return false;
3479 }
3480 if (context->hasPath(path) && !context->hasPathData(path))
3481 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003482 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003483 return false;
3484 }
3485
3486 switch (coverMode)
3487 {
3488 case GL_CONVEX_HULL_CHROMIUM:
3489 case GL_BOUNDING_BOX_CHROMIUM:
3490 break;
3491 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003492 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003493 return false;
3494 }
3495 return true;
3496}
3497
Jamie Madill007530e2017-12-28 14:27:04 -05003498bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3499 GLuint path,
3500 GLenum fillMode,
3501 GLuint mask,
3502 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003503{
Jamie Madill007530e2017-12-28 14:27:04 -05003504 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3505 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003506}
3507
Jamie Madill007530e2017-12-28 14:27:04 -05003508bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3509 GLuint path,
3510 GLint reference,
3511 GLuint mask,
3512 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003513{
Jamie Madill007530e2017-12-28 14:27:04 -05003514 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3515 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003516}
3517
Jamie Madill007530e2017-12-28 14:27:04 -05003518bool ValidateIsPathCHROMIUM(Context *context)
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 }
3525 return true;
3526}
3527
Jamie Madill007530e2017-12-28 14:27:04 -05003528bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3529 GLsizei numPaths,
3530 GLenum pathNameType,
3531 const void *paths,
3532 GLuint pathBase,
3533 GLenum coverMode,
3534 GLenum transformType,
3535 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003536{
3537 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3538 transformType, transformValues))
3539 return false;
3540
3541 switch (coverMode)
3542 {
3543 case GL_CONVEX_HULL_CHROMIUM:
3544 case GL_BOUNDING_BOX_CHROMIUM:
3545 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3546 break;
3547 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003548 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003549 return false;
3550 }
3551
3552 return true;
3553}
3554
Jamie Madill007530e2017-12-28 14:27:04 -05003555bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3556 GLsizei numPaths,
3557 GLenum pathNameType,
3558 const void *paths,
3559 GLuint pathBase,
3560 GLenum coverMode,
3561 GLenum transformType,
3562 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003563{
3564 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3565 transformType, transformValues))
3566 return false;
3567
3568 switch (coverMode)
3569 {
3570 case GL_CONVEX_HULL_CHROMIUM:
3571 case GL_BOUNDING_BOX_CHROMIUM:
3572 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3573 break;
3574 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003575 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003576 return false;
3577 }
3578
3579 return true;
3580}
3581
Jamie Madill007530e2017-12-28 14:27:04 -05003582bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3583 GLsizei numPaths,
3584 GLenum pathNameType,
3585 const void *paths,
3586 GLuint pathBase,
3587 GLenum fillMode,
3588 GLuint mask,
3589 GLenum transformType,
3590 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003591{
3592
3593 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3594 transformType, transformValues))
3595 return false;
3596
3597 switch (fillMode)
3598 {
3599 case GL_COUNT_UP_CHROMIUM:
3600 case GL_COUNT_DOWN_CHROMIUM:
3601 break;
3602 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003603 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003604 return false;
3605 }
3606 if (!isPow2(mask + 1))
3607 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003608 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003609 return false;
3610 }
3611 return true;
3612}
3613
Jamie Madill007530e2017-12-28 14:27:04 -05003614bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3615 GLsizei numPaths,
3616 GLenum pathNameType,
3617 const void *paths,
3618 GLuint pathBase,
3619 GLint reference,
3620 GLuint mask,
3621 GLenum transformType,
3622 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003623{
3624 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3625 transformType, transformValues))
3626 return false;
3627
3628 // no more validation here.
3629
3630 return true;
3631}
3632
Jamie Madill007530e2017-12-28 14:27:04 -05003633bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3634 GLsizei numPaths,
3635 GLenum pathNameType,
3636 const void *paths,
3637 GLuint pathBase,
3638 GLenum fillMode,
3639 GLuint mask,
3640 GLenum coverMode,
3641 GLenum transformType,
3642 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003643{
3644 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3645 transformType, transformValues))
3646 return false;
3647
3648 switch (coverMode)
3649 {
3650 case GL_CONVEX_HULL_CHROMIUM:
3651 case GL_BOUNDING_BOX_CHROMIUM:
3652 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3653 break;
3654 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003655 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003656 return false;
3657 }
3658
3659 switch (fillMode)
3660 {
3661 case GL_COUNT_UP_CHROMIUM:
3662 case GL_COUNT_DOWN_CHROMIUM:
3663 break;
3664 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003665 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003666 return false;
3667 }
3668 if (!isPow2(mask + 1))
3669 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003670 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003671 return false;
3672 }
3673
3674 return true;
3675}
3676
Jamie Madill007530e2017-12-28 14:27:04 -05003677bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3678 GLsizei numPaths,
3679 GLenum pathNameType,
3680 const void *paths,
3681 GLuint pathBase,
3682 GLint reference,
3683 GLuint mask,
3684 GLenum coverMode,
3685 GLenum transformType,
3686 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003687{
3688 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3689 transformType, transformValues))
3690 return false;
3691
3692 switch (coverMode)
3693 {
3694 case GL_CONVEX_HULL_CHROMIUM:
3695 case GL_BOUNDING_BOX_CHROMIUM:
3696 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3697 break;
3698 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003699 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003700 return false;
3701 }
3702
3703 return true;
3704}
3705
Jamie Madill007530e2017-12-28 14:27:04 -05003706bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3707 GLuint program,
3708 GLint location,
3709 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003710{
3711 if (!context->getExtensions().pathRendering)
3712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003713 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003714 return false;
3715 }
3716
3717 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3718 if (location >= MaxLocation)
3719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003720 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003721 return false;
3722 }
3723
3724 const auto *programObject = context->getProgram(program);
3725 if (!programObject)
3726 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003727 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003728 return false;
3729 }
3730
3731 if (!name)
3732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003733 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003734 return false;
3735 }
3736
3737 if (angle::BeginsWith(name, "gl_"))
3738 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003739 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003740 return false;
3741 }
3742
3743 return true;
3744}
3745
Jamie Madill007530e2017-12-28 14:27:04 -05003746bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3747 GLuint program,
3748 GLint location,
3749 GLenum genMode,
3750 GLint components,
3751 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003752{
3753 if (!context->getExtensions().pathRendering)
3754 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003755 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003756 return false;
3757 }
3758
3759 const auto *programObject = context->getProgram(program);
3760 if (!programObject || programObject->isFlaggedForDeletion())
3761 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003762 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003763 return false;
3764 }
3765
3766 if (!programObject->isLinked())
3767 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003768 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003769 return false;
3770 }
3771
3772 switch (genMode)
3773 {
3774 case GL_NONE:
3775 if (components != 0)
3776 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003777 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003778 return false;
3779 }
3780 break;
3781
3782 case GL_OBJECT_LINEAR_CHROMIUM:
3783 case GL_EYE_LINEAR_CHROMIUM:
3784 case GL_CONSTANT_CHROMIUM:
3785 if (components < 1 || components > 4)
3786 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003787 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003788 return false;
3789 }
3790 if (!coeffs)
3791 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003792 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003793 return false;
3794 }
3795 break;
3796
3797 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003798 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003799 return false;
3800 }
3801
3802 // If the location is -1 then the command is silently ignored
3803 // and no further validation is needed.
3804 if (location == -1)
3805 return true;
3806
Jamie Madillbd044ed2017-06-05 12:59:21 -04003807 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003808
3809 if (!binding.valid)
3810 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003811 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003812 return false;
3813 }
3814
3815 if (binding.type != GL_NONE)
3816 {
3817 GLint expectedComponents = 0;
3818 switch (binding.type)
3819 {
3820 case GL_FLOAT:
3821 expectedComponents = 1;
3822 break;
3823 case GL_FLOAT_VEC2:
3824 expectedComponents = 2;
3825 break;
3826 case GL_FLOAT_VEC3:
3827 expectedComponents = 3;
3828 break;
3829 case GL_FLOAT_VEC4:
3830 expectedComponents = 4;
3831 break;
3832 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003833 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003834 InvalidOperation()
3835 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003836 return false;
3837 }
3838 if (expectedComponents != components && genMode != GL_NONE)
3839 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003840 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003841 return false;
3842 }
3843 }
3844 return true;
3845}
3846
Geoff Lang97073d12016-04-20 10:42:34 -07003847bool ValidateCopyTextureCHROMIUM(Context *context,
3848 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003849 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003850 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003851 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003852 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003853 GLint internalFormat,
3854 GLenum destType,
3855 GLboolean unpackFlipY,
3856 GLboolean unpackPremultiplyAlpha,
3857 GLboolean unpackUnmultiplyAlpha)
3858{
3859 if (!context->getExtensions().copyTexture)
3860 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003861 context->handleError(InvalidOperation()
3862 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003863 return false;
3864 }
3865
Geoff Lang4f0e0032017-05-01 16:04:35 -04003866 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003867 if (source == nullptr)
3868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003869 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003870 return false;
3871 }
3872
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003873 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003874 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003875 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003876 return false;
3877 }
3878
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003879 TextureType sourceType = source->getType();
3880 ASSERT(sourceType != TextureType::CubeMap);
3881 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003882
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003883 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003884 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003885 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003886 return false;
3887 }
3888
Geoff Lang4f0e0032017-05-01 16:04:35 -04003889 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3890 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3891 if (sourceWidth == 0 || sourceHeight == 0)
3892 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003893 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003894 return false;
3895 }
3896
3897 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3898 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003899 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003900 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003901 return false;
3902 }
3903
Geoff Lang63458a32017-10-30 15:16:53 -04003904 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3905 {
3906 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3907 return false;
3908 }
3909
Geoff Lang4f0e0032017-05-01 16:04:35 -04003910 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003911 if (dest == nullptr)
3912 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003913 context->handleError(InvalidValue()
3914 << "Destination 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 (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003919 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003920 context->handleError(InvalidValue() << "Destination 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 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones22026802018-03-05 09:37:32 -08003925 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003926 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003927 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003928 return false;
3929 }
3930
Geoff Lang97073d12016-04-20 10:42:34 -07003931 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3932 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003933 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003934 return false;
3935 }
3936
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003937 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003938 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003939 context->handleError(
3940 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003941 return false;
3942 }
3943
Geoff Lang97073d12016-04-20 10:42:34 -07003944 if (dest->getImmutableFormat())
3945 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003946 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003947 return false;
3948 }
3949
3950 return true;
3951}
3952
3953bool ValidateCopySubTextureCHROMIUM(Context *context,
3954 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003955 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003956 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003957 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003958 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003959 GLint xoffset,
3960 GLint yoffset,
3961 GLint x,
3962 GLint y,
3963 GLsizei width,
3964 GLsizei height,
3965 GLboolean unpackFlipY,
3966 GLboolean unpackPremultiplyAlpha,
3967 GLboolean unpackUnmultiplyAlpha)
3968{
3969 if (!context->getExtensions().copyTexture)
3970 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003971 context->handleError(InvalidOperation()
3972 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003973 return false;
3974 }
3975
Geoff Lang4f0e0032017-05-01 16:04:35 -04003976 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003977 if (source == nullptr)
3978 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003979 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003980 return false;
3981 }
3982
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003983 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003985 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003986 return false;
3987 }
3988
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003989 TextureType sourceType = source->getType();
3990 ASSERT(sourceType != TextureType::CubeMap);
3991 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003992
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003993 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003994 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003995 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003996 return false;
3997 }
3998
3999 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4000 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004001 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004002 context->handleError(InvalidValue()
4003 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004004 return false;
4005 }
4006
4007 if (x < 0 || y < 0)
4008 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004009 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004010 return false;
4011 }
4012
4013 if (width < 0 || height < 0)
4014 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004015 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004016 return false;
4017 }
4018
Geoff Lang4f0e0032017-05-01 16:04:35 -04004019 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4020 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004021 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004022 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004023 return false;
4024 }
4025
Geoff Lang4f0e0032017-05-01 16:04:35 -04004026 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4027 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004028 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004029 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004030 return false;
4031 }
4032
Geoff Lang63458a32017-10-30 15:16:53 -04004033 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4034 {
4035 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4036 return false;
4037 }
4038
Geoff Lang4f0e0032017-05-01 16:04:35 -04004039 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004040 if (dest == nullptr)
4041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004042 context->handleError(InvalidValue()
4043 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004044 return false;
4045 }
4046
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004047 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004049 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004050 return false;
4051 }
4052
Brandon Jones22026802018-03-05 09:37:32 -08004053 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4054 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004055 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004056 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004057 return false;
4058 }
4059
Geoff Lang4f0e0032017-05-01 16:04:35 -04004060 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4061 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004062 context
4063 ->handleError(InvalidOperation()
4064 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004065 return false;
4066 }
4067
4068 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4069 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004070 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004071 context->handleError(InvalidOperation()
4072 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004073 return false;
4074 }
4075
4076 if (xoffset < 0 || yoffset < 0)
4077 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004078 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004079 return false;
4080 }
4081
Geoff Lang4f0e0032017-05-01 16:04:35 -04004082 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4083 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004084 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004085 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004086 return false;
4087 }
4088
4089 return true;
4090}
4091
Geoff Lang47110bf2016-04-20 11:13:22 -07004092bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4093{
4094 if (!context->getExtensions().copyCompressedTexture)
4095 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004096 context->handleError(InvalidOperation()
4097 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004098 return false;
4099 }
4100
4101 const gl::Texture *source = context->getTexture(sourceId);
4102 if (source == nullptr)
4103 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004104 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004105 return false;
4106 }
4107
Corentin Wallez99d492c2018-02-27 15:17:10 -05004108 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004109 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004110 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004111 return false;
4112 }
4113
Corentin Wallez99d492c2018-02-27 15:17:10 -05004114 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4115 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004117 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004118 return false;
4119 }
4120
Corentin Wallez99d492c2018-02-27 15:17:10 -05004121 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004122 if (!sourceFormat.info->compressed)
4123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004124 context->handleError(InvalidOperation()
4125 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004126 return false;
4127 }
4128
4129 const gl::Texture *dest = context->getTexture(destId);
4130 if (dest == nullptr)
4131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004132 context->handleError(InvalidValue()
4133 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004134 return false;
4135 }
4136
Corentin Wallez99d492c2018-02-27 15:17:10 -05004137 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004139 context->handleError(InvalidValue()
4140 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004141 return false;
4142 }
4143
4144 if (dest->getImmutableFormat())
4145 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004146 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004147 return false;
4148 }
4149
4150 return true;
4151}
4152
Martin Radev4c4c8e72016-08-04 12:25:34 +03004153bool ValidateCreateShader(Context *context, GLenum type)
4154{
4155 switch (type)
4156 {
4157 case GL_VERTEX_SHADER:
4158 case GL_FRAGMENT_SHADER:
4159 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004160
Martin Radev4c4c8e72016-08-04 12:25:34 +03004161 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004162 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004163 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004164 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004165 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004166 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004167 break;
4168
Jiawei Shao89be29a2017-11-06 14:36:45 +08004169 case GL_GEOMETRY_SHADER_EXT:
4170 if (!context->getExtensions().geometryShader)
4171 {
4172 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4173 return false;
4174 }
4175 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004176 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004177 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004178 return false;
4179 }
Jamie Madill29639852016-09-02 15:00:09 -04004180
4181 return true;
4182}
4183
4184bool ValidateBufferData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004185 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004186 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004187 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004188 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004189{
4190 if (size < 0)
4191 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004192 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004193 return false;
4194 }
4195
4196 switch (usage)
4197 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004198 case BufferUsage::StreamDraw:
4199 case BufferUsage::StaticDraw:
4200 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004201 break;
4202
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004203 case BufferUsage::StreamRead:
4204 case BufferUsage::StaticRead:
4205 case BufferUsage::DynamicRead:
4206 case BufferUsage::StreamCopy:
4207 case BufferUsage::StaticCopy:
4208 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004209 if (context->getClientMajorVersion() < 3)
4210 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004211 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004212 return false;
4213 }
4214 break;
4215
4216 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004217 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004218 return false;
4219 }
4220
Corentin Walleze4477002017-12-01 14:39:58 -05004221 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004222 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004223 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004224 return false;
4225 }
4226
4227 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4228
4229 if (!buffer)
4230 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004231 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004232 return false;
4233 }
4234
4235 return true;
4236}
4237
4238bool ValidateBufferSubData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004239 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004240 GLintptr offset,
4241 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004242 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004243{
Brandon Jones6cad5662017-06-14 13:25:13 -07004244 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004246 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4247 return false;
4248 }
4249
4250 if (offset < 0)
4251 {
4252 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004253 return false;
4254 }
4255
Corentin Walleze4477002017-12-01 14:39:58 -05004256 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004257 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004258 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004259 return false;
4260 }
4261
4262 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4263
4264 if (!buffer)
4265 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004266 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004267 return false;
4268 }
4269
4270 if (buffer->isMapped())
4271 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004272 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004273 return false;
4274 }
4275
4276 // Check for possible overflow of size + offset
4277 angle::CheckedNumeric<size_t> checkedSize(size);
4278 checkedSize += offset;
4279 if (!checkedSize.IsValid())
4280 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004281 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004282 return false;
4283 }
4284
4285 if (size + offset > buffer->getSize())
4286 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004287 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004288 return false;
4289 }
4290
Martin Radev4c4c8e72016-08-04 12:25:34 +03004291 return true;
4292}
4293
Geoff Lang111a99e2017-10-17 10:58:41 -04004294bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004295{
Geoff Langc339c4e2016-11-29 10:37:36 -05004296 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004297 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004298 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004299 return false;
4300 }
4301
Geoff Lang111a99e2017-10-17 10:58:41 -04004302 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004303 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004304 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004305 return false;
4306 }
4307
4308 return true;
4309}
4310
Jamie Madillef300b12016-10-07 15:12:09 -04004311bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4312{
4313 if (texture < GL_TEXTURE0 ||
4314 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4315 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004316 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004317 return false;
4318 }
4319
4320 return true;
4321}
4322
4323bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4324{
4325 Program *programObject = GetValidProgram(context, program);
4326 if (!programObject)
4327 {
4328 return false;
4329 }
4330
4331 Shader *shaderObject = GetValidShader(context, shader);
4332 if (!shaderObject)
4333 {
4334 return false;
4335 }
4336
4337 switch (shaderObject->getType())
4338 {
4339 case GL_VERTEX_SHADER:
4340 {
4341 if (programObject->getAttachedVertexShader())
4342 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004343 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004344 return false;
4345 }
4346 break;
4347 }
4348 case GL_FRAGMENT_SHADER:
4349 {
4350 if (programObject->getAttachedFragmentShader())
4351 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004352 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004353 return false;
4354 }
4355 break;
4356 }
4357 case GL_COMPUTE_SHADER:
4358 {
4359 if (programObject->getAttachedComputeShader())
4360 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004361 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004362 return false;
4363 }
4364 break;
4365 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004366 case GL_GEOMETRY_SHADER_EXT:
4367 {
4368 if (programObject->getAttachedGeometryShader())
4369 {
4370 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4371 return false;
4372 }
4373 break;
4374 }
Jamie Madillef300b12016-10-07 15:12:09 -04004375 default:
4376 UNREACHABLE();
4377 break;
4378 }
4379
4380 return true;
4381}
4382
Jamie Madill01a80ee2016-11-07 12:06:18 -05004383bool ValidateBindAttribLocation(ValidationContext *context,
4384 GLuint program,
4385 GLuint index,
4386 const GLchar *name)
4387{
4388 if (index >= MAX_VERTEX_ATTRIBS)
4389 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004390 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004391 return false;
4392 }
4393
4394 if (strncmp(name, "gl_", 3) == 0)
4395 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004396 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004397 return false;
4398 }
4399
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004400 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004401 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004402 const size_t length = strlen(name);
4403
4404 if (!IsValidESSLString(name, length))
4405 {
4406 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4407 // for shader-related entry points
4408 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4409 return false;
4410 }
4411
4412 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4413 {
4414 return false;
4415 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004416 }
4417
Jamie Madill01a80ee2016-11-07 12:06:18 -05004418 return GetValidProgram(context, program) != nullptr;
4419}
4420
Corentin Wallez336129f2017-10-17 15:55:40 -04004421bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004422{
Corentin Walleze4477002017-12-01 14:39:58 -05004423 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004424 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004425 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004426 return false;
4427 }
4428
4429 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4430 !context->isBufferGenerated(buffer))
4431 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004432 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004433 return false;
4434 }
4435
4436 return true;
4437}
4438
4439bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4440{
Geoff Lange8afa902017-09-27 15:00:43 -04004441 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004442 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004443 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444 return false;
4445 }
4446
4447 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4448 !context->isFramebufferGenerated(framebuffer))
4449 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004450 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004451 return false;
4452 }
4453
4454 return true;
4455}
4456
4457bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4458{
4459 if (target != GL_RENDERBUFFER)
4460 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004461 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004462 return false;
4463 }
4464
4465 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4466 !context->isRenderbufferGenerated(renderbuffer))
4467 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004468 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004469 return false;
4470 }
4471
4472 return true;
4473}
4474
Geoff Lang50cac572017-09-26 17:37:43 -04004475static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004476{
4477 switch (mode)
4478 {
4479 case GL_FUNC_ADD:
4480 case GL_FUNC_SUBTRACT:
4481 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004482 return true;
4483
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004484 case GL_MIN:
4485 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004486 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004487
4488 default:
4489 return false;
4490 }
4491}
4492
Jamie Madillc1d770e2017-04-13 17:31:24 -04004493bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004494 GLfloat red,
4495 GLfloat green,
4496 GLfloat blue,
4497 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004498{
4499 return true;
4500}
4501
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004502bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4503{
Geoff Lang50cac572017-09-26 17:37:43 -04004504 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004505 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004506 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004507 return false;
4508 }
4509
4510 return true;
4511}
4512
4513bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4514{
Geoff Lang50cac572017-09-26 17:37:43 -04004515 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004516 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004517 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004518 return false;
4519 }
4520
Geoff Lang50cac572017-09-26 17:37:43 -04004521 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004522 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004523 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004524 return false;
4525 }
4526
4527 return true;
4528}
4529
4530bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4531{
4532 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4533}
4534
4535static bool ValidSrcBlendFunc(GLenum srcBlend)
4536{
4537 switch (srcBlend)
4538 {
4539 case GL_ZERO:
4540 case GL_ONE:
4541 case GL_SRC_COLOR:
4542 case GL_ONE_MINUS_SRC_COLOR:
4543 case GL_DST_COLOR:
4544 case GL_ONE_MINUS_DST_COLOR:
4545 case GL_SRC_ALPHA:
4546 case GL_ONE_MINUS_SRC_ALPHA:
4547 case GL_DST_ALPHA:
4548 case GL_ONE_MINUS_DST_ALPHA:
4549 case GL_CONSTANT_COLOR:
4550 case GL_ONE_MINUS_CONSTANT_COLOR:
4551 case GL_CONSTANT_ALPHA:
4552 case GL_ONE_MINUS_CONSTANT_ALPHA:
4553 case GL_SRC_ALPHA_SATURATE:
4554 return true;
4555
4556 default:
4557 return false;
4558 }
4559}
4560
4561static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4562{
4563 switch (dstBlend)
4564 {
4565 case GL_ZERO:
4566 case GL_ONE:
4567 case GL_SRC_COLOR:
4568 case GL_ONE_MINUS_SRC_COLOR:
4569 case GL_DST_COLOR:
4570 case GL_ONE_MINUS_DST_COLOR:
4571 case GL_SRC_ALPHA:
4572 case GL_ONE_MINUS_SRC_ALPHA:
4573 case GL_DST_ALPHA:
4574 case GL_ONE_MINUS_DST_ALPHA:
4575 case GL_CONSTANT_COLOR:
4576 case GL_ONE_MINUS_CONSTANT_COLOR:
4577 case GL_CONSTANT_ALPHA:
4578 case GL_ONE_MINUS_CONSTANT_ALPHA:
4579 return true;
4580
4581 case GL_SRC_ALPHA_SATURATE:
4582 return (contextMajorVersion >= 3);
4583
4584 default:
4585 return false;
4586 }
4587}
4588
4589bool ValidateBlendFuncSeparate(ValidationContext *context,
4590 GLenum srcRGB,
4591 GLenum dstRGB,
4592 GLenum srcAlpha,
4593 GLenum dstAlpha)
4594{
4595 if (!ValidSrcBlendFunc(srcRGB))
4596 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004597 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004598 return false;
4599 }
4600
4601 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4602 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004603 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004604 return false;
4605 }
4606
4607 if (!ValidSrcBlendFunc(srcAlpha))
4608 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004609 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004610 return false;
4611 }
4612
4613 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4614 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004615 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004616 return false;
4617 }
4618
Frank Henigman146e8a12017-03-02 23:22:37 -05004619 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4620 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004621 {
4622 bool constantColorUsed =
4623 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4624 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4625
4626 bool constantAlphaUsed =
4627 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4628 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4629
4630 if (constantColorUsed && constantAlphaUsed)
4631 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004632 const char *msg;
4633 if (context->getExtensions().webglCompatibility)
4634 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004635 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004636 }
4637 else
4638 {
4639 msg =
4640 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4641 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4642 "implementation.";
4643 ERR() << msg;
4644 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004645 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004646 return false;
4647 }
4648 }
4649
4650 return true;
4651}
4652
Geoff Langc339c4e2016-11-29 10:37:36 -05004653bool ValidateGetString(Context *context, GLenum name)
4654{
4655 switch (name)
4656 {
4657 case GL_VENDOR:
4658 case GL_RENDERER:
4659 case GL_VERSION:
4660 case GL_SHADING_LANGUAGE_VERSION:
4661 case GL_EXTENSIONS:
4662 break;
4663
4664 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4665 if (!context->getExtensions().requestExtension)
4666 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004667 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004668 return false;
4669 }
4670 break;
4671
4672 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004673 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004674 return false;
4675 }
4676
4677 return true;
4678}
4679
Geoff Lang47c48082016-12-07 15:38:13 -05004680bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4681{
4682 if (width <= 0.0f || isNaN(width))
4683 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004684 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004685 return false;
4686 }
4687
4688 return true;
4689}
4690
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004691bool ValidateVertexAttribPointer(ValidationContext *context,
4692 GLuint index,
4693 GLint size,
4694 GLenum type,
4695 GLboolean normalized,
4696 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004697 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004698{
Shao80957d92017-02-20 21:25:59 +08004699 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004700 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004701 return false;
4702 }
4703
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004704 if (stride < 0)
4705 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004706 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004707 return false;
4708 }
4709
Shao80957d92017-02-20 21:25:59 +08004710 const Caps &caps = context->getCaps();
4711 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004712 {
Shao80957d92017-02-20 21:25:59 +08004713 if (stride > caps.maxVertexAttribStride)
4714 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004715 context->handleError(InvalidValue()
4716 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004717 return false;
4718 }
4719
4720 if (index >= caps.maxVertexAttribBindings)
4721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004722 context->handleError(InvalidValue()
4723 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004724 return false;
4725 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004726 }
4727
4728 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4729 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4730 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4731 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004732 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4733 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004734 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4735 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004736 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004737 context
4738 ->handleError(InvalidOperation()
4739 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004740 return false;
4741 }
4742
4743 if (context->getExtensions().webglCompatibility)
4744 {
4745 // WebGL 1.0 [Section 6.14] Fixed point support
4746 // The WebGL API does not support the GL_FIXED data type.
4747 if (type == GL_FIXED)
4748 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004749 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004750 return false;
4751 }
4752
Geoff Lang2d62ab72017-03-23 16:54:40 -04004753 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004754 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004755 return false;
4756 }
4757 }
4758
4759 return true;
4760}
4761
Jamie Madill876429b2017-04-20 15:46:24 -04004762bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004763{
4764 if (context->getExtensions().webglCompatibility && zNear > zFar)
4765 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004766 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004767 return false;
4768 }
4769
4770 return true;
4771}
4772
Jamie Madille8fb6402017-02-14 17:56:40 -05004773bool ValidateRenderbufferStorage(ValidationContext *context,
4774 GLenum target,
4775 GLenum internalformat,
4776 GLsizei width,
4777 GLsizei height)
4778{
4779 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4780 height);
4781}
4782
4783bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4784 GLenum target,
4785 GLsizei samples,
4786 GLenum internalformat,
4787 GLsizei width,
4788 GLsizei height)
4789{
4790 if (!context->getExtensions().framebufferMultisample)
4791 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004792 context->handleError(InvalidOperation()
4793 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004794 return false;
4795 }
4796
4797 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4798 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4799 // generated.
4800 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4801 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004802 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004803 return false;
4804 }
4805
4806 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4807 // the specified storage. This is different than ES 3.0 in which a sample number higher
4808 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4809 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4810 if (context->getClientMajorVersion() >= 3)
4811 {
4812 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4813 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4814 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004815 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004816 return false;
4817 }
4818 }
4819
4820 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4821 width, height);
4822}
4823
Jamie Madillc1d770e2017-04-13 17:31:24 -04004824bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4825{
Geoff Lange8afa902017-09-27 15:00:43 -04004826 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004827 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004828 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004829 return false;
4830 }
4831
4832 return true;
4833}
4834
4835bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004836 GLfloat red,
4837 GLfloat green,
4838 GLfloat blue,
4839 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004840{
4841 return true;
4842}
4843
Jamie Madill876429b2017-04-20 15:46:24 -04004844bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004845{
4846 return true;
4847}
4848
4849bool ValidateClearStencil(ValidationContext *context, GLint s)
4850{
4851 return true;
4852}
4853
4854bool ValidateColorMask(ValidationContext *context,
4855 GLboolean red,
4856 GLboolean green,
4857 GLboolean blue,
4858 GLboolean alpha)
4859{
4860 return true;
4861}
4862
4863bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4864{
4865 return true;
4866}
4867
4868bool ValidateCreateProgram(ValidationContext *context)
4869{
4870 return true;
4871}
4872
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004873bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004874{
4875 switch (mode)
4876 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004877 case CullFaceMode::Front:
4878 case CullFaceMode::Back:
4879 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004880 break;
4881
4882 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004883 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004884 return false;
4885 }
4886
4887 return true;
4888}
4889
4890bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4891{
4892 if (program == 0)
4893 {
4894 return false;
4895 }
4896
4897 if (!context->getProgram(program))
4898 {
4899 if (context->getShader(program))
4900 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004901 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004902 return false;
4903 }
4904 else
4905 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004906 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004907 return false;
4908 }
4909 }
4910
4911 return true;
4912}
4913
4914bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4915{
4916 if (shader == 0)
4917 {
4918 return false;
4919 }
4920
4921 if (!context->getShader(shader))
4922 {
4923 if (context->getProgram(shader))
4924 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004925 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004926 return false;
4927 }
4928 else
4929 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004930 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004931 return false;
4932 }
4933 }
4934
4935 return true;
4936}
4937
4938bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4939{
4940 switch (func)
4941 {
4942 case GL_NEVER:
4943 case GL_ALWAYS:
4944 case GL_LESS:
4945 case GL_LEQUAL:
4946 case GL_EQUAL:
4947 case GL_GREATER:
4948 case GL_GEQUAL:
4949 case GL_NOTEQUAL:
4950 break;
4951
4952 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004953 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004954 return false;
4955 }
4956
4957 return true;
4958}
4959
4960bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4961{
4962 return true;
4963}
4964
4965bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4966{
4967 Program *programObject = GetValidProgram(context, program);
4968 if (!programObject)
4969 {
4970 return false;
4971 }
4972
4973 Shader *shaderObject = GetValidShader(context, shader);
4974 if (!shaderObject)
4975 {
4976 return false;
4977 }
4978
4979 const Shader *attachedShader = nullptr;
4980
4981 switch (shaderObject->getType())
4982 {
4983 case GL_VERTEX_SHADER:
4984 {
4985 attachedShader = programObject->getAttachedVertexShader();
4986 break;
4987 }
4988 case GL_FRAGMENT_SHADER:
4989 {
4990 attachedShader = programObject->getAttachedFragmentShader();
4991 break;
4992 }
4993 case GL_COMPUTE_SHADER:
4994 {
4995 attachedShader = programObject->getAttachedComputeShader();
4996 break;
4997 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004998 case GL_GEOMETRY_SHADER_EXT:
4999 {
5000 attachedShader = programObject->getAttachedGeometryShader();
5001 break;
5002 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04005003 default:
5004 UNREACHABLE();
5005 return false;
5006 }
5007
5008 if (attachedShader != shaderObject)
5009 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005010 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005011 return false;
5012 }
5013
5014 return true;
5015}
5016
5017bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
5018{
5019 if (index >= MAX_VERTEX_ATTRIBS)
5020 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005021 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005022 return false;
5023 }
5024
5025 return true;
5026}
5027
5028bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
5029{
5030 if (index >= MAX_VERTEX_ATTRIBS)
5031 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005032 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005033 return false;
5034 }
5035
5036 return true;
5037}
5038
5039bool ValidateFinish(ValidationContext *context)
5040{
5041 return true;
5042}
5043
5044bool ValidateFlush(ValidationContext *context)
5045{
5046 return true;
5047}
5048
5049bool ValidateFrontFace(ValidationContext *context, GLenum mode)
5050{
5051 switch (mode)
5052 {
5053 case GL_CW:
5054 case GL_CCW:
5055 break;
5056 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005057 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005058 return false;
5059 }
5060
5061 return true;
5062}
5063
5064bool ValidateGetActiveAttrib(ValidationContext *context,
5065 GLuint program,
5066 GLuint index,
5067 GLsizei bufsize,
5068 GLsizei *length,
5069 GLint *size,
5070 GLenum *type,
5071 GLchar *name)
5072{
5073 if (bufsize < 0)
5074 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005075 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005076 return false;
5077 }
5078
5079 Program *programObject = GetValidProgram(context, program);
5080
5081 if (!programObject)
5082 {
5083 return false;
5084 }
5085
5086 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5087 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005088 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005089 return false;
5090 }
5091
5092 return true;
5093}
5094
5095bool ValidateGetActiveUniform(ValidationContext *context,
5096 GLuint program,
5097 GLuint index,
5098 GLsizei bufsize,
5099 GLsizei *length,
5100 GLint *size,
5101 GLenum *type,
5102 GLchar *name)
5103{
5104 if (bufsize < 0)
5105 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005106 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005107 return false;
5108 }
5109
5110 Program *programObject = GetValidProgram(context, program);
5111
5112 if (!programObject)
5113 {
5114 return false;
5115 }
5116
5117 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5118 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005119 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005120 return false;
5121 }
5122
5123 return true;
5124}
5125
5126bool ValidateGetAttachedShaders(ValidationContext *context,
5127 GLuint program,
5128 GLsizei maxcount,
5129 GLsizei *count,
5130 GLuint *shaders)
5131{
5132 if (maxcount < 0)
5133 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005134 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005135 return false;
5136 }
5137
5138 Program *programObject = GetValidProgram(context, program);
5139
5140 if (!programObject)
5141 {
5142 return false;
5143 }
5144
5145 return true;
5146}
5147
5148bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5149{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005150 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5151 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005152 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005154 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005155 return false;
5156 }
5157
Jamie Madillc1d770e2017-04-13 17:31:24 -04005158 Program *programObject = GetValidProgram(context, program);
5159
5160 if (!programObject)
5161 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005162 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005163 return false;
5164 }
5165
5166 if (!programObject->isLinked())
5167 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005168 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005169 return false;
5170 }
5171
5172 return true;
5173}
5174
5175bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5176{
5177 GLenum nativeType;
5178 unsigned int numParams = 0;
5179 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5180}
5181
5182bool ValidateGetError(ValidationContext *context)
5183{
5184 return true;
5185}
5186
5187bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5188{
5189 GLenum nativeType;
5190 unsigned int numParams = 0;
5191 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5192}
5193
5194bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5195{
5196 GLenum nativeType;
5197 unsigned int numParams = 0;
5198 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5199}
5200
5201bool ValidateGetProgramInfoLog(ValidationContext *context,
5202 GLuint program,
5203 GLsizei bufsize,
5204 GLsizei *length,
5205 GLchar *infolog)
5206{
5207 if (bufsize < 0)
5208 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005209 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005210 return false;
5211 }
5212
5213 Program *programObject = GetValidProgram(context, program);
5214 if (!programObject)
5215 {
5216 return false;
5217 }
5218
5219 return true;
5220}
5221
5222bool ValidateGetShaderInfoLog(ValidationContext *context,
5223 GLuint shader,
5224 GLsizei bufsize,
5225 GLsizei *length,
5226 GLchar *infolog)
5227{
5228 if (bufsize < 0)
5229 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005230 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005231 return false;
5232 }
5233
5234 Shader *shaderObject = GetValidShader(context, shader);
5235 if (!shaderObject)
5236 {
5237 return false;
5238 }
5239
5240 return true;
5241}
5242
5243bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5244 GLenum shadertype,
5245 GLenum precisiontype,
5246 GLint *range,
5247 GLint *precision)
5248{
5249 switch (shadertype)
5250 {
5251 case GL_VERTEX_SHADER:
5252 case GL_FRAGMENT_SHADER:
5253 break;
5254 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005255 context->handleError(InvalidOperation()
5256 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005257 return false;
5258 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005259 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005260 return false;
5261 }
5262
5263 switch (precisiontype)
5264 {
5265 case GL_LOW_FLOAT:
5266 case GL_MEDIUM_FLOAT:
5267 case GL_HIGH_FLOAT:
5268 case GL_LOW_INT:
5269 case GL_MEDIUM_INT:
5270 case GL_HIGH_INT:
5271 break;
5272
5273 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005274 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005275 return false;
5276 }
5277
5278 return true;
5279}
5280
5281bool ValidateGetShaderSource(ValidationContext *context,
5282 GLuint shader,
5283 GLsizei bufsize,
5284 GLsizei *length,
5285 GLchar *source)
5286{
5287 if (bufsize < 0)
5288 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005289 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005290 return false;
5291 }
5292
5293 Shader *shaderObject = GetValidShader(context, shader);
5294 if (!shaderObject)
5295 {
5296 return false;
5297 }
5298
5299 return true;
5300}
5301
5302bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5303{
5304 if (strstr(name, "gl_") == name)
5305 {
5306 return false;
5307 }
5308
Geoff Langfc32e8b2017-05-31 14:16:59 -04005309 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5310 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005311 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005312 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005313 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005314 return false;
5315 }
5316
Jamie Madillc1d770e2017-04-13 17:31:24 -04005317 Program *programObject = GetValidProgram(context, program);
5318
5319 if (!programObject)
5320 {
5321 return false;
5322 }
5323
5324 if (!programObject->isLinked())
5325 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005326 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005327 return false;
5328 }
5329
5330 return true;
5331}
5332
5333bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5334{
5335 switch (mode)
5336 {
5337 case GL_FASTEST:
5338 case GL_NICEST:
5339 case GL_DONT_CARE:
5340 break;
5341
5342 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005343 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005344 return false;
5345 }
5346
5347 switch (target)
5348 {
5349 case GL_GENERATE_MIPMAP_HINT:
5350 break;
5351
Geoff Lange7bd2182017-06-16 16:13:13 -04005352 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5353 if (context->getClientVersion() < ES_3_0 &&
5354 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005355 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005356 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005357 return false;
5358 }
5359 break;
5360
5361 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005362 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005363 return false;
5364 }
5365
5366 return true;
5367}
5368
5369bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5370{
5371 return true;
5372}
5373
5374bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5375{
5376 return true;
5377}
5378
5379bool ValidateIsProgram(ValidationContext *context, GLuint program)
5380{
5381 return true;
5382}
5383
5384bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5385{
5386 return true;
5387}
5388
5389bool ValidateIsShader(ValidationContext *context, GLuint shader)
5390{
5391 return true;
5392}
5393
5394bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5395{
5396 return true;
5397}
5398
5399bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5400{
5401 if (context->getClientMajorVersion() < 3)
5402 {
5403 switch (pname)
5404 {
5405 case GL_UNPACK_IMAGE_HEIGHT:
5406 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005407 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005408 return false;
5409
5410 case GL_UNPACK_ROW_LENGTH:
5411 case GL_UNPACK_SKIP_ROWS:
5412 case GL_UNPACK_SKIP_PIXELS:
5413 if (!context->getExtensions().unpackSubimage)
5414 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005415 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005416 return false;
5417 }
5418 break;
5419
5420 case GL_PACK_ROW_LENGTH:
5421 case GL_PACK_SKIP_ROWS:
5422 case GL_PACK_SKIP_PIXELS:
5423 if (!context->getExtensions().packSubimage)
5424 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005425 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005426 return false;
5427 }
5428 break;
5429 }
5430 }
5431
5432 if (param < 0)
5433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005434 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005435 return false;
5436 }
5437
5438 switch (pname)
5439 {
5440 case GL_UNPACK_ALIGNMENT:
5441 if (param != 1 && param != 2 && param != 4 && param != 8)
5442 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005443 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444 return false;
5445 }
5446 break;
5447
5448 case GL_PACK_ALIGNMENT:
5449 if (param != 1 && param != 2 && param != 4 && param != 8)
5450 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005451 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005452 return false;
5453 }
5454 break;
5455
5456 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005457 if (!context->getExtensions().packReverseRowOrder)
5458 {
5459 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5460 }
5461 break;
5462
Jamie Madillc1d770e2017-04-13 17:31:24 -04005463 case GL_UNPACK_ROW_LENGTH:
5464 case GL_UNPACK_IMAGE_HEIGHT:
5465 case GL_UNPACK_SKIP_IMAGES:
5466 case GL_UNPACK_SKIP_ROWS:
5467 case GL_UNPACK_SKIP_PIXELS:
5468 case GL_PACK_ROW_LENGTH:
5469 case GL_PACK_SKIP_ROWS:
5470 case GL_PACK_SKIP_PIXELS:
5471 break;
5472
5473 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005474 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005475 return false;
5476 }
5477
5478 return true;
5479}
5480
5481bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5482{
5483 return true;
5484}
5485
5486bool ValidateReleaseShaderCompiler(ValidationContext *context)
5487{
5488 return true;
5489}
5490
Jamie Madill876429b2017-04-20 15:46:24 -04005491bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005492{
5493 return true;
5494}
5495
5496bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5497{
5498 if (width < 0 || height < 0)
5499 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005500 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005501 return false;
5502 }
5503
5504 return true;
5505}
5506
5507bool ValidateShaderBinary(ValidationContext *context,
5508 GLsizei n,
5509 const GLuint *shaders,
5510 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005511 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005512 GLsizei length)
5513{
5514 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5515 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5516 shaderBinaryFormats.end())
5517 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005518 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005519 return false;
5520 }
5521
5522 return true;
5523}
5524
5525bool ValidateShaderSource(ValidationContext *context,
5526 GLuint shader,
5527 GLsizei count,
5528 const GLchar *const *string,
5529 const GLint *length)
5530{
5531 if (count < 0)
5532 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005533 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005534 return false;
5535 }
5536
Geoff Langfc32e8b2017-05-31 14:16:59 -04005537 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5538 // shader-related entry points
5539 if (context->getExtensions().webglCompatibility)
5540 {
5541 for (GLsizei i = 0; i < count; i++)
5542 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005543 size_t len =
5544 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005545
5546 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005547 if (!IsValidESSLShaderSourceString(string[i], len,
5548 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005549 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005550 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005551 return false;
5552 }
5553 }
5554 }
5555
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556 Shader *shaderObject = GetValidShader(context, shader);
5557 if (!shaderObject)
5558 {
5559 return false;
5560 }
5561
5562 return true;
5563}
5564
5565bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5566{
5567 if (!IsValidStencilFunc(func))
5568 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005569 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005570 return false;
5571 }
5572
5573 return true;
5574}
5575
5576bool ValidateStencilFuncSeparate(ValidationContext *context,
5577 GLenum face,
5578 GLenum func,
5579 GLint ref,
5580 GLuint mask)
5581{
5582 if (!IsValidStencilFace(face))
5583 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005584 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005585 return false;
5586 }
5587
5588 if (!IsValidStencilFunc(func))
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
5597bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5598{
5599 return true;
5600}
5601
5602bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5603{
5604 if (!IsValidStencilFace(face))
5605 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005606 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005607 return false;
5608 }
5609
5610 return true;
5611}
5612
5613bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5614{
5615 if (!IsValidStencilOp(fail))
5616 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005617 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005618 return false;
5619 }
5620
5621 if (!IsValidStencilOp(zfail))
5622 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005623 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005624 return false;
5625 }
5626
5627 if (!IsValidStencilOp(zpass))
5628 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005629 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005630 return false;
5631 }
5632
5633 return true;
5634}
5635
5636bool ValidateStencilOpSeparate(ValidationContext *context,
5637 GLenum face,
5638 GLenum fail,
5639 GLenum zfail,
5640 GLenum zpass)
5641{
5642 if (!IsValidStencilFace(face))
5643 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005644 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005645 return false;
5646 }
5647
5648 return ValidateStencilOp(context, fail, zfail, zpass);
5649}
5650
5651bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5652{
5653 return ValidateUniform(context, GL_FLOAT, location, 1);
5654}
5655
5656bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5657{
5658 return ValidateUniform(context, GL_FLOAT, location, count);
5659}
5660
Jamie Madillbe849e42017-05-02 15:49:00 -04005661bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5662{
5663 return ValidateUniform1iv(context, location, 1, &x);
5664}
5665
Jamie Madillc1d770e2017-04-13 17:31:24 -04005666bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5667{
5668 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5669}
5670
5671bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5672{
5673 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5674}
5675
5676bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5677{
5678 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5679}
5680
5681bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5682{
5683 return ValidateUniform(context, GL_INT_VEC2, location, count);
5684}
5685
5686bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5687{
5688 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5689}
5690
5691bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5692{
5693 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5694}
5695
5696bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5697{
5698 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5699}
5700
5701bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5702{
5703 return ValidateUniform(context, GL_INT_VEC3, location, count);
5704}
5705
5706bool ValidateUniform4f(ValidationContext *context,
5707 GLint location,
5708 GLfloat x,
5709 GLfloat y,
5710 GLfloat z,
5711 GLfloat w)
5712{
5713 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5714}
5715
5716bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5717{
5718 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5719}
5720
5721bool ValidateUniform4i(ValidationContext *context,
5722 GLint location,
5723 GLint x,
5724 GLint y,
5725 GLint z,
5726 GLint w)
5727{
5728 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5729}
5730
5731bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5732{
5733 return ValidateUniform(context, GL_INT_VEC4, location, count);
5734}
5735
5736bool ValidateUniformMatrix2fv(ValidationContext *context,
5737 GLint location,
5738 GLsizei count,
5739 GLboolean transpose,
5740 const GLfloat *value)
5741{
5742 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5743}
5744
5745bool ValidateUniformMatrix3fv(ValidationContext *context,
5746 GLint location,
5747 GLsizei count,
5748 GLboolean transpose,
5749 const GLfloat *value)
5750{
5751 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5752}
5753
5754bool ValidateUniformMatrix4fv(ValidationContext *context,
5755 GLint location,
5756 GLsizei count,
5757 GLboolean transpose,
5758 const GLfloat *value)
5759{
5760 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5761}
5762
5763bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5764{
5765 Program *programObject = GetValidProgram(context, program);
5766
5767 if (!programObject)
5768 {
5769 return false;
5770 }
5771
5772 return true;
5773}
5774
Jamie Madillc1d770e2017-04-13 17:31:24 -04005775bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5776{
5777 return ValidateVertexAttribIndex(context, index);
5778}
5779
5780bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5781{
5782 return ValidateVertexAttribIndex(context, index);
5783}
5784
5785bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5786{
5787 return ValidateVertexAttribIndex(context, index);
5788}
5789
5790bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5791{
5792 return ValidateVertexAttribIndex(context, index);
5793}
5794
5795bool ValidateVertexAttrib3f(ValidationContext *context,
5796 GLuint index,
5797 GLfloat x,
5798 GLfloat y,
5799 GLfloat z)
5800{
5801 return ValidateVertexAttribIndex(context, index);
5802}
5803
5804bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5805{
5806 return ValidateVertexAttribIndex(context, index);
5807}
5808
5809bool ValidateVertexAttrib4f(ValidationContext *context,
5810 GLuint index,
5811 GLfloat x,
5812 GLfloat y,
5813 GLfloat z,
5814 GLfloat w)
5815{
5816 return ValidateVertexAttribIndex(context, index);
5817}
5818
5819bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5820{
5821 return ValidateVertexAttribIndex(context, index);
5822}
5823
5824bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5825{
5826 if (width < 0 || height < 0)
5827 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005828 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005829 return false;
5830 }
5831
5832 return true;
5833}
5834
5835bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5836{
5837 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5838}
5839
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005840bool ValidateDrawElements(ValidationContext *context,
5841 GLenum mode,
5842 GLsizei count,
5843 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005844 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005845{
5846 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5847}
5848
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005849bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005850 GLenum target,
5851 GLenum attachment,
5852 GLenum pname,
5853 GLint *params)
5854{
5855 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5856 nullptr);
5857}
5858
5859bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5860{
5861 return ValidateGetProgramivBase(context, program, pname, nullptr);
5862}
5863
5864bool ValidateCopyTexImage2D(ValidationContext *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005865 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005866 GLint level,
5867 GLenum internalformat,
5868 GLint x,
5869 GLint y,
5870 GLsizei width,
5871 GLsizei height,
5872 GLint border)
5873{
5874 if (context->getClientMajorVersion() < 3)
5875 {
5876 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5877 0, x, y, width, height, border);
5878 }
5879
5880 ASSERT(context->getClientMajorVersion() == 3);
5881 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5882 0, x, y, width, height, border);
5883}
5884
5885bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005886 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005887 GLint level,
5888 GLint xoffset,
5889 GLint yoffset,
5890 GLint x,
5891 GLint y,
5892 GLsizei width,
5893 GLsizei height)
5894{
5895 if (context->getClientMajorVersion() < 3)
5896 {
5897 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5898 yoffset, x, y, width, height, 0);
5899 }
5900
5901 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5902 yoffset, 0, x, y, width, height, 0);
5903}
5904
5905bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5906{
5907 return ValidateGenOrDelete(context, n);
5908}
5909
5910bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5911{
5912 return ValidateGenOrDelete(context, n);
5913}
5914
5915bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5916{
5917 return ValidateGenOrDelete(context, n);
5918}
5919
5920bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5921{
5922 return ValidateGenOrDelete(context, n);
5923}
5924
5925bool ValidateDisable(Context *context, GLenum cap)
5926{
5927 if (!ValidCap(context, cap, false))
5928 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005929 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005930 return false;
5931 }
5932
5933 return true;
5934}
5935
5936bool ValidateEnable(Context *context, GLenum cap)
5937{
5938 if (!ValidCap(context, cap, false))
5939 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005940 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005941 return false;
5942 }
5943
5944 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5945 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5946 {
5947 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005948 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005949
5950 // We also output an error message to the debugger window if tracing is active, so that
5951 // developers can see the error message.
5952 ERR() << errorMessage;
5953 return false;
5954 }
5955
5956 return true;
5957}
5958
5959bool ValidateFramebufferRenderbuffer(Context *context,
5960 GLenum target,
5961 GLenum attachment,
5962 GLenum renderbuffertarget,
5963 GLuint renderbuffer)
5964{
Geoff Lange8afa902017-09-27 15:00:43 -04005965 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005966 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005967 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5968 return false;
5969 }
5970
5971 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5972 {
5973 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005974 return false;
5975 }
5976
5977 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5978 renderbuffertarget, renderbuffer);
5979}
5980
5981bool ValidateFramebufferTexture2D(Context *context,
5982 GLenum target,
5983 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005984 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005985 GLuint texture,
5986 GLint level)
5987{
5988 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5989 // extension
5990 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5991 level != 0)
5992 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005993 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005994 return false;
5995 }
5996
5997 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5998 {
5999 return false;
6000 }
6001
6002 if (texture != 0)
6003 {
6004 gl::Texture *tex = context->getTexture(texture);
6005 ASSERT(tex);
6006
6007 const gl::Caps &caps = context->getCaps();
6008
6009 switch (textarget)
6010 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006011 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 {
6013 if (level > gl::log2(caps.max2DTextureSize))
6014 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006015 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006016 return false;
6017 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006018 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006019 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006020 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006021 return false;
6022 }
6023 }
6024 break;
6025
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006026 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006027 {
6028 if (level != 0)
6029 {
6030 context->handleError(InvalidValue());
6031 return false;
6032 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006033 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006034 {
6035 context->handleError(InvalidOperation()
6036 << "Textarget must match the texture target type.");
6037 return false;
6038 }
6039 }
6040 break;
6041
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006042 case TextureTarget::CubeMapNegativeX:
6043 case TextureTarget::CubeMapNegativeY:
6044 case TextureTarget::CubeMapNegativeZ:
6045 case TextureTarget::CubeMapPositiveX:
6046 case TextureTarget::CubeMapPositiveY:
6047 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006048 {
6049 if (level > gl::log2(caps.maxCubeMapTextureSize))
6050 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006051 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006052 return false;
6053 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006054 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006055 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006056 context->handleError(InvalidOperation()
6057 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 return false;
6059 }
6060 }
6061 break;
6062
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006063 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006064 {
6065 if (context->getClientVersion() < ES_3_1)
6066 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006067 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006068 return false;
6069 }
6070
6071 if (level != 0)
6072 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006073 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006074 return false;
6075 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006076 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006077 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006078 context->handleError(InvalidOperation()
6079 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006080 return false;
6081 }
6082 }
6083 break;
6084
6085 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006086 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006087 return false;
6088 }
6089
6090 const Format &format = tex->getFormat(textarget, level);
6091 if (format.info->compressed)
6092 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006093 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006094 return false;
6095 }
6096 }
6097
6098 return true;
6099}
6100
6101bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6102{
6103 return ValidateGenOrDelete(context, n);
6104}
6105
6106bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6107{
6108 return ValidateGenOrDelete(context, n);
6109}
6110
6111bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6112{
6113 return ValidateGenOrDelete(context, n);
6114}
6115
6116bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6117{
6118 return ValidateGenOrDelete(context, n);
6119}
6120
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006121bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006122{
6123 if (!ValidTextureTarget(context, target))
6124 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006125 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006126 return false;
6127 }
6128
6129 Texture *texture = context->getTargetTexture(target);
6130
6131 if (texture == nullptr)
6132 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006133 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006134 return false;
6135 }
6136
6137 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6138
6139 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6140 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6141 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006143 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006144 return false;
6145 }
6146
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006147 TextureTarget baseTarget = (target == TextureType::CubeMap)
6148 ? TextureTarget::CubeMapPositiveX
6149 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006150 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6151 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6152 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006153 {
6154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6155 return false;
6156 }
6157
Geoff Lang536eca12017-09-13 11:23:35 -04006158 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6159 bool formatUnsized = !format.sized;
6160 bool formatColorRenderableAndFilterable =
6161 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6162 format.renderSupport(context->getClientVersion(), context->getExtensions());
6163 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006164 {
Geoff Lang536eca12017-09-13 11:23:35 -04006165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006166 return false;
6167 }
6168
Geoff Lang536eca12017-09-13 11:23:35 -04006169 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6170 // generation
6171 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6172 {
6173 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6174 return false;
6175 }
6176
6177 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6178 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006179 bool supportsSRGBMipmapGeneration =
6180 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006181 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006182 {
Geoff Lang536eca12017-09-13 11:23:35 -04006183 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006184 return false;
6185 }
6186
6187 // Non-power of 2 ES2 check
6188 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6189 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6190 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6191 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006192 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6193 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006194 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006195 return false;
6196 }
6197
6198 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006199 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006201 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006202 return false;
6203 }
6204
6205 return true;
6206}
6207
6208bool ValidateGetBufferParameteriv(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006209 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006210 GLenum pname,
6211 GLint *params)
6212{
6213 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6214}
6215
6216bool ValidateGetRenderbufferParameteriv(Context *context,
6217 GLenum target,
6218 GLenum pname,
6219 GLint *params)
6220{
6221 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6222}
6223
6224bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6225{
6226 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6227}
6228
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006229bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006230{
6231 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6232}
6233
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006234bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006235{
6236 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6237}
6238
6239bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6240{
6241 return ValidateGetUniformBase(context, program, location);
6242}
6243
6244bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6245{
6246 return ValidateGetUniformBase(context, program, location);
6247}
6248
6249bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6250{
6251 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6252}
6253
6254bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6255{
6256 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6257}
6258
6259bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6260{
6261 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6262}
6263
6264bool ValidateIsEnabled(Context *context, GLenum cap)
6265{
6266 if (!ValidCap(context, cap, true))
6267 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006268 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006269 return false;
6270 }
6271
6272 return true;
6273}
6274
6275bool ValidateLinkProgram(Context *context, GLuint program)
6276{
6277 if (context->hasActiveTransformFeedback(program))
6278 {
6279 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006280 context->handleError(InvalidOperation() << "Cannot link program while program is "
6281 "associated with an active transform "
6282 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006283 return false;
6284 }
6285
6286 Program *programObject = GetValidProgram(context, program);
6287 if (!programObject)
6288 {
6289 return false;
6290 }
6291
6292 return true;
6293}
6294
Jamie Madill4928b7c2017-06-20 12:57:39 -04006295bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006296 GLint x,
6297 GLint y,
6298 GLsizei width,
6299 GLsizei height,
6300 GLenum format,
6301 GLenum type,
6302 void *pixels)
6303{
6304 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6305 nullptr, pixels);
6306}
6307
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006308bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006309{
6310 return ValidateTexParameterBase(context, target, pname, -1, &param);
6311}
6312
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006313bool ValidateTexParameterfv(Context *context,
6314 TextureType target,
6315 GLenum pname,
6316 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006317{
6318 return ValidateTexParameterBase(context, target, pname, -1, params);
6319}
6320
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006321bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006322{
6323 return ValidateTexParameterBase(context, target, pname, -1, &param);
6324}
6325
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006326bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006327{
6328 return ValidateTexParameterBase(context, target, pname, -1, params);
6329}
6330
6331bool ValidateUseProgram(Context *context, GLuint program)
6332{
6333 if (program != 0)
6334 {
6335 Program *programObject = context->getProgram(program);
6336 if (!programObject)
6337 {
6338 // ES 3.1.0 section 7.3 page 72
6339 if (context->getShader(program))
6340 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006341 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006342 return false;
6343 }
6344 else
6345 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006346 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006347 return false;
6348 }
6349 }
6350 if (!programObject->isLinked())
6351 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006352 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006353 return false;
6354 }
6355 }
6356 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6357 {
6358 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006359 context
6360 ->handleError(InvalidOperation()
6361 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006362 return false;
6363 }
6364
6365 return true;
6366}
6367
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006368bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6369{
6370 if (!context->getExtensions().fence)
6371 {
6372 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6373 return false;
6374 }
6375
6376 if (n < 0)
6377 {
6378 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6379 return false;
6380 }
6381
6382 return true;
6383}
6384
6385bool ValidateFinishFenceNV(Context *context, GLuint fence)
6386{
6387 if (!context->getExtensions().fence)
6388 {
6389 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6390 return false;
6391 }
6392
6393 FenceNV *fenceObject = context->getFenceNV(fence);
6394
6395 if (fenceObject == nullptr)
6396 {
6397 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6398 return false;
6399 }
6400
6401 if (!fenceObject->isSet())
6402 {
6403 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6404 return false;
6405 }
6406
6407 return true;
6408}
6409
6410bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6411{
6412 if (!context->getExtensions().fence)
6413 {
6414 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6415 return false;
6416 }
6417
6418 if (n < 0)
6419 {
6420 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6421 return false;
6422 }
6423
6424 return true;
6425}
6426
6427bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6428{
6429 if (!context->getExtensions().fence)
6430 {
6431 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6432 return false;
6433 }
6434
6435 FenceNV *fenceObject = context->getFenceNV(fence);
6436
6437 if (fenceObject == nullptr)
6438 {
6439 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6440 return false;
6441 }
6442
6443 if (!fenceObject->isSet())
6444 {
6445 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6446 return false;
6447 }
6448
6449 switch (pname)
6450 {
6451 case GL_FENCE_STATUS_NV:
6452 case GL_FENCE_CONDITION_NV:
6453 break;
6454
6455 default:
6456 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6457 return false;
6458 }
6459
6460 return true;
6461}
6462
6463bool ValidateGetGraphicsResetStatusEXT(Context *context)
6464{
6465 if (!context->getExtensions().robustness)
6466 {
6467 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6468 return false;
6469 }
6470
6471 return true;
6472}
6473
6474bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6475 GLuint shader,
6476 GLsizei bufsize,
6477 GLsizei *length,
6478 GLchar *source)
6479{
6480 if (!context->getExtensions().translatedShaderSource)
6481 {
6482 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6483 return false;
6484 }
6485
6486 if (bufsize < 0)
6487 {
6488 context->handleError(InvalidValue());
6489 return false;
6490 }
6491
6492 Shader *shaderObject = context->getShader(shader);
6493
6494 if (!shaderObject)
6495 {
6496 context->handleError(InvalidOperation());
6497 return false;
6498 }
6499
6500 return true;
6501}
6502
6503bool ValidateIsFenceNV(Context *context, GLuint fence)
6504{
6505 if (!context->getExtensions().fence)
6506 {
6507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6508 return false;
6509 }
6510
6511 return true;
6512}
6513
Jamie Madill007530e2017-12-28 14:27:04 -05006514bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6515{
6516 if (!context->getExtensions().fence)
6517 {
6518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6519 return false;
6520 }
6521
6522 if (condition != GL_ALL_COMPLETED_NV)
6523 {
6524 context->handleError(InvalidEnum());
6525 return false;
6526 }
6527
6528 FenceNV *fenceObject = context->getFenceNV(fence);
6529
6530 if (fenceObject == nullptr)
6531 {
6532 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6533 return false;
6534 }
6535
6536 return true;
6537}
6538
6539bool ValidateTestFenceNV(Context *context, GLuint fence)
6540{
6541 if (!context->getExtensions().fence)
6542 {
6543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6544 return false;
6545 }
6546
6547 FenceNV *fenceObject = context->getFenceNV(fence);
6548
6549 if (fenceObject == nullptr)
6550 {
6551 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6552 return false;
6553 }
6554
6555 if (fenceObject->isSet() != GL_TRUE)
6556 {
6557 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6558 return false;
6559 }
6560
6561 return true;
6562}
6563
6564bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006565 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006566 GLsizei levels,
6567 GLenum internalformat,
6568 GLsizei width,
6569 GLsizei height)
6570{
6571 if (!context->getExtensions().textureStorage)
6572 {
6573 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6574 return false;
6575 }
6576
6577 if (context->getClientMajorVersion() < 3)
6578 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006579 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006580 height);
6581 }
6582
6583 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006584 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006585 1);
6586}
6587
6588bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6589{
6590 if (!context->getExtensions().instancedArrays)
6591 {
6592 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6593 return false;
6594 }
6595
6596 if (index >= MAX_VERTEX_ATTRIBS)
6597 {
6598 context->handleError(InvalidValue());
6599 return false;
6600 }
6601
6602 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6603 {
6604 if (index == 0 && divisor != 0)
6605 {
6606 const char *errorMessage =
6607 "The current context doesn't support setting a non-zero divisor on the "
6608 "attribute with index zero. "
6609 "Please reorder the attributes in your vertex shader so that attribute zero "
6610 "can have a zero divisor.";
6611 context->handleError(InvalidOperation() << errorMessage);
6612
6613 // We also output an error message to the debugger window if tracing is active, so
6614 // that developers can see the error message.
6615 ERR() << errorMessage;
6616 return false;
6617 }
6618 }
6619
6620 return true;
6621}
6622
6623bool ValidateTexImage3DOES(Context *context,
6624 GLenum target,
6625 GLint level,
6626 GLenum internalformat,
6627 GLsizei width,
6628 GLsizei height,
6629 GLsizei depth,
6630 GLint border,
6631 GLenum format,
6632 GLenum type,
6633 const void *pixels)
6634{
6635 UNIMPLEMENTED(); // FIXME
6636 return false;
6637}
6638
6639bool ValidatePopGroupMarkerEXT(Context *context)
6640{
6641 if (!context->getExtensions().debugMarker)
6642 {
6643 // The debug marker calls should not set error state
6644 // However, it seems reasonable to set an error state if the extension is not enabled
6645 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6646 return false;
6647 }
6648
6649 return true;
6650}
6651
Jamie Madillfa920eb2018-01-04 11:45:50 -05006652bool ValidateTexStorage1DEXT(Context *context,
6653 GLenum target,
6654 GLsizei levels,
6655 GLenum internalformat,
6656 GLsizei width)
6657{
6658 UNIMPLEMENTED();
6659 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6660 return false;
6661}
6662
6663bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006664 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006665 GLsizei levels,
6666 GLenum internalformat,
6667 GLsizei width,
6668 GLsizei height,
6669 GLsizei depth)
6670{
6671 if (!context->getExtensions().textureStorage)
6672 {
6673 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6674 return false;
6675 }
6676
6677 if (context->getClientMajorVersion() < 3)
6678 {
6679 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6680 return false;
6681 }
6682
6683 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6684 depth);
6685}
6686
Jamie Madillc29968b2016-01-20 11:17:23 -05006687} // namespace gl