blob: bb164ef5cc19d9167e40982fa14f635e5b32de07 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070078 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030079 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800374 GLsizei height,
375 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800377 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378 {
379 return false;
380 }
381
Brandon Jones28783792018-03-05 09:37:32 -0800382 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
383 {
384 return false;
385 }
386
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800388 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 case TextureType::_2D:
391 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
392 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
393 case TextureType::Rectangle:
394 ASSERT(level == 0);
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400397
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800398 case TextureType::CubeMap:
399 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
401 default:
402 return true;
403 }
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madill5b772312018-03-08 20:28:32 -0500458bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800459 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800477 TextureType texType = TextureTargetToType(target);
478 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500480 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 return false;
482 }
483
484 Format textureFormat = Format::Invalid();
485 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
486 xoffset, yoffset, 0, x, y, width, height, border,
487 &textureFormat))
488 {
489 return false;
490 }
491
492 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
493 GLenum colorbufferFormat =
494 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
495 const auto &formatInfo = *textureFormat.info;
496
497 // [OpenGL ES 2.0.24] table 3.9
498 if (isSubImage)
499 {
500 switch (formatInfo.format)
501 {
502 case GL_ALPHA:
503 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400504 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
505 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400506 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 return false;
509 }
510 break;
511 case GL_LUMINANCE:
512 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
513 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
514 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400515 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
516 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 return false;
520 }
521 break;
522 case GL_RED_EXT:
523 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
524 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
525 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
526 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
527 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400528 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
529 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400530 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 return false;
533 }
534 break;
535 case GL_RG_EXT:
536 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
537 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
538 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
539 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400540 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
541 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400542 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 return false;
545 }
546 break;
547 case GL_RGB:
548 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
549 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
550 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400551 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
552 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 return false;
556 }
557 break;
558 case GL_LUMINANCE_ALPHA:
559 case GL_RGBA:
560 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400561 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
562 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 return false;
566 }
567 break;
568 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
571 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
572 case GL_ETC1_RGB8_OES:
573 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
574 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400579 return false;
580 case GL_DEPTH_COMPONENT:
581 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700582 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400583 return false;
584 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588
589 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
590 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594 }
595 else
596 {
597 switch (internalformat)
598 {
599 case GL_ALPHA:
600 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
601 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
602 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
603 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700604 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400605 return false;
606 }
607 break;
608 case GL_LUMINANCE:
609 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
610 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
611 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
612 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
613 colorbufferFormat != GL_BGR5_A1_ANGLEX)
614 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400616 return false;
617 }
618 break;
619 case GL_RED_EXT:
620 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
621 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
622 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
623 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
624 colorbufferFormat != GL_BGR5_A1_ANGLEX)
625 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700626 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400627 return false;
628 }
629 break;
630 case GL_RG_EXT:
631 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
632 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
633 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
634 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
635 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 return false;
638 }
639 break;
640 case GL_RGB:
641 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
642 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
643 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
644 colorbufferFormat != GL_BGR5_A1_ANGLEX)
645 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700646 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 return false;
648 }
649 break;
650 case GL_LUMINANCE_ALPHA:
651 case GL_RGBA:
652 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
653 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
654 colorbufferFormat != GL_BGR5_A1_ANGLEX)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 break;
660 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
661 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
662 if (context->getExtensions().textureCompressionDXT1)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 else
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 break;
673 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
674 if (context->getExtensions().textureCompressionDXT3)
675 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678 }
679 else
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 break;
685 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
686 if (context->getExtensions().textureCompressionDXT5)
687 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400689 return false;
690 }
691 else
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 break;
697 case GL_ETC1_RGB8_OES:
698 if (context->getExtensions().compressedETC1RGB8Texture)
699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500700 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400701 return false;
702 }
703 else
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 break;
709 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
710 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 if (context->getExtensions().lossyETCDecode)
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidOperation()
717 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 else
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidEnum()
723 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 break;
727 case GL_DEPTH_COMPONENT:
728 case GL_DEPTH_COMPONENT16:
729 case GL_DEPTH_COMPONENT32_OES:
730 case GL_DEPTH_STENCIL_OES:
731 case GL_DEPTH24_STENCIL8_OES:
732 if (context->getExtensions().depthTextures)
733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500734 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400735 return false;
736 }
737 else
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 }
747
748 // If width or height is zero, it is a no-op. Return false without setting an error.
749 return (width > 0 && height > 0);
750}
751
752bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
753{
754 switch (cap)
755 {
756 // EXT_multisample_compatibility
757 case GL_MULTISAMPLE_EXT:
758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
759 return context->getExtensions().multisampleCompatibility;
760
761 case GL_CULL_FACE:
762 case GL_POLYGON_OFFSET_FILL:
763 case GL_SAMPLE_ALPHA_TO_COVERAGE:
764 case GL_SAMPLE_COVERAGE:
765 case GL_SCISSOR_TEST:
766 case GL_STENCIL_TEST:
767 case GL_DEPTH_TEST:
768 case GL_BLEND:
769 case GL_DITHER:
770 return true;
771
772 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
773 case GL_RASTERIZER_DISCARD:
774 return (context->getClientMajorVersion() >= 3);
775
776 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
777 case GL_DEBUG_OUTPUT:
778 return context->getExtensions().debug;
779
780 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
781 return queryOnly && context->getExtensions().bindGeneratesResource;
782
783 case GL_CLIENT_ARRAYS_ANGLE:
784 return queryOnly && context->getExtensions().clientArrays;
785
786 case GL_FRAMEBUFFER_SRGB_EXT:
787 return context->getExtensions().sRGBWriteControl;
788
789 case GL_SAMPLE_MASK:
790 return context->getClientVersion() >= Version(3, 1);
791
Geoff Langb433e872017-10-05 14:01:47 -0400792 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400793 return queryOnly && context->getExtensions().robustResourceInitialization;
794
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700795 // GLES1 emulation: GLES1-specific caps
796 case GL_ALPHA_TEST:
797 return context->getClientVersion() < Version(2, 0);
798
Jamie Madillbe849e42017-05-02 15:49:00 -0400799 default:
800 return false;
801 }
802}
803
Geoff Langfc32e8b2017-05-31 14:16:59 -0400804// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
805// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400806bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400807{
808 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400809 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
810 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400811 {
812 return true;
813 }
814
815 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
816 if (c >= 9 && c <= 13)
817 {
818 return true;
819 }
820
821 return false;
822}
823
Geoff Langcab92ee2017-07-19 17:32:07 -0400824bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400825{
Geoff Langa71a98e2017-06-19 15:15:00 -0400826 for (size_t i = 0; i < len; i++)
827 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400828 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400829 {
830 return false;
831 }
832 }
833
834 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400835}
836
Geoff Langcab92ee2017-07-19 17:32:07 -0400837bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
838{
839 enum class ParseState
840 {
841 // Have not seen an ASCII non-whitespace character yet on
842 // this line. Possible that we might see a preprocessor
843 // directive.
844 BEGINING_OF_LINE,
845
846 // Have seen at least one ASCII non-whitespace character
847 // on this line.
848 MIDDLE_OF_LINE,
849
850 // Handling a preprocessor directive. Passes through all
851 // characters up to the end of the line. Disables comment
852 // processing.
853 IN_PREPROCESSOR_DIRECTIVE,
854
855 // Handling a single-line comment. The comment text is
856 // replaced with a single space.
857 IN_SINGLE_LINE_COMMENT,
858
859 // Handling a multi-line comment. Newlines are passed
860 // through to preserve line numbers.
861 IN_MULTI_LINE_COMMENT
862 };
863
864 ParseState state = ParseState::BEGINING_OF_LINE;
865 size_t pos = 0;
866
867 while (pos < len)
868 {
869 char c = str[pos];
870 char next = pos + 1 < len ? str[pos + 1] : 0;
871
872 // Check for newlines
873 if (c == '\n' || c == '\r')
874 {
875 if (state != ParseState::IN_MULTI_LINE_COMMENT)
876 {
877 state = ParseState::BEGINING_OF_LINE;
878 }
879
880 pos++;
881 continue;
882 }
883
884 switch (state)
885 {
886 case ParseState::BEGINING_OF_LINE:
887 if (c == ' ')
888 {
889 // Maintain the BEGINING_OF_LINE state until a non-space is seen
890 pos++;
891 }
892 else if (c == '#')
893 {
894 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
895 pos++;
896 }
897 else
898 {
899 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
900 state = ParseState::MIDDLE_OF_LINE;
901 }
902 break;
903
904 case ParseState::MIDDLE_OF_LINE:
905 if (c == '/' && next == '/')
906 {
907 state = ParseState::IN_SINGLE_LINE_COMMENT;
908 pos++;
909 }
910 else if (c == '/' && next == '*')
911 {
912 state = ParseState::IN_MULTI_LINE_COMMENT;
913 pos++;
914 }
915 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
916 {
917 // Skip line continuation characters
918 }
919 else if (!IsValidESSLCharacter(c))
920 {
921 return false;
922 }
923 pos++;
924 break;
925
926 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700927 // Line-continuation characters may not be permitted.
928 // Otherwise, just pass it through. Do not parse comments in this state.
929 if (!lineContinuationAllowed && c == '\\')
930 {
931 return false;
932 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400933 pos++;
934 break;
935
936 case ParseState::IN_SINGLE_LINE_COMMENT:
937 // Line-continuation characters are processed before comment processing.
938 // Advance string if a new line character is immediately behind
939 // line-continuation character.
940 if (c == '\\' && (next == '\n' || next == '\r'))
941 {
942 pos++;
943 }
944 pos++;
945 break;
946
947 case ParseState::IN_MULTI_LINE_COMMENT:
948 if (c == '*' && next == '/')
949 {
950 state = ParseState::MIDDLE_OF_LINE;
951 pos++;
952 }
953 pos++;
954 break;
955 }
956 }
957
958 return true;
959}
960
Jamie Madill5b772312018-03-08 20:28:32 -0500961bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700962{
963 ASSERT(context->isWebGL());
964
965 // WebGL 1.0 [Section 6.16] GLSL Constructs
966 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
967 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
968 {
969 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
970 return false;
971 }
972
973 return true;
974}
975
Jamie Madill5b772312018-03-08 20:28:32 -0500976bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700977{
978 ASSERT(context->isWebGL());
979
980 if (context->isWebGL1() && length > 256)
981 {
982 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
983 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
984 // locations.
985 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
986
987 return false;
988 }
989 else if (length > 1024)
990 {
991 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
992 // uniform and attribute locations.
993 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
994 return false;
995 }
996
997 return true;
998}
999
Jamie Madill007530e2017-12-28 14:27:04 -05001000bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1001{
1002 if (!context->getExtensions().pathRendering)
1003 {
1004 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1005 return false;
1006 }
1007
1008 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1009 {
1010 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1011 return false;
1012 }
1013 return true;
1014}
Jamie Madillc29968b2016-01-20 11:17:23 -05001015} // anonymous namespace
1016
Geoff Langff5b2d52016-09-07 11:32:23 -04001017bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001018 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001019 GLint level,
1020 GLenum internalformat,
1021 bool isCompressed,
1022 bool isSubImage,
1023 GLint xoffset,
1024 GLint yoffset,
1025 GLsizei width,
1026 GLsizei height,
1027 GLint border,
1028 GLenum format,
1029 GLenum type,
1030 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001031 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001032{
Jamie Madill6f38f822014-06-06 17:12:20 -04001033 if (!ValidTexture2DDestinationTarget(context, target))
1034 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001035 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001036 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001037 }
1038
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001039 TextureType texType = TextureTargetToType(target);
1040 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001042 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001043 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001044 }
1045
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001046 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001047 {
1048 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1049 return false;
1050 }
1051
1052 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001053 std::numeric_limits<GLsizei>::max() - yoffset < height)
1054 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001055 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001056 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001057 }
1058
Geoff Lang6e898aa2017-06-02 11:17:26 -04001059 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1060 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1061 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1062 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1063 // case.
1064 bool nonEqualFormatsAllowed =
1065 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1066 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1067
1068 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001069 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001070 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001071 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001072 }
1073
Geoff Langaae65a42014-05-26 12:43:44 -04001074 const gl::Caps &caps = context->getCaps();
1075
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001076 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001077 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001078 case TextureType::_2D:
1079 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1080 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1081 {
1082 context->handleError(InvalidValue());
1083 return false;
1084 }
1085 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001086
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001087 case TextureType::Rectangle:
1088 ASSERT(level == 0);
1089 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1090 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1091 {
1092 context->handleError(InvalidValue());
1093 return false;
1094 }
1095 if (isCompressed)
1096 {
1097 context->handleError(InvalidEnum()
1098 << "Rectangle texture cannot have a compressed format.");
1099 return false;
1100 }
1101 break;
1102
1103 case TextureType::CubeMap:
1104 if (!isSubImage && width != height)
1105 {
1106 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1107 return false;
1108 }
1109
1110 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1111 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1112 {
1113 context->handleError(InvalidValue());
1114 return false;
1115 }
1116 break;
1117
1118 default:
1119 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001120 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001121 }
1122
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001123 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001124 if (!texture)
1125 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001126 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001127 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001128 }
1129
Geoff Langa9be0dc2014-12-17 12:34:40 -05001130 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001131 {
Geoff Langca271392017-04-05 12:30:00 -04001132 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1133 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001135 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001136 return false;
1137 }
1138
Geoff Langa9be0dc2014-12-17 12:34:40 -05001139 if (format != GL_NONE)
1140 {
Geoff Langca271392017-04-05 12:30:00 -04001141 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1142 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001143 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001145 return false;
1146 }
1147 }
1148
1149 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1150 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1151 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001152 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001153 return false;
1154 }
Geoff Langfb052642017-10-24 13:42:09 -04001155
1156 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001157 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001158 {
1159 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1160 return false;
1161 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001162 }
1163 else
1164 {
Geoff Lang69cce582015-09-17 13:20:36 -04001165 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001166 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001167 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001168 return false;
1169 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001170 }
1171
1172 // Verify zero border
1173 if (border != 0)
1174 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001175 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001176 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001177 }
1178
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001179 if (isCompressed)
1180 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001181 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001182 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1183 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184 switch (actualInternalFormat)
1185 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001186 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1187 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1188 if (!context->getExtensions().textureCompressionDXT1)
1189 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001190 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001191 return false;
1192 }
1193 break;
1194 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001195 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001196 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001197 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001198 return false;
1199 }
1200 break;
1201 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1202 if (!context->getExtensions().textureCompressionDXT5)
1203 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001204 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001205 return false;
1206 }
1207 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001208 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1209 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1210 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1211 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1212 if (!context->getExtensions().textureCompressionS3TCsRGB)
1213 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001214 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001215 return false;
1216 }
1217 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001218 case GL_ETC1_RGB8_OES:
1219 if (!context->getExtensions().compressedETC1RGB8Texture)
1220 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001221 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001222 return false;
1223 }
Geoff Lang86f81162017-10-30 15:10:45 -04001224 if (isSubImage)
1225 {
1226 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1227 return false;
1228 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001229 break;
1230 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001231 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1232 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1233 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1234 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001235 if (!context->getExtensions().lossyETCDecode)
1236 {
Geoff Lang86f81162017-10-30 15:10:45 -04001237 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001238 return false;
1239 }
1240 break;
1241 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001242 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001243 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001244 }
Geoff Lang966c9402017-04-18 12:38:27 -04001245
1246 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001247 {
Geoff Lang966c9402017-04-18 12:38:27 -04001248 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1249 height, texture->getWidth(target, level),
1250 texture->getHeight(target, level)))
1251 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001252 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001253 return false;
1254 }
1255
1256 if (format != actualInternalFormat)
1257 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001258 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001259 return false;
1260 }
1261 }
1262 else
1263 {
1264 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1265 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001266 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001267 return false;
1268 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001269 }
1270 }
1271 else
1272 {
1273 // validate <type> by itself (used as secondary key below)
1274 switch (type)
1275 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001276 case GL_UNSIGNED_BYTE:
1277 case GL_UNSIGNED_SHORT_5_6_5:
1278 case GL_UNSIGNED_SHORT_4_4_4_4:
1279 case GL_UNSIGNED_SHORT_5_5_5_1:
1280 case GL_UNSIGNED_SHORT:
1281 case GL_UNSIGNED_INT:
1282 case GL_UNSIGNED_INT_24_8_OES:
1283 case GL_HALF_FLOAT_OES:
1284 case GL_FLOAT:
1285 break;
1286 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001287 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001288 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001289 }
1290
1291 // validate <format> + <type> combinations
1292 // - invalid <format> -> sets INVALID_ENUM
1293 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1294 switch (format)
1295 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001296 case GL_ALPHA:
1297 case GL_LUMINANCE:
1298 case GL_LUMINANCE_ALPHA:
1299 switch (type)
1300 {
1301 case GL_UNSIGNED_BYTE:
1302 case GL_FLOAT:
1303 case GL_HALF_FLOAT_OES:
1304 break;
1305 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001306 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001307 return false;
1308 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001309 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001310 case GL_RED:
1311 case GL_RG:
1312 if (!context->getExtensions().textureRG)
1313 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001314 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001315 return false;
1316 }
1317 switch (type)
1318 {
1319 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001320 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001321 case GL_FLOAT:
1322 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001323 if (!context->getExtensions().textureFloat)
1324 {
1325 context->handleError(InvalidEnum());
1326 return false;
1327 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001328 break;
1329 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001330 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001331 return false;
1332 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001333 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001334 case GL_RGB:
1335 switch (type)
1336 {
1337 case GL_UNSIGNED_BYTE:
1338 case GL_UNSIGNED_SHORT_5_6_5:
1339 case GL_FLOAT:
1340 case GL_HALF_FLOAT_OES:
1341 break;
1342 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001343 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001344 return false;
1345 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001346 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001347 case GL_RGBA:
1348 switch (type)
1349 {
1350 case GL_UNSIGNED_BYTE:
1351 case GL_UNSIGNED_SHORT_4_4_4_4:
1352 case GL_UNSIGNED_SHORT_5_5_5_1:
1353 case GL_FLOAT:
1354 case GL_HALF_FLOAT_OES:
1355 break;
1356 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001358 return false;
1359 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001360 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001361 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001362 if (!context->getExtensions().textureFormatBGRA8888)
1363 {
1364 context->handleError(InvalidEnum());
1365 return false;
1366 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001367 switch (type)
1368 {
1369 case GL_UNSIGNED_BYTE:
1370 break;
1371 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001372 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001373 return false;
1374 }
1375 break;
1376 case GL_SRGB_EXT:
1377 case GL_SRGB_ALPHA_EXT:
1378 if (!context->getExtensions().sRGB)
1379 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001380 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001381 return false;
1382 }
1383 switch (type)
1384 {
1385 case GL_UNSIGNED_BYTE:
1386 break;
1387 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001389 return false;
1390 }
1391 break;
1392 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1393 // handled below
1394 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1395 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1396 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1397 break;
1398 case GL_DEPTH_COMPONENT:
1399 switch (type)
1400 {
1401 case GL_UNSIGNED_SHORT:
1402 case GL_UNSIGNED_INT:
1403 break;
1404 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001405 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001406 return false;
1407 }
1408 break;
1409 case GL_DEPTH_STENCIL_OES:
1410 switch (type)
1411 {
1412 case GL_UNSIGNED_INT_24_8_OES:
1413 break;
1414 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001415 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001416 return false;
1417 }
1418 break;
1419 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001420 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001421 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001422 }
1423
1424 switch (format)
1425 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001426 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1427 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1428 if (context->getExtensions().textureCompressionDXT1)
1429 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001430 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001431 return false;
1432 }
1433 else
1434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001435 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001436 return false;
1437 }
1438 break;
1439 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1440 if (context->getExtensions().textureCompressionDXT3)
1441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001442 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 else
1446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001447 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001448 return false;
1449 }
1450 break;
1451 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1452 if (context->getExtensions().textureCompressionDXT5)
1453 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001454 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001455 return false;
1456 }
1457 else
1458 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001459 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001460 return false;
1461 }
1462 break;
1463 case GL_ETC1_RGB8_OES:
1464 if (context->getExtensions().compressedETC1RGB8Texture)
1465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001466 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 return false;
1468 }
1469 else
1470 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001471 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001472 return false;
1473 }
1474 break;
1475 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001476 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1477 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1478 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1479 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001480 if (context->getExtensions().lossyETCDecode)
1481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001482 context->handleError(InvalidOperation()
1483 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001484 return false;
1485 }
1486 else
1487 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001488 context->handleError(InvalidEnum()
1489 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001490 return false;
1491 }
1492 break;
1493 case GL_DEPTH_COMPONENT:
1494 case GL_DEPTH_STENCIL_OES:
1495 if (!context->getExtensions().depthTextures)
1496 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001497 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001498 return false;
1499 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001500 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001501 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001502 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001503 return false;
1504 }
1505 // OES_depth_texture supports loading depth data and multiple levels,
1506 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001507 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001508 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001509 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1510 return false;
1511 }
1512 if (level != 0)
1513 {
1514 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001515 return false;
1516 }
1517 break;
1518 default:
1519 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001520 }
1521
Geoff Lang6e898aa2017-06-02 11:17:26 -04001522 if (!isSubImage)
1523 {
1524 switch (internalformat)
1525 {
1526 case GL_RGBA32F:
1527 if (!context->getExtensions().colorBufferFloatRGBA)
1528 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001529 context->handleError(InvalidValue()
1530 << "Sized GL_RGBA32F internal format requires "
1531 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001532 return false;
1533 }
1534 if (type != GL_FLOAT)
1535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001536 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001537 return false;
1538 }
1539 if (format != GL_RGBA)
1540 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001541 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001542 return false;
1543 }
1544 break;
1545
1546 case GL_RGB32F:
1547 if (!context->getExtensions().colorBufferFloatRGB)
1548 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001549 context->handleError(InvalidValue()
1550 << "Sized GL_RGB32F internal format requires "
1551 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001552 return false;
1553 }
1554 if (type != GL_FLOAT)
1555 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001556 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001557 return false;
1558 }
1559 if (format != GL_RGB)
1560 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001561 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001562 return false;
1563 }
1564 break;
1565
1566 default:
1567 break;
1568 }
1569 }
1570
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001571 if (type == GL_FLOAT)
1572 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001573 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001574 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001575 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001576 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001577 }
1578 }
1579 else if (type == GL_HALF_FLOAT_OES)
1580 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001581 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001582 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001583 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001584 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001585 }
1586 }
1587 }
1588
Geoff Langdbcced82017-06-06 15:55:54 -04001589 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001590 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001591 imageSize))
1592 {
1593 return false;
1594 }
1595
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001596 return true;
1597}
1598
He Yunchaoced53ae2016-11-29 15:00:51 +08001599bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001600 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001601 GLsizei levels,
1602 GLenum internalformat,
1603 GLsizei width,
1604 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001605{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001606 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1607 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001608 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001609 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001610 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001611 }
1612
1613 if (width < 1 || height < 1 || levels < 1)
1614 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001615 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001616 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001617 }
1618
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001619 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001620 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001621 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001622 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001623 }
1624
1625 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1626 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001627 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001628 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001629 }
1630
Geoff Langca271392017-04-05 12:30:00 -04001631 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001632 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001634 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001635 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 }
1637
Geoff Langaae65a42014-05-26 12:43:44 -04001638 const gl::Caps &caps = context->getCaps();
1639
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001640 switch (target)
1641 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001642 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001643 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1644 static_cast<GLuint>(height) > caps.max2DTextureSize)
1645 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001646 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001647 return false;
1648 }
1649 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001650 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001651 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1652 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1653 {
1654 context->handleError(InvalidValue());
1655 return false;
1656 }
1657 if (formatInfo.compressed)
1658 {
1659 context->handleError(InvalidEnum()
1660 << "Rectangle texture cannot have a compressed format.");
1661 return false;
1662 }
1663 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001664 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001665 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1666 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1667 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001668 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001669 return false;
1670 }
1671 break;
1672 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001673 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001674 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001675 }
1676
Geoff Langc0b9ef42014-07-02 10:02:37 -04001677 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001678 {
1679 if (!gl::isPow2(width) || !gl::isPow2(height))
1680 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001681 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001682 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001683 }
1684 }
1685
1686 switch (internalformat)
1687 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001688 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1689 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1690 if (!context->getExtensions().textureCompressionDXT1)
1691 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001692 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001693 return false;
1694 }
1695 break;
1696 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1697 if (!context->getExtensions().textureCompressionDXT3)
1698 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001699 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001700 return false;
1701 }
1702 break;
1703 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1704 if (!context->getExtensions().textureCompressionDXT5)
1705 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001706 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001707 return false;
1708 }
1709 break;
1710 case GL_ETC1_RGB8_OES:
1711 if (!context->getExtensions().compressedETC1RGB8Texture)
1712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001713 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001714 return false;
1715 }
1716 break;
1717 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001718 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1719 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1720 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1721 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001722 if (!context->getExtensions().lossyETCDecode)
1723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001724 context->handleError(InvalidEnum()
1725 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001726 return false;
1727 }
1728 break;
1729 case GL_RGBA32F_EXT:
1730 case GL_RGB32F_EXT:
1731 case GL_ALPHA32F_EXT:
1732 case GL_LUMINANCE32F_EXT:
1733 case GL_LUMINANCE_ALPHA32F_EXT:
1734 if (!context->getExtensions().textureFloat)
1735 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001736 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001737 return false;
1738 }
1739 break;
1740 case GL_RGBA16F_EXT:
1741 case GL_RGB16F_EXT:
1742 case GL_ALPHA16F_EXT:
1743 case GL_LUMINANCE16F_EXT:
1744 case GL_LUMINANCE_ALPHA16F_EXT:
1745 if (!context->getExtensions().textureHalfFloat)
1746 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001747 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001748 return false;
1749 }
1750 break;
1751 case GL_R8_EXT:
1752 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001753 if (!context->getExtensions().textureRG)
1754 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001755 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001756 return false;
1757 }
1758 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001759 case GL_R16F_EXT:
1760 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001761 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1762 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001763 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001764 return false;
1765 }
1766 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001767 case GL_R32F_EXT:
1768 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001769 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001770 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001771 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001772 return false;
1773 }
1774 break;
1775 case GL_DEPTH_COMPONENT16:
1776 case GL_DEPTH_COMPONENT32_OES:
1777 case GL_DEPTH24_STENCIL8_OES:
1778 if (!context->getExtensions().depthTextures)
1779 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001780 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001781 return false;
1782 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001783 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001785 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001786 return false;
1787 }
1788 // ANGLE_depth_texture only supports 1-level textures
1789 if (levels != 1)
1790 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001791 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001792 return false;
1793 }
1794 break;
1795 default:
1796 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001797 }
1798
Geoff Lang691e58c2014-12-19 17:03:25 -05001799 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001800 if (!texture || texture->id() == 0)
1801 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001802 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001803 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001804 }
1805
Geoff Lang69cce582015-09-17 13:20:36 -04001806 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001807 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001808 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001809 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001810 }
1811
1812 return true;
1813}
1814
He Yunchaoced53ae2016-11-29 15:00:51 +08001815bool ValidateDiscardFramebufferEXT(Context *context,
1816 GLenum target,
1817 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001818 const GLenum *attachments)
1819{
Jamie Madillc29968b2016-01-20 11:17:23 -05001820 if (!context->getExtensions().discardFramebuffer)
1821 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001822 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001823 return false;
1824 }
1825
Austin Kinross08332632015-05-05 13:35:47 -07001826 bool defaultFramebuffer = false;
1827
1828 switch (target)
1829 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001830 case GL_FRAMEBUFFER:
1831 defaultFramebuffer =
1832 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1833 break;
1834 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001835 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001836 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001837 }
1838
He Yunchaoced53ae2016-11-29 15:00:51 +08001839 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1840 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001841}
1842
Austin Kinrossbc781f32015-10-26 09:27:38 -07001843bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1844{
1845 if (!context->getExtensions().vertexArrayObject)
1846 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001847 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001848 return false;
1849 }
1850
1851 return ValidateBindVertexArrayBase(context, array);
1852}
1853
Jamie Madilld7576732017-08-26 18:49:50 -04001854bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001855{
1856 if (!context->getExtensions().vertexArrayObject)
1857 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001858 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001859 return false;
1860 }
1861
Olli Etuaho41997e72016-03-10 13:38:39 +02001862 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001863}
1864
Jamie Madilld7576732017-08-26 18:49:50 -04001865bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001866{
1867 if (!context->getExtensions().vertexArrayObject)
1868 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001869 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870 return false;
1871 }
1872
Olli Etuaho41997e72016-03-10 13:38:39 +02001873 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001874}
1875
Jamie Madilld7576732017-08-26 18:49:50 -04001876bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001877{
1878 if (!context->getExtensions().vertexArrayObject)
1879 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001880 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001881 return false;
1882 }
1883
1884 return true;
1885}
Geoff Langc5629752015-12-07 16:29:04 -05001886
1887bool ValidateProgramBinaryOES(Context *context,
1888 GLuint program,
1889 GLenum binaryFormat,
1890 const void *binary,
1891 GLint length)
1892{
1893 if (!context->getExtensions().getProgramBinary)
1894 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001895 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001896 return false;
1897 }
1898
1899 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1900}
1901
1902bool ValidateGetProgramBinaryOES(Context *context,
1903 GLuint program,
1904 GLsizei bufSize,
1905 GLsizei *length,
1906 GLenum *binaryFormat,
1907 void *binary)
1908{
1909 if (!context->getExtensions().getProgramBinary)
1910 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001911 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001912 return false;
1913 }
1914
1915 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1916}
Geoff Lange102fee2015-12-10 11:23:30 -05001917
Geoff Lang70d0f492015-12-10 17:45:46 -05001918static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1919{
1920 switch (source)
1921 {
1922 case GL_DEBUG_SOURCE_API:
1923 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1924 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1925 case GL_DEBUG_SOURCE_OTHER:
1926 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1927 return !mustBeThirdPartyOrApplication;
1928
1929 case GL_DEBUG_SOURCE_THIRD_PARTY:
1930 case GL_DEBUG_SOURCE_APPLICATION:
1931 return true;
1932
1933 default:
1934 return false;
1935 }
1936}
1937
1938static bool ValidDebugType(GLenum type)
1939{
1940 switch (type)
1941 {
1942 case GL_DEBUG_TYPE_ERROR:
1943 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1944 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1945 case GL_DEBUG_TYPE_PERFORMANCE:
1946 case GL_DEBUG_TYPE_PORTABILITY:
1947 case GL_DEBUG_TYPE_OTHER:
1948 case GL_DEBUG_TYPE_MARKER:
1949 case GL_DEBUG_TYPE_PUSH_GROUP:
1950 case GL_DEBUG_TYPE_POP_GROUP:
1951 return true;
1952
1953 default:
1954 return false;
1955 }
1956}
1957
1958static bool ValidDebugSeverity(GLenum severity)
1959{
1960 switch (severity)
1961 {
1962 case GL_DEBUG_SEVERITY_HIGH:
1963 case GL_DEBUG_SEVERITY_MEDIUM:
1964 case GL_DEBUG_SEVERITY_LOW:
1965 case GL_DEBUG_SEVERITY_NOTIFICATION:
1966 return true;
1967
1968 default:
1969 return false;
1970 }
1971}
1972
Geoff Lange102fee2015-12-10 11:23:30 -05001973bool ValidateDebugMessageControlKHR(Context *context,
1974 GLenum source,
1975 GLenum type,
1976 GLenum severity,
1977 GLsizei count,
1978 const GLuint *ids,
1979 GLboolean enabled)
1980{
1981 if (!context->getExtensions().debug)
1982 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001983 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001984 return false;
1985 }
1986
Geoff Lang70d0f492015-12-10 17:45:46 -05001987 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1988 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001989 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001990 return false;
1991 }
1992
1993 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1994 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001995 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001996 return false;
1997 }
1998
1999 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2000 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002001 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002002 return false;
2003 }
2004
2005 if (count > 0)
2006 {
2007 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2008 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002009 context->handleError(
2010 InvalidOperation()
2011 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002012 return false;
2013 }
2014
2015 if (severity != GL_DONT_CARE)
2016 {
Jamie Madill437fa652016-05-03 15:13:24 -04002017 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002018 InvalidOperation()
2019 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002020 return false;
2021 }
2022 }
2023
Geoff Lange102fee2015-12-10 11:23:30 -05002024 return true;
2025}
2026
2027bool ValidateDebugMessageInsertKHR(Context *context,
2028 GLenum source,
2029 GLenum type,
2030 GLuint id,
2031 GLenum severity,
2032 GLsizei length,
2033 const GLchar *buf)
2034{
2035 if (!context->getExtensions().debug)
2036 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002037 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002038 return false;
2039 }
2040
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002041 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002042 {
2043 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2044 // not generate an error.
2045 return false;
2046 }
2047
2048 if (!ValidDebugSeverity(severity))
2049 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002051 return false;
2052 }
2053
2054 if (!ValidDebugType(type))
2055 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002056 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002057 return false;
2058 }
2059
2060 if (!ValidDebugSource(source, true))
2061 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002062 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002063 return false;
2064 }
2065
2066 size_t messageLength = (length < 0) ? strlen(buf) : length;
2067 if (messageLength > context->getExtensions().maxDebugMessageLength)
2068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002069 context->handleError(InvalidValue()
2070 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002071 return false;
2072 }
2073
Geoff Lange102fee2015-12-10 11:23:30 -05002074 return true;
2075}
2076
2077bool ValidateDebugMessageCallbackKHR(Context *context,
2078 GLDEBUGPROCKHR callback,
2079 const void *userParam)
2080{
2081 if (!context->getExtensions().debug)
2082 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002083 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002084 return false;
2085 }
2086
Geoff Lange102fee2015-12-10 11:23:30 -05002087 return true;
2088}
2089
2090bool ValidateGetDebugMessageLogKHR(Context *context,
2091 GLuint count,
2092 GLsizei bufSize,
2093 GLenum *sources,
2094 GLenum *types,
2095 GLuint *ids,
2096 GLenum *severities,
2097 GLsizei *lengths,
2098 GLchar *messageLog)
2099{
2100 if (!context->getExtensions().debug)
2101 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002102 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002103 return false;
2104 }
2105
Geoff Lang70d0f492015-12-10 17:45:46 -05002106 if (bufSize < 0 && messageLog != nullptr)
2107 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002108 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002109 return false;
2110 }
2111
Geoff Lange102fee2015-12-10 11:23:30 -05002112 return true;
2113}
2114
2115bool ValidatePushDebugGroupKHR(Context *context,
2116 GLenum source,
2117 GLuint id,
2118 GLsizei length,
2119 const GLchar *message)
2120{
2121 if (!context->getExtensions().debug)
2122 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002123 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002124 return false;
2125 }
2126
Geoff Lang70d0f492015-12-10 17:45:46 -05002127 if (!ValidDebugSource(source, true))
2128 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002129 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002130 return false;
2131 }
2132
2133 size_t messageLength = (length < 0) ? strlen(message) : length;
2134 if (messageLength > context->getExtensions().maxDebugMessageLength)
2135 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002136 context->handleError(InvalidValue()
2137 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002138 return false;
2139 }
2140
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002141 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002142 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2143 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002144 context
2145 ->handleError(StackOverflow()
2146 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002147 return false;
2148 }
2149
Geoff Lange102fee2015-12-10 11:23:30 -05002150 return true;
2151}
2152
2153bool ValidatePopDebugGroupKHR(Context *context)
2154{
2155 if (!context->getExtensions().debug)
2156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002158 return false;
2159 }
2160
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002161 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002162 if (currentStackSize <= 1)
2163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002164 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002165 return false;
2166 }
2167
2168 return true;
2169}
2170
2171static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2172{
2173 switch (identifier)
2174 {
2175 case GL_BUFFER:
2176 if (context->getBuffer(name) == nullptr)
2177 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002178 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002179 return false;
2180 }
2181 return true;
2182
2183 case GL_SHADER:
2184 if (context->getShader(name) == nullptr)
2185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002186 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002187 return false;
2188 }
2189 return true;
2190
2191 case GL_PROGRAM:
2192 if (context->getProgram(name) == nullptr)
2193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002194 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002195 return false;
2196 }
2197 return true;
2198
2199 case GL_VERTEX_ARRAY:
2200 if (context->getVertexArray(name) == nullptr)
2201 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002202 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002203 return false;
2204 }
2205 return true;
2206
2207 case GL_QUERY:
2208 if (context->getQuery(name) == nullptr)
2209 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002210 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002211 return false;
2212 }
2213 return true;
2214
2215 case GL_TRANSFORM_FEEDBACK:
2216 if (context->getTransformFeedback(name) == nullptr)
2217 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002218 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002219 return false;
2220 }
2221 return true;
2222
2223 case GL_SAMPLER:
2224 if (context->getSampler(name) == nullptr)
2225 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002226 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002227 return false;
2228 }
2229 return true;
2230
2231 case GL_TEXTURE:
2232 if (context->getTexture(name) == nullptr)
2233 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002234 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002235 return false;
2236 }
2237 return true;
2238
2239 case GL_RENDERBUFFER:
2240 if (context->getRenderbuffer(name) == nullptr)
2241 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002242 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002243 return false;
2244 }
2245 return true;
2246
2247 case GL_FRAMEBUFFER:
2248 if (context->getFramebuffer(name) == nullptr)
2249 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002250 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002251 return false;
2252 }
2253 return true;
2254
2255 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002256 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002257 return false;
2258 }
Geoff Lange102fee2015-12-10 11:23:30 -05002259}
2260
Martin Radev9d901792016-07-15 15:58:58 +03002261static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2262{
2263 size_t labelLength = 0;
2264
2265 if (length < 0)
2266 {
2267 if (label != nullptr)
2268 {
2269 labelLength = strlen(label);
2270 }
2271 }
2272 else
2273 {
2274 labelLength = static_cast<size_t>(length);
2275 }
2276
2277 if (labelLength > context->getExtensions().maxLabelLength)
2278 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002279 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002280 return false;
2281 }
2282
2283 return true;
2284}
2285
Geoff Lange102fee2015-12-10 11:23:30 -05002286bool ValidateObjectLabelKHR(Context *context,
2287 GLenum identifier,
2288 GLuint name,
2289 GLsizei length,
2290 const GLchar *label)
2291{
2292 if (!context->getExtensions().debug)
2293 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002294 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002295 return false;
2296 }
2297
Geoff Lang70d0f492015-12-10 17:45:46 -05002298 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2299 {
2300 return false;
2301 }
2302
Martin Radev9d901792016-07-15 15:58:58 +03002303 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002304 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002305 return false;
2306 }
2307
Geoff Lange102fee2015-12-10 11:23:30 -05002308 return true;
2309}
2310
2311bool ValidateGetObjectLabelKHR(Context *context,
2312 GLenum identifier,
2313 GLuint name,
2314 GLsizei bufSize,
2315 GLsizei *length,
2316 GLchar *label)
2317{
2318 if (!context->getExtensions().debug)
2319 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002320 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002321 return false;
2322 }
2323
Geoff Lang70d0f492015-12-10 17:45:46 -05002324 if (bufSize < 0)
2325 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002326 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002327 return false;
2328 }
2329
2330 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2331 {
2332 return false;
2333 }
2334
Martin Radev9d901792016-07-15 15:58:58 +03002335 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002336}
2337
2338static bool ValidateObjectPtrName(Context *context, const void *ptr)
2339{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002340 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002341 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002342 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002343 return false;
2344 }
2345
Geoff Lange102fee2015-12-10 11:23:30 -05002346 return true;
2347}
2348
2349bool ValidateObjectPtrLabelKHR(Context *context,
2350 const void *ptr,
2351 GLsizei length,
2352 const GLchar *label)
2353{
2354 if (!context->getExtensions().debug)
2355 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002356 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002357 return false;
2358 }
2359
Geoff Lang70d0f492015-12-10 17:45:46 -05002360 if (!ValidateObjectPtrName(context, ptr))
2361 {
2362 return false;
2363 }
2364
Martin Radev9d901792016-07-15 15:58:58 +03002365 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002366 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002367 return false;
2368 }
2369
Geoff Lange102fee2015-12-10 11:23:30 -05002370 return true;
2371}
2372
2373bool ValidateGetObjectPtrLabelKHR(Context *context,
2374 const void *ptr,
2375 GLsizei bufSize,
2376 GLsizei *length,
2377 GLchar *label)
2378{
2379 if (!context->getExtensions().debug)
2380 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002382 return false;
2383 }
2384
Geoff Lang70d0f492015-12-10 17:45:46 -05002385 if (bufSize < 0)
2386 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002387 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002388 return false;
2389 }
2390
2391 if (!ValidateObjectPtrName(context, ptr))
2392 {
2393 return false;
2394 }
2395
Martin Radev9d901792016-07-15 15:58:58 +03002396 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002397}
2398
2399bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2400{
2401 if (!context->getExtensions().debug)
2402 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002403 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002404 return false;
2405 }
2406
Geoff Lang70d0f492015-12-10 17:45:46 -05002407 // TODO: represent this in Context::getQueryParameterInfo.
2408 switch (pname)
2409 {
2410 case GL_DEBUG_CALLBACK_FUNCTION:
2411 case GL_DEBUG_CALLBACK_USER_PARAM:
2412 break;
2413
2414 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002415 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002416 return false;
2417 }
2418
Geoff Lange102fee2015-12-10 11:23:30 -05002419 return true;
2420}
Jamie Madillc29968b2016-01-20 11:17:23 -05002421
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002422bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2423 GLenum pname,
2424 GLsizei bufSize,
2425 GLsizei *length,
2426 void **params)
2427{
2428 UNIMPLEMENTED();
2429 return false;
2430}
2431
Jamie Madillc29968b2016-01-20 11:17:23 -05002432bool ValidateBlitFramebufferANGLE(Context *context,
2433 GLint srcX0,
2434 GLint srcY0,
2435 GLint srcX1,
2436 GLint srcY1,
2437 GLint dstX0,
2438 GLint dstY0,
2439 GLint dstX1,
2440 GLint dstY1,
2441 GLbitfield mask,
2442 GLenum filter)
2443{
2444 if (!context->getExtensions().framebufferBlit)
2445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002446 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002447 return false;
2448 }
2449
2450 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2451 {
2452 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002453 context->handleError(InvalidOperation() << "Scaling and flipping in "
2454 "BlitFramebufferANGLE not supported by this "
2455 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002456 return false;
2457 }
2458
2459 if (filter == GL_LINEAR)
2460 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002461 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002462 return false;
2463 }
2464
Jamie Madill51f40ec2016-06-15 14:06:00 -04002465 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2466 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002467
2468 if (mask & GL_COLOR_BUFFER_BIT)
2469 {
2470 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2471 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2472
2473 if (readColorAttachment && drawColorAttachment)
2474 {
2475 if (!(readColorAttachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002476 readColorAttachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002477 readColorAttachment->type() != GL_RENDERBUFFER &&
2478 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002480 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002481 return false;
2482 }
2483
Geoff Langa15472a2015-08-11 11:48:03 -04002484 for (size_t drawbufferIdx = 0;
2485 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002486 {
Geoff Langa15472a2015-08-11 11:48:03 -04002487 const FramebufferAttachment *attachment =
2488 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2489 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002490 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 if (!(attachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002492 attachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002493 attachment->type() != GL_RENDERBUFFER &&
2494 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2495 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002496 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002497 return false;
2498 }
2499
2500 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002501 if (!Format::EquivalentForBlit(attachment->getFormat(),
2502 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002503 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002504 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002505 return false;
2506 }
2507 }
2508 }
2509
Jamie Madille98b1b52018-03-08 09:47:23 -05002510 GLint samples = 0;
2511 ANGLE_VALIDATION_TRY(readFramebuffer->getSamples(context, &samples));
2512 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002513 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2514 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2515 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002516 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002517 return false;
2518 }
2519 }
2520 }
2521
2522 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2523 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2524 for (size_t i = 0; i < 2; i++)
2525 {
2526 if (mask & masks[i])
2527 {
2528 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002529 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002530 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002531 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002532
2533 if (readBuffer && drawBuffer)
2534 {
2535 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2536 dstX0, dstY0, dstX1, dstY1))
2537 {
2538 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002539 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2540 "stencil blits are supported by "
2541 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002542 return false;
2543 }
2544
2545 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2546 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002547 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002548 return false;
2549 }
2550 }
2551 }
2552 }
2553
2554 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2555 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002556}
Jamie Madillc29968b2016-01-20 11:17:23 -05002557
Jamie Madill5b772312018-03-08 20:28:32 -05002558bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002559{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002560 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002561
2562 if (!ValidateFramebufferComplete(context, fbo, true))
Jamie Madillc29968b2016-01-20 11:17:23 -05002563 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002564 return false;
2565 }
2566
2567 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2568 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002569 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002570 return false;
2571 }
2572
Geoff Lang76e65652017-03-27 14:58:02 -04002573 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2574 {
2575 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2576 GL_SIGNED_NORMALIZED};
2577
Corentin Wallez59c41592017-07-11 13:19:54 -04002578 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002579 drawBufferIdx++)
2580 {
2581 if (!ValidateWebGLFramebufferAttachmentClearType(
2582 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2583 {
2584 return false;
2585 }
2586 }
2587 }
2588
Jamie Madillc29968b2016-01-20 11:17:23 -05002589 return true;
2590}
2591
Jamie Madill5b772312018-03-08 20:28:32 -05002592bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002593{
2594 if (!context->getExtensions().drawBuffers)
2595 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002596 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002597 return false;
2598 }
2599
2600 return ValidateDrawBuffersBase(context, n, bufs);
2601}
2602
Jamie Madill73a84962016-02-12 09:27:23 -05002603bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002604 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002605 GLint level,
2606 GLint internalformat,
2607 GLsizei width,
2608 GLsizei height,
2609 GLint border,
2610 GLenum format,
2611 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002612 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002613{
Martin Radev1be913c2016-07-11 17:59:16 +03002614 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002615 {
2616 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002617 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002618 }
2619
Martin Radev1be913c2016-07-11 17:59:16 +03002620 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002621 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002622 0, 0, width, height, 1, border, format, type, -1,
2623 pixels);
2624}
2625
2626bool ValidateTexImage2DRobust(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002627 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04002628 GLint level,
2629 GLint internalformat,
2630 GLsizei width,
2631 GLsizei height,
2632 GLint border,
2633 GLenum format,
2634 GLenum type,
2635 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002636 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002637{
2638 if (!ValidateRobustEntryPoint(context, bufSize))
2639 {
2640 return false;
2641 }
2642
2643 if (context->getClientMajorVersion() < 3)
2644 {
2645 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2646 0, 0, width, height, border, format, type, bufSize,
2647 pixels);
2648 }
2649
2650 ASSERT(context->getClientMajorVersion() >= 3);
2651 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2652 0, 0, width, height, 1, border, format, type, bufSize,
2653 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002654}
2655
2656bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002657 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002658 GLint level,
2659 GLint xoffset,
2660 GLint yoffset,
2661 GLsizei width,
2662 GLsizei height,
2663 GLenum format,
2664 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002665 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002666{
2667
Martin Radev1be913c2016-07-11 17:59:16 +03002668 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002669 {
2670 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002671 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002672 }
2673
Martin Radev1be913c2016-07-11 17:59:16 +03002674 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002675 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002676 yoffset, 0, width, height, 1, 0, format, type, -1,
2677 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002678}
2679
Geoff Langc52f6f12016-10-14 10:18:00 -04002680bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002681 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002682 GLint level,
2683 GLint xoffset,
2684 GLint yoffset,
2685 GLsizei width,
2686 GLsizei height,
2687 GLenum format,
2688 GLenum type,
2689 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002690 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002691{
2692 if (!ValidateRobustEntryPoint(context, bufSize))
2693 {
2694 return false;
2695 }
2696
2697 if (context->getClientMajorVersion() < 3)
2698 {
2699 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2700 yoffset, width, height, 0, format, type, bufSize,
2701 pixels);
2702 }
2703
2704 ASSERT(context->getClientMajorVersion() >= 3);
2705 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2706 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2707 pixels);
2708}
2709
Jamie Madill73a84962016-02-12 09:27:23 -05002710bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002711 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002712 GLint level,
2713 GLenum internalformat,
2714 GLsizei width,
2715 GLsizei height,
2716 GLint border,
2717 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002718 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002719{
Martin Radev1be913c2016-07-11 17:59:16 +03002720 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002721 {
2722 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002723 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002724 {
2725 return false;
2726 }
2727 }
2728 else
2729 {
Martin Radev1be913c2016-07-11 17:59:16 +03002730 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002731 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002732 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002733 data))
2734 {
2735 return false;
2736 }
2737 }
2738
Geoff Langca271392017-04-05 12:30:00 -04002739 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002740 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002741 if (blockSizeOrErr.isError())
2742 {
2743 context->handleError(blockSizeOrErr.getError());
2744 return false;
2745 }
2746
2747 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002748 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002749 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002750 return false;
2751 }
2752
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002753 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002754 {
2755 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2756 return false;
2757 }
2758
Jamie Madill73a84962016-02-12 09:27:23 -05002759 return true;
2760}
2761
Corentin Wallezb2931602017-04-11 15:58:57 -04002762bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002763 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002764 GLint level,
2765 GLenum internalformat,
2766 GLsizei width,
2767 GLsizei height,
2768 GLint border,
2769 GLsizei imageSize,
2770 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002771 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002772{
2773 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2774 {
2775 return false;
2776 }
2777
2778 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2779 border, imageSize, data);
2780}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002781
Corentin Wallezb2931602017-04-11 15:58:57 -04002782bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002783 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002784 GLint level,
2785 GLint xoffset,
2786 GLint yoffset,
2787 GLsizei width,
2788 GLsizei height,
2789 GLenum format,
2790 GLsizei imageSize,
2791 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002792 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002793{
2794 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2795 {
2796 return false;
2797 }
2798
2799 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2800 format, imageSize, data);
2801}
2802
Jamie Madill73a84962016-02-12 09:27:23 -05002803bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002804 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002805 GLint level,
2806 GLint xoffset,
2807 GLint yoffset,
2808 GLsizei width,
2809 GLsizei height,
2810 GLenum format,
2811 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002812 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002813{
Martin Radev1be913c2016-07-11 17:59:16 +03002814 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002815 {
2816 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002817 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002818 {
2819 return false;
2820 }
2821 }
2822 else
2823 {
Martin Radev1be913c2016-07-11 17:59:16 +03002824 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002825 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002826 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002827 data))
2828 {
2829 return false;
2830 }
2831 }
2832
Geoff Langca271392017-04-05 12:30:00 -04002833 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002834 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002835 if (blockSizeOrErr.isError())
2836 {
2837 context->handleError(blockSizeOrErr.getError());
2838 return false;
2839 }
2840
2841 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002842 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002843 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002844 return false;
2845 }
2846
2847 return true;
2848}
2849
Corentin Wallez336129f2017-10-17 15:55:40 -04002850bool ValidateGetBufferPointervOES(Context *context,
2851 BufferBinding target,
2852 GLenum pname,
2853 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002854{
Geoff Lang496c02d2016-10-20 11:38:11 -07002855 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002856}
2857
Corentin Wallez336129f2017-10-17 15:55:40 -04002858bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002859{
2860 if (!context->getExtensions().mapBuffer)
2861 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002862 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002863 return false;
2864 }
2865
Corentin Walleze4477002017-12-01 14:39:58 -05002866 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002867 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002868 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002869 return false;
2870 }
2871
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002872 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002873
2874 if (buffer == nullptr)
2875 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002876 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002877 return false;
2878 }
2879
2880 if (access != GL_WRITE_ONLY_OES)
2881 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002882 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002883 return false;
2884 }
2885
2886 if (buffer->isMapped())
2887 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002888 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002889 return false;
2890 }
2891
Geoff Lang79f71042017-08-14 16:43:43 -04002892 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002893}
2894
Corentin Wallez336129f2017-10-17 15:55:40 -04002895bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002896{
2897 if (!context->getExtensions().mapBuffer)
2898 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002899 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002900 return false;
2901 }
2902
2903 return ValidateUnmapBufferBase(context, target);
2904}
2905
2906bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002907 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002908 GLintptr offset,
2909 GLsizeiptr length,
2910 GLbitfield access)
2911{
2912 if (!context->getExtensions().mapBufferRange)
2913 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002914 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002915 return false;
2916 }
2917
2918 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2919}
2920
Corentin Wallez336129f2017-10-17 15:55:40 -04002921bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002922{
2923 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2924 ASSERT(buffer != nullptr);
2925
2926 // Check if this buffer is currently being used as a transform feedback output buffer
2927 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2928 if (transformFeedback != nullptr && transformFeedback->isActive())
2929 {
2930 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2931 {
2932 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2933 if (transformFeedbackBuffer.get() == buffer)
2934 {
2935 context->handleError(InvalidOperation()
2936 << "Buffer is currently bound for transform feedback.");
2937 return false;
2938 }
2939 }
2940 }
2941
James Darpiniane8a93c62018-01-04 18:02:24 -08002942 if (context->getExtensions().webglCompatibility &&
2943 buffer->isBoundForTransformFeedbackAndOtherUse())
2944 {
2945 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
2946 return false;
2947 }
2948
Geoff Lang79f71042017-08-14 16:43:43 -04002949 return true;
2950}
2951
Olli Etuaho4f667482016-03-30 15:56:35 +03002952bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002953 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002954 GLintptr offset,
2955 GLsizeiptr length)
2956{
2957 if (!context->getExtensions().mapBufferRange)
2958 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002959 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002960 return false;
2961 }
2962
2963 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2964}
2965
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002966bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002967{
2968 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002969 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002970 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002971 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002972 return false;
2973 }
2974
Geoff Langf41a7152016-09-19 15:11:17 -04002975 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2976 !context->isTextureGenerated(texture))
2977 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002978 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002979 return false;
2980 }
2981
Ian Ewell54f87462016-03-10 13:47:21 -05002982 switch (target)
2983 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002984 case TextureType::_2D:
2985 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002986 break;
2987
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002988 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002989 if (!context->getExtensions().textureRectangle)
2990 {
2991 context->handleError(InvalidEnum()
2992 << "Context does not support GL_ANGLE_texture_rectangle");
2993 return false;
2994 }
2995 break;
2996
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002997 case TextureType::_3D:
2998 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002999 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003000 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003001 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003002 return false;
3003 }
3004 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003005
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003006 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003007 if (context->getClientVersion() < Version(3, 1))
3008 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003009 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003010 return false;
3011 }
Geoff Lang3b573612016-10-31 14:08:10 -04003012 break;
3013
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003014 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003015 if (!context->getExtensions().eglImageExternal &&
3016 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003017 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003018 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003019 return false;
3020 }
3021 break;
3022 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003023 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003024 return false;
3025 }
3026
3027 return true;
3028}
3029
Geoff Langd8605522016-04-13 10:19:12 -04003030bool ValidateBindUniformLocationCHROMIUM(Context *context,
3031 GLuint program,
3032 GLint location,
3033 const GLchar *name)
3034{
3035 if (!context->getExtensions().bindUniformLocation)
3036 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003037 context->handleError(InvalidOperation()
3038 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003039 return false;
3040 }
3041
3042 Program *programObject = GetValidProgram(context, program);
3043 if (!programObject)
3044 {
3045 return false;
3046 }
3047
3048 if (location < 0)
3049 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003050 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003051 return false;
3052 }
3053
3054 const Caps &caps = context->getCaps();
3055 if (static_cast<size_t>(location) >=
3056 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003058 context->handleError(InvalidValue() << "Location must be less than "
3059 "(MAX_VERTEX_UNIFORM_VECTORS + "
3060 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003061 return false;
3062 }
3063
Geoff Langfc32e8b2017-05-31 14:16:59 -04003064 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3065 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003066 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003067 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003068 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003069 return false;
3070 }
3071
Geoff Langd8605522016-04-13 10:19:12 -04003072 if (strncmp(name, "gl_", 3) == 0)
3073 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003074 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003075 return false;
3076 }
3077
3078 return true;
3079}
3080
Jamie Madille2e406c2016-06-02 13:04:10 -04003081bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003082{
3083 if (!context->getExtensions().framebufferMixedSamples)
3084 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003085 context->handleError(InvalidOperation()
3086 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003087 return false;
3088 }
3089 switch (components)
3090 {
3091 case GL_RGB:
3092 case GL_RGBA:
3093 case GL_ALPHA:
3094 case GL_NONE:
3095 break;
3096 default:
3097 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003098 InvalidEnum()
3099 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003100 return false;
3101 }
3102
3103 return true;
3104}
3105
Sami Väisänene45e53b2016-05-25 10:36:04 +03003106// CHROMIUM_path_rendering
3107
Jamie Madill007530e2017-12-28 14:27:04 -05003108bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003109{
Jamie Madill007530e2017-12-28 14:27:04 -05003110 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003112 return false;
3113 }
Jamie Madill007530e2017-12-28 14:27:04 -05003114
Sami Väisänene45e53b2016-05-25 10:36:04 +03003115 if (matrix == nullptr)
3116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003117 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003118 return false;
3119 }
Jamie Madill007530e2017-12-28 14:27:04 -05003120
Sami Väisänene45e53b2016-05-25 10:36:04 +03003121 return true;
3122}
3123
Jamie Madill007530e2017-12-28 14:27:04 -05003124bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003125{
Jamie Madill007530e2017-12-28 14:27:04 -05003126 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003127}
3128
Jamie Madill007530e2017-12-28 14:27:04 -05003129bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003130{
3131 if (!context->getExtensions().pathRendering)
3132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003133 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003134 return false;
3135 }
3136
3137 // range = 0 is undefined in NV_path_rendering.
3138 // we add stricter semantic check here and require a non zero positive range.
3139 if (range <= 0)
3140 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003141 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003142 return false;
3143 }
3144
3145 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3146 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003147 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003148 return false;
3149 }
3150
3151 return true;
3152}
3153
Jamie Madill007530e2017-12-28 14:27:04 -05003154bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003155{
3156 if (!context->getExtensions().pathRendering)
3157 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003158 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003159 return false;
3160 }
3161
3162 // range = 0 is undefined in NV_path_rendering.
3163 // we add stricter semantic check here and require a non zero positive range.
3164 if (range <= 0)
3165 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003166 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003167 return false;
3168 }
3169
3170 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3171 checkedRange += range;
3172
3173 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3174 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003175 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003176 return false;
3177 }
3178 return true;
3179}
3180
Jamie Madill007530e2017-12-28 14:27:04 -05003181bool ValidatePathCommandsCHROMIUM(Context *context,
3182 GLuint path,
3183 GLsizei numCommands,
3184 const GLubyte *commands,
3185 GLsizei numCoords,
3186 GLenum coordType,
3187 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003188{
3189 if (!context->getExtensions().pathRendering)
3190 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003191 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003192 return false;
3193 }
Brandon Jones59770802018-04-02 13:18:42 -07003194 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003195 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003196 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003197 return false;
3198 }
3199
3200 if (numCommands < 0)
3201 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003202 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003203 return false;
3204 }
3205 else if (numCommands > 0)
3206 {
3207 if (!commands)
3208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003209 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003210 return false;
3211 }
3212 }
3213
3214 if (numCoords < 0)
3215 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003216 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003217 return false;
3218 }
3219 else if (numCoords > 0)
3220 {
3221 if (!coords)
3222 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003223 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003224 return false;
3225 }
3226 }
3227
3228 std::uint32_t coordTypeSize = 0;
3229 switch (coordType)
3230 {
3231 case GL_BYTE:
3232 coordTypeSize = sizeof(GLbyte);
3233 break;
3234
3235 case GL_UNSIGNED_BYTE:
3236 coordTypeSize = sizeof(GLubyte);
3237 break;
3238
3239 case GL_SHORT:
3240 coordTypeSize = sizeof(GLshort);
3241 break;
3242
3243 case GL_UNSIGNED_SHORT:
3244 coordTypeSize = sizeof(GLushort);
3245 break;
3246
3247 case GL_FLOAT:
3248 coordTypeSize = sizeof(GLfloat);
3249 break;
3250
3251 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003252 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003253 return false;
3254 }
3255
3256 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3257 checkedSize += (coordTypeSize * numCoords);
3258 if (!checkedSize.IsValid())
3259 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003260 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003261 return false;
3262 }
3263
3264 // early return skips command data validation when it doesn't exist.
3265 if (!commands)
3266 return true;
3267
3268 GLsizei expectedNumCoords = 0;
3269 for (GLsizei i = 0; i < numCommands; ++i)
3270 {
3271 switch (commands[i])
3272 {
3273 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3274 break;
3275 case GL_MOVE_TO_CHROMIUM:
3276 case GL_LINE_TO_CHROMIUM:
3277 expectedNumCoords += 2;
3278 break;
3279 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3280 expectedNumCoords += 4;
3281 break;
3282 case GL_CUBIC_CURVE_TO_CHROMIUM:
3283 expectedNumCoords += 6;
3284 break;
3285 case GL_CONIC_CURVE_TO_CHROMIUM:
3286 expectedNumCoords += 5;
3287 break;
3288 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003289 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003290 return false;
3291 }
3292 }
3293 if (expectedNumCoords != numCoords)
3294 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003295 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003296 return false;
3297 }
3298
3299 return true;
3300}
3301
Jamie Madill007530e2017-12-28 14:27:04 -05003302bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003303{
3304 if (!context->getExtensions().pathRendering)
3305 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003306 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003307 return false;
3308 }
Brandon Jones59770802018-04-02 13:18:42 -07003309 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003310 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003311 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003312 return false;
3313 }
3314
3315 switch (pname)
3316 {
3317 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3318 if (value < 0.0f)
3319 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003320 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003321 return false;
3322 }
3323 break;
3324 case GL_PATH_END_CAPS_CHROMIUM:
3325 switch (static_cast<GLenum>(value))
3326 {
3327 case GL_FLAT_CHROMIUM:
3328 case GL_SQUARE_CHROMIUM:
3329 case GL_ROUND_CHROMIUM:
3330 break;
3331 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003332 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003333 return false;
3334 }
3335 break;
3336 case GL_PATH_JOIN_STYLE_CHROMIUM:
3337 switch (static_cast<GLenum>(value))
3338 {
3339 case GL_MITER_REVERT_CHROMIUM:
3340 case GL_BEVEL_CHROMIUM:
3341 case GL_ROUND_CHROMIUM:
3342 break;
3343 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003344 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003345 return false;
3346 }
Nico Weber41b072b2018-02-09 10:01:32 -05003347 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003348 case GL_PATH_MITER_LIMIT_CHROMIUM:
3349 if (value < 0.0f)
3350 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003351 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003352 return false;
3353 }
3354 break;
3355
3356 case GL_PATH_STROKE_BOUND_CHROMIUM:
3357 // no errors, only clamping.
3358 break;
3359
3360 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003361 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003362 return false;
3363 }
3364 return true;
3365}
3366
Jamie Madill007530e2017-12-28 14:27:04 -05003367bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3368{
3369 // TODO(jmadill): Use proper clamping cast.
3370 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3371}
3372
3373bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003374{
3375 if (!context->getExtensions().pathRendering)
3376 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003377 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003378 return false;
3379 }
3380
Brandon Jones59770802018-04-02 13:18:42 -07003381 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003382 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003383 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003384 return false;
3385 }
3386 if (!value)
3387 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003388 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003389 return false;
3390 }
3391
3392 switch (pname)
3393 {
3394 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3395 case GL_PATH_END_CAPS_CHROMIUM:
3396 case GL_PATH_JOIN_STYLE_CHROMIUM:
3397 case GL_PATH_MITER_LIMIT_CHROMIUM:
3398 case GL_PATH_STROKE_BOUND_CHROMIUM:
3399 break;
3400
3401 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003402 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003403 return false;
3404 }
3405
3406 return true;
3407}
3408
Jamie Madill007530e2017-12-28 14:27:04 -05003409bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3410{
3411 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3412 reinterpret_cast<GLfloat *>(value));
3413}
3414
3415bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003416{
3417 if (!context->getExtensions().pathRendering)
3418 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003419 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003420 return false;
3421 }
3422
3423 switch (func)
3424 {
3425 case GL_NEVER:
3426 case GL_ALWAYS:
3427 case GL_LESS:
3428 case GL_LEQUAL:
3429 case GL_EQUAL:
3430 case GL_GEQUAL:
3431 case GL_GREATER:
3432 case GL_NOTEQUAL:
3433 break;
3434 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003435 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003436 return false;
3437 }
3438
3439 return true;
3440}
3441
3442// Note that the spec specifies that for the path drawing commands
3443// if the path object is not an existing path object the command
3444// does nothing and no error is generated.
3445// However if the path object exists but has not been specified any
3446// commands then an error is generated.
3447
Jamie Madill007530e2017-12-28 14:27:04 -05003448bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003449{
3450 if (!context->getExtensions().pathRendering)
3451 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003452 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003453 return false;
3454 }
Brandon Jones59770802018-04-02 13:18:42 -07003455 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003456 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003457 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458 return false;
3459 }
3460
3461 switch (fillMode)
3462 {
3463 case GL_COUNT_UP_CHROMIUM:
3464 case GL_COUNT_DOWN_CHROMIUM:
3465 break;
3466 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003467 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003468 return false;
3469 }
3470
3471 if (!isPow2(mask + 1))
3472 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003473 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474 return false;
3475 }
3476
3477 return true;
3478}
3479
Jamie Madill007530e2017-12-28 14:27:04 -05003480bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003481{
3482 if (!context->getExtensions().pathRendering)
3483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003484 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003485 return false;
3486 }
Brandon Jones59770802018-04-02 13:18:42 -07003487 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003488 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003489 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003490 return false;
3491 }
3492
3493 return true;
3494}
3495
Brandon Jonesd1049182018-03-28 10:02:20 -07003496bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3497{
3498 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3499}
3500
3501bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3502{
3503 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3504}
3505
Jamie Madill007530e2017-12-28 14:27:04 -05003506bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003507{
3508 if (!context->getExtensions().pathRendering)
3509 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003510 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003511 return false;
3512 }
Brandon Jones59770802018-04-02 13:18:42 -07003513 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003514 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003515 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003516 return false;
3517 }
3518
3519 switch (coverMode)
3520 {
3521 case GL_CONVEX_HULL_CHROMIUM:
3522 case GL_BOUNDING_BOX_CHROMIUM:
3523 break;
3524 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003525 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003526 return false;
3527 }
3528 return true;
3529}
3530
Jamie Madill007530e2017-12-28 14:27:04 -05003531bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3532 GLuint path,
3533 GLenum fillMode,
3534 GLuint mask,
3535 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003536{
Jamie Madill007530e2017-12-28 14:27:04 -05003537 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3538 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003539}
3540
Jamie Madill007530e2017-12-28 14:27:04 -05003541bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3542 GLuint path,
3543 GLint reference,
3544 GLuint mask,
3545 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546{
Jamie Madill007530e2017-12-28 14:27:04 -05003547 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3548 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003549}
3550
Brandon Jonesd1049182018-03-28 10:02:20 -07003551bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003552{
3553 if (!context->getExtensions().pathRendering)
3554 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003555 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003556 return false;
3557 }
3558 return true;
3559}
3560
Jamie Madill007530e2017-12-28 14:27:04 -05003561bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3562 GLsizei numPaths,
3563 GLenum pathNameType,
3564 const void *paths,
3565 GLuint pathBase,
3566 GLenum coverMode,
3567 GLenum transformType,
3568 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003569{
3570 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3571 transformType, transformValues))
3572 return false;
3573
3574 switch (coverMode)
3575 {
3576 case GL_CONVEX_HULL_CHROMIUM:
3577 case GL_BOUNDING_BOX_CHROMIUM:
3578 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3579 break;
3580 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003581 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003582 return false;
3583 }
3584
3585 return true;
3586}
3587
Jamie Madill007530e2017-12-28 14:27:04 -05003588bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3589 GLsizei numPaths,
3590 GLenum pathNameType,
3591 const void *paths,
3592 GLuint pathBase,
3593 GLenum coverMode,
3594 GLenum transformType,
3595 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003596{
3597 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3598 transformType, transformValues))
3599 return false;
3600
3601 switch (coverMode)
3602 {
3603 case GL_CONVEX_HULL_CHROMIUM:
3604 case GL_BOUNDING_BOX_CHROMIUM:
3605 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3606 break;
3607 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003609 return false;
3610 }
3611
3612 return true;
3613}
3614
Jamie Madill007530e2017-12-28 14:27:04 -05003615bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3616 GLsizei numPaths,
3617 GLenum pathNameType,
3618 const void *paths,
3619 GLuint pathBase,
3620 GLenum fillMode,
3621 GLuint mask,
3622 GLenum transformType,
3623 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003624{
3625
3626 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3627 transformType, transformValues))
3628 return false;
3629
3630 switch (fillMode)
3631 {
3632 case GL_COUNT_UP_CHROMIUM:
3633 case GL_COUNT_DOWN_CHROMIUM:
3634 break;
3635 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003636 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003637 return false;
3638 }
3639 if (!isPow2(mask + 1))
3640 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003641 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003642 return false;
3643 }
3644 return true;
3645}
3646
Jamie Madill007530e2017-12-28 14:27:04 -05003647bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3648 GLsizei numPaths,
3649 GLenum pathNameType,
3650 const void *paths,
3651 GLuint pathBase,
3652 GLint reference,
3653 GLuint mask,
3654 GLenum transformType,
3655 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003656{
3657 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3658 transformType, transformValues))
3659 return false;
3660
3661 // no more validation here.
3662
3663 return true;
3664}
3665
Jamie Madill007530e2017-12-28 14:27:04 -05003666bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3667 GLsizei numPaths,
3668 GLenum pathNameType,
3669 const void *paths,
3670 GLuint pathBase,
3671 GLenum fillMode,
3672 GLuint mask,
3673 GLenum coverMode,
3674 GLenum transformType,
3675 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003676{
3677 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3678 transformType, transformValues))
3679 return false;
3680
3681 switch (coverMode)
3682 {
3683 case GL_CONVEX_HULL_CHROMIUM:
3684 case GL_BOUNDING_BOX_CHROMIUM:
3685 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3686 break;
3687 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003688 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003689 return false;
3690 }
3691
3692 switch (fillMode)
3693 {
3694 case GL_COUNT_UP_CHROMIUM:
3695 case GL_COUNT_DOWN_CHROMIUM:
3696 break;
3697 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003698 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003699 return false;
3700 }
3701 if (!isPow2(mask + 1))
3702 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003703 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003704 return false;
3705 }
3706
3707 return true;
3708}
3709
Jamie Madill007530e2017-12-28 14:27:04 -05003710bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3711 GLsizei numPaths,
3712 GLenum pathNameType,
3713 const void *paths,
3714 GLuint pathBase,
3715 GLint reference,
3716 GLuint mask,
3717 GLenum coverMode,
3718 GLenum transformType,
3719 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003720{
3721 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3722 transformType, transformValues))
3723 return false;
3724
3725 switch (coverMode)
3726 {
3727 case GL_CONVEX_HULL_CHROMIUM:
3728 case GL_BOUNDING_BOX_CHROMIUM:
3729 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3730 break;
3731 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003732 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003733 return false;
3734 }
3735
3736 return true;
3737}
3738
Jamie Madill007530e2017-12-28 14:27:04 -05003739bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3740 GLuint program,
3741 GLint location,
3742 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003743{
3744 if (!context->getExtensions().pathRendering)
3745 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003746 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003747 return false;
3748 }
3749
3750 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3751 if (location >= MaxLocation)
3752 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003753 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003754 return false;
3755 }
3756
3757 const auto *programObject = context->getProgram(program);
3758 if (!programObject)
3759 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003760 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003761 return false;
3762 }
3763
3764 if (!name)
3765 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003766 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003767 return false;
3768 }
3769
3770 if (angle::BeginsWith(name, "gl_"))
3771 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003772 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003773 return false;
3774 }
3775
3776 return true;
3777}
3778
Jamie Madill007530e2017-12-28 14:27:04 -05003779bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3780 GLuint program,
3781 GLint location,
3782 GLenum genMode,
3783 GLint components,
3784 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003785{
3786 if (!context->getExtensions().pathRendering)
3787 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003788 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003789 return false;
3790 }
3791
3792 const auto *programObject = context->getProgram(program);
3793 if (!programObject || programObject->isFlaggedForDeletion())
3794 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003795 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003796 return false;
3797 }
3798
3799 if (!programObject->isLinked())
3800 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003801 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003802 return false;
3803 }
3804
3805 switch (genMode)
3806 {
3807 case GL_NONE:
3808 if (components != 0)
3809 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003810 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003811 return false;
3812 }
3813 break;
3814
3815 case GL_OBJECT_LINEAR_CHROMIUM:
3816 case GL_EYE_LINEAR_CHROMIUM:
3817 case GL_CONSTANT_CHROMIUM:
3818 if (components < 1 || components > 4)
3819 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003820 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003821 return false;
3822 }
3823 if (!coeffs)
3824 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003825 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003826 return false;
3827 }
3828 break;
3829
3830 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003831 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003832 return false;
3833 }
3834
3835 // If the location is -1 then the command is silently ignored
3836 // and no further validation is needed.
3837 if (location == -1)
3838 return true;
3839
Jamie Madillbd044ed2017-06-05 12:59:21 -04003840 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003841
3842 if (!binding.valid)
3843 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003844 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003845 return false;
3846 }
3847
3848 if (binding.type != GL_NONE)
3849 {
3850 GLint expectedComponents = 0;
3851 switch (binding.type)
3852 {
3853 case GL_FLOAT:
3854 expectedComponents = 1;
3855 break;
3856 case GL_FLOAT_VEC2:
3857 expectedComponents = 2;
3858 break;
3859 case GL_FLOAT_VEC3:
3860 expectedComponents = 3;
3861 break;
3862 case GL_FLOAT_VEC4:
3863 expectedComponents = 4;
3864 break;
3865 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003866 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003867 InvalidOperation()
3868 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003869 return false;
3870 }
3871 if (expectedComponents != components && genMode != GL_NONE)
3872 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003873 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003874 return false;
3875 }
3876 }
3877 return true;
3878}
3879
Geoff Lang97073d12016-04-20 10:42:34 -07003880bool ValidateCopyTextureCHROMIUM(Context *context,
3881 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003882 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003883 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003884 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003885 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003886 GLint internalFormat,
3887 GLenum destType,
3888 GLboolean unpackFlipY,
3889 GLboolean unpackPremultiplyAlpha,
3890 GLboolean unpackUnmultiplyAlpha)
3891{
3892 if (!context->getExtensions().copyTexture)
3893 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003894 context->handleError(InvalidOperation()
3895 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003896 return false;
3897 }
3898
Geoff Lang4f0e0032017-05-01 16:04:35 -04003899 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003900 if (source == nullptr)
3901 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003902 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003903 return false;
3904 }
3905
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003906 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003907 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003908 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003909 return false;
3910 }
3911
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003912 TextureType sourceType = source->getType();
3913 ASSERT(sourceType != TextureType::CubeMap);
3914 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003915
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003916 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003917 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003918 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003919 return false;
3920 }
3921
Geoff Lang4f0e0032017-05-01 16:04:35 -04003922 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3923 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3924 if (sourceWidth == 0 || sourceHeight == 0)
3925 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003926 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003927 return false;
3928 }
3929
3930 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3931 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003932 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003933 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003934 return false;
3935 }
3936
Geoff Lang63458a32017-10-30 15:16:53 -04003937 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3938 {
3939 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3940 return false;
3941 }
3942
Geoff Lang4f0e0032017-05-01 16:04:35 -04003943 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003944 if (dest == nullptr)
3945 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003946 context->handleError(InvalidValue()
3947 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003948 return false;
3949 }
3950
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003951 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003952 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003953 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003954 return false;
3955 }
3956
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003957 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08003958 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003959 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003960 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003961 return false;
3962 }
3963
Geoff Lang97073d12016-04-20 10:42:34 -07003964 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3965 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003966 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003967 return false;
3968 }
3969
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003970 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003971 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003972 context->handleError(
3973 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003974 return false;
3975 }
3976
Geoff Lang97073d12016-04-20 10:42:34 -07003977 if (dest->getImmutableFormat())
3978 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003979 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003980 return false;
3981 }
3982
3983 return true;
3984}
3985
3986bool ValidateCopySubTextureCHROMIUM(Context *context,
3987 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003988 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003989 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003990 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003991 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003992 GLint xoffset,
3993 GLint yoffset,
3994 GLint x,
3995 GLint y,
3996 GLsizei width,
3997 GLsizei height,
3998 GLboolean unpackFlipY,
3999 GLboolean unpackPremultiplyAlpha,
4000 GLboolean unpackUnmultiplyAlpha)
4001{
4002 if (!context->getExtensions().copyTexture)
4003 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004004 context->handleError(InvalidOperation()
4005 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004006 return false;
4007 }
4008
Geoff Lang4f0e0032017-05-01 16:04:35 -04004009 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004010 if (source == nullptr)
4011 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004012 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004013 return false;
4014 }
4015
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004016 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004017 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004018 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004019 return false;
4020 }
4021
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004022 TextureType sourceType = source->getType();
4023 ASSERT(sourceType != TextureType::CubeMap);
4024 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004025
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004026 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004027 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004028 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004029 return false;
4030 }
4031
4032 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4033 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004034 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004035 context->handleError(InvalidValue()
4036 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004037 return false;
4038 }
4039
4040 if (x < 0 || y < 0)
4041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004042 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004043 return false;
4044 }
4045
4046 if (width < 0 || height < 0)
4047 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004048 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004049 return false;
4050 }
4051
Geoff Lang4f0e0032017-05-01 16:04:35 -04004052 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4053 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004054 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004055 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004056 return false;
4057 }
4058
Geoff Lang4f0e0032017-05-01 16:04:35 -04004059 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4060 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004061 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004062 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004063 return false;
4064 }
4065
Geoff Lang63458a32017-10-30 15:16:53 -04004066 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4067 {
4068 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4069 return false;
4070 }
4071
Geoff Lang4f0e0032017-05-01 16:04:35 -04004072 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004073 if (dest == nullptr)
4074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004075 context->handleError(InvalidValue()
4076 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004077 return false;
4078 }
4079
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004080 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004081 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004082 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004083 return false;
4084 }
4085
Brandon Jones28783792018-03-05 09:37:32 -08004086 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4087 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004088 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004089 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004090 return false;
4091 }
4092
Geoff Lang4f0e0032017-05-01 16:04:35 -04004093 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4094 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004095 context
4096 ->handleError(InvalidOperation()
4097 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004098 return false;
4099 }
4100
4101 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4102 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004103 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004104 context->handleError(InvalidOperation()
4105 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004106 return false;
4107 }
4108
4109 if (xoffset < 0 || yoffset < 0)
4110 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004111 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004112 return false;
4113 }
4114
Geoff Lang4f0e0032017-05-01 16:04:35 -04004115 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4116 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004117 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004118 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004119 return false;
4120 }
4121
4122 return true;
4123}
4124
Geoff Lang47110bf2016-04-20 11:13:22 -07004125bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4126{
4127 if (!context->getExtensions().copyCompressedTexture)
4128 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004129 context->handleError(InvalidOperation()
4130 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004131 return false;
4132 }
4133
4134 const gl::Texture *source = context->getTexture(sourceId);
4135 if (source == nullptr)
4136 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004137 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004138 return false;
4139 }
4140
Corentin Wallez99d492c2018-02-27 15:17:10 -05004141 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004142 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004143 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004144 return false;
4145 }
4146
Corentin Wallez99d492c2018-02-27 15:17:10 -05004147 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4148 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004149 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004150 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004151 return false;
4152 }
4153
Corentin Wallez99d492c2018-02-27 15:17:10 -05004154 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004155 if (!sourceFormat.info->compressed)
4156 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004157 context->handleError(InvalidOperation()
4158 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004159 return false;
4160 }
4161
4162 const gl::Texture *dest = context->getTexture(destId);
4163 if (dest == nullptr)
4164 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004165 context->handleError(InvalidValue()
4166 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004167 return false;
4168 }
4169
Corentin Wallez99d492c2018-02-27 15:17:10 -05004170 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004171 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004172 context->handleError(InvalidValue()
4173 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004174 return false;
4175 }
4176
4177 if (dest->getImmutableFormat())
4178 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004179 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004180 return false;
4181 }
4182
4183 return true;
4184}
4185
Jiawei Shao385b3e02018-03-21 09:43:28 +08004186bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004187{
4188 switch (type)
4189 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004190 case ShaderType::Vertex:
4191 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004192 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004193
Jiawei Shao385b3e02018-03-21 09:43:28 +08004194 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004195 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004196 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004197 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004198 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004199 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004200 break;
4201
Jiawei Shao385b3e02018-03-21 09:43:28 +08004202 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004203 if (!context->getExtensions().geometryShader)
4204 {
4205 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4206 return false;
4207 }
4208 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004209 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004210 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004211 return false;
4212 }
Jamie Madill29639852016-09-02 15:00:09 -04004213
4214 return true;
4215}
4216
Jamie Madill5b772312018-03-08 20:28:32 -05004217bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004218 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004219 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004220 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004221 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004222{
4223 if (size < 0)
4224 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004225 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004226 return false;
4227 }
4228
4229 switch (usage)
4230 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004231 case BufferUsage::StreamDraw:
4232 case BufferUsage::StaticDraw:
4233 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004234 break;
4235
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004236 case BufferUsage::StreamRead:
4237 case BufferUsage::StaticRead:
4238 case BufferUsage::DynamicRead:
4239 case BufferUsage::StreamCopy:
4240 case BufferUsage::StaticCopy:
4241 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004242 if (context->getClientMajorVersion() < 3)
4243 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004244 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004245 return false;
4246 }
4247 break;
4248
4249 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004250 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004251 return false;
4252 }
4253
Corentin Walleze4477002017-12-01 14:39:58 -05004254 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004255 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004256 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004257 return false;
4258 }
4259
4260 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4261
4262 if (!buffer)
4263 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004264 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004265 return false;
4266 }
4267
James Darpiniane8a93c62018-01-04 18:02:24 -08004268 if (context->getExtensions().webglCompatibility &&
4269 buffer->isBoundForTransformFeedbackAndOtherUse())
4270 {
4271 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4272 return false;
4273 }
4274
Jamie Madill29639852016-09-02 15:00:09 -04004275 return true;
4276}
4277
Jamie Madill5b772312018-03-08 20:28:32 -05004278bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004279 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004280 GLintptr offset,
4281 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004282 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004283{
Brandon Jones6cad5662017-06-14 13:25:13 -07004284 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004285 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004286 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4287 return false;
4288 }
4289
4290 if (offset < 0)
4291 {
4292 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004293 return false;
4294 }
4295
Corentin Walleze4477002017-12-01 14:39:58 -05004296 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004297 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004298 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004299 return false;
4300 }
4301
4302 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4303
4304 if (!buffer)
4305 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004306 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004307 return false;
4308 }
4309
4310 if (buffer->isMapped())
4311 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004312 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004313 return false;
4314 }
4315
James Darpiniane8a93c62018-01-04 18:02:24 -08004316 if (context->getExtensions().webglCompatibility &&
4317 buffer->isBoundForTransformFeedbackAndOtherUse())
4318 {
4319 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4320 return false;
4321 }
4322
Jamie Madill29639852016-09-02 15:00:09 -04004323 // Check for possible overflow of size + offset
4324 angle::CheckedNumeric<size_t> checkedSize(size);
4325 checkedSize += offset;
4326 if (!checkedSize.IsValid())
4327 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004328 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004329 return false;
4330 }
4331
4332 if (size + offset > buffer->getSize())
4333 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004334 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004335 return false;
4336 }
4337
Martin Radev4c4c8e72016-08-04 12:25:34 +03004338 return true;
4339}
4340
Geoff Lang111a99e2017-10-17 10:58:41 -04004341bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004342{
Geoff Langc339c4e2016-11-29 10:37:36 -05004343 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004344 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004345 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004346 return false;
4347 }
4348
Geoff Lang111a99e2017-10-17 10:58:41 -04004349 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004350 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004351 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004352 return false;
4353 }
4354
4355 return true;
4356}
4357
Jamie Madill5b772312018-03-08 20:28:32 -05004358bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004359{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004360 if (context->getClientMajorVersion() < 2)
4361 {
4362 return ValidateMultitextureUnit(context, texture);
4363 }
4364
Jamie Madillef300b12016-10-07 15:12:09 -04004365 if (texture < GL_TEXTURE0 ||
4366 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4367 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004368 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004369 return false;
4370 }
4371
4372 return true;
4373}
4374
Jamie Madill5b772312018-03-08 20:28:32 -05004375bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004376{
4377 Program *programObject = GetValidProgram(context, program);
4378 if (!programObject)
4379 {
4380 return false;
4381 }
4382
4383 Shader *shaderObject = GetValidShader(context, shader);
4384 if (!shaderObject)
4385 {
4386 return false;
4387 }
4388
Jiawei Shao385b3e02018-03-21 09:43:28 +08004389 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004390 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004391 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4392 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004393 }
4394
4395 return true;
4396}
4397
Jamie Madill5b772312018-03-08 20:28:32 -05004398bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004399{
4400 if (index >= MAX_VERTEX_ATTRIBS)
4401 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004402 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004403 return false;
4404 }
4405
4406 if (strncmp(name, "gl_", 3) == 0)
4407 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004408 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004409 return false;
4410 }
4411
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004412 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004413 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004414 const size_t length = strlen(name);
4415
4416 if (!IsValidESSLString(name, length))
4417 {
4418 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4419 // for shader-related entry points
4420 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4421 return false;
4422 }
4423
4424 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4425 {
4426 return false;
4427 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004428 }
4429
Jamie Madill01a80ee2016-11-07 12:06:18 -05004430 return GetValidProgram(context, program) != nullptr;
4431}
4432
Jamie Madill5b772312018-03-08 20:28:32 -05004433bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004434{
Corentin Walleze4477002017-12-01 14:39:58 -05004435 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004436 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004437 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004438 return false;
4439 }
4440
4441 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4442 !context->isBufferGenerated(buffer))
4443 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004444 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004445 return false;
4446 }
4447
4448 return true;
4449}
4450
Jamie Madill5b772312018-03-08 20:28:32 -05004451bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004452{
Geoff Lange8afa902017-09-27 15:00:43 -04004453 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004454 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004455 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004456 return false;
4457 }
4458
4459 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4460 !context->isFramebufferGenerated(framebuffer))
4461 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004462 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004463 return false;
4464 }
4465
4466 return true;
4467}
4468
Jamie Madill5b772312018-03-08 20:28:32 -05004469bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004470{
4471 if (target != GL_RENDERBUFFER)
4472 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004474 return false;
4475 }
4476
4477 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4478 !context->isRenderbufferGenerated(renderbuffer))
4479 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004480 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004481 return false;
4482 }
4483
4484 return true;
4485}
4486
Jamie Madill5b772312018-03-08 20:28:32 -05004487static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004488{
4489 switch (mode)
4490 {
4491 case GL_FUNC_ADD:
4492 case GL_FUNC_SUBTRACT:
4493 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004494 return true;
4495
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004496 case GL_MIN:
4497 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004498 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004499
4500 default:
4501 return false;
4502 }
4503}
4504
Jamie Madill5b772312018-03-08 20:28:32 -05004505bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004506{
4507 return true;
4508}
4509
Jamie Madill5b772312018-03-08 20:28:32 -05004510bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004511{
Geoff Lang50cac572017-09-26 17:37:43 -04004512 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004513 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004514 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004515 return false;
4516 }
4517
4518 return true;
4519}
4520
Jamie Madill5b772312018-03-08 20:28:32 -05004521bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004522{
Geoff Lang50cac572017-09-26 17:37:43 -04004523 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004524 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004525 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004526 return false;
4527 }
4528
Geoff Lang50cac572017-09-26 17:37:43 -04004529 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004530 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004531 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004532 return false;
4533 }
4534
4535 return true;
4536}
4537
Jamie Madill5b772312018-03-08 20:28:32 -05004538bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004539{
4540 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4541}
4542
4543static bool ValidSrcBlendFunc(GLenum srcBlend)
4544{
4545 switch (srcBlend)
4546 {
4547 case GL_ZERO:
4548 case GL_ONE:
4549 case GL_SRC_COLOR:
4550 case GL_ONE_MINUS_SRC_COLOR:
4551 case GL_DST_COLOR:
4552 case GL_ONE_MINUS_DST_COLOR:
4553 case GL_SRC_ALPHA:
4554 case GL_ONE_MINUS_SRC_ALPHA:
4555 case GL_DST_ALPHA:
4556 case GL_ONE_MINUS_DST_ALPHA:
4557 case GL_CONSTANT_COLOR:
4558 case GL_ONE_MINUS_CONSTANT_COLOR:
4559 case GL_CONSTANT_ALPHA:
4560 case GL_ONE_MINUS_CONSTANT_ALPHA:
4561 case GL_SRC_ALPHA_SATURATE:
4562 return true;
4563
4564 default:
4565 return false;
4566 }
4567}
4568
4569static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4570{
4571 switch (dstBlend)
4572 {
4573 case GL_ZERO:
4574 case GL_ONE:
4575 case GL_SRC_COLOR:
4576 case GL_ONE_MINUS_SRC_COLOR:
4577 case GL_DST_COLOR:
4578 case GL_ONE_MINUS_DST_COLOR:
4579 case GL_SRC_ALPHA:
4580 case GL_ONE_MINUS_SRC_ALPHA:
4581 case GL_DST_ALPHA:
4582 case GL_ONE_MINUS_DST_ALPHA:
4583 case GL_CONSTANT_COLOR:
4584 case GL_ONE_MINUS_CONSTANT_COLOR:
4585 case GL_CONSTANT_ALPHA:
4586 case GL_ONE_MINUS_CONSTANT_ALPHA:
4587 return true;
4588
4589 case GL_SRC_ALPHA_SATURATE:
4590 return (contextMajorVersion >= 3);
4591
4592 default:
4593 return false;
4594 }
4595}
4596
Jamie Madill5b772312018-03-08 20:28:32 -05004597bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004598 GLenum srcRGB,
4599 GLenum dstRGB,
4600 GLenum srcAlpha,
4601 GLenum dstAlpha)
4602{
4603 if (!ValidSrcBlendFunc(srcRGB))
4604 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004605 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004606 return false;
4607 }
4608
4609 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4610 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004611 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004612 return false;
4613 }
4614
4615 if (!ValidSrcBlendFunc(srcAlpha))
4616 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004617 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004618 return false;
4619 }
4620
4621 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4622 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004623 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004624 return false;
4625 }
4626
Frank Henigman146e8a12017-03-02 23:22:37 -05004627 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4628 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004629 {
4630 bool constantColorUsed =
4631 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4632 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4633
4634 bool constantAlphaUsed =
4635 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4636 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4637
4638 if (constantColorUsed && constantAlphaUsed)
4639 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004640 const char *msg;
4641 if (context->getExtensions().webglCompatibility)
4642 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004643 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004644 }
4645 else
4646 {
4647 msg =
4648 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4649 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4650 "implementation.";
4651 ERR() << msg;
4652 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004653 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004654 return false;
4655 }
4656 }
4657
4658 return true;
4659}
4660
Geoff Langc339c4e2016-11-29 10:37:36 -05004661bool ValidateGetString(Context *context, GLenum name)
4662{
4663 switch (name)
4664 {
4665 case GL_VENDOR:
4666 case GL_RENDERER:
4667 case GL_VERSION:
4668 case GL_SHADING_LANGUAGE_VERSION:
4669 case GL_EXTENSIONS:
4670 break;
4671
4672 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4673 if (!context->getExtensions().requestExtension)
4674 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004675 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004676 return false;
4677 }
4678 break;
4679
4680 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004681 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004682 return false;
4683 }
4684
4685 return true;
4686}
4687
Jamie Madill5b772312018-03-08 20:28:32 -05004688bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004689{
4690 if (width <= 0.0f || isNaN(width))
4691 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004692 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004693 return false;
4694 }
4695
4696 return true;
4697}
4698
Jamie Madill5b772312018-03-08 20:28:32 -05004699bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004700 GLuint index,
4701 GLint size,
4702 GLenum type,
4703 GLboolean normalized,
4704 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004705 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004706{
Shao80957d92017-02-20 21:25:59 +08004707 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004708 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004709 return false;
4710 }
4711
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004712 if (stride < 0)
4713 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004714 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004715 return false;
4716 }
4717
Shao80957d92017-02-20 21:25:59 +08004718 const Caps &caps = context->getCaps();
4719 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004720 {
Shao80957d92017-02-20 21:25:59 +08004721 if (stride > caps.maxVertexAttribStride)
4722 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004723 context->handleError(InvalidValue()
4724 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004725 return false;
4726 }
4727
4728 if (index >= caps.maxVertexAttribBindings)
4729 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004730 context->handleError(InvalidValue()
4731 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004732 return false;
4733 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004734 }
4735
4736 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4737 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4738 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4739 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004740 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4741 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004742 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4743 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004744 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004745 context
4746 ->handleError(InvalidOperation()
4747 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004748 return false;
4749 }
4750
4751 if (context->getExtensions().webglCompatibility)
4752 {
4753 // WebGL 1.0 [Section 6.14] Fixed point support
4754 // The WebGL API does not support the GL_FIXED data type.
4755 if (type == GL_FIXED)
4756 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004757 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004758 return false;
4759 }
4760
Geoff Lang2d62ab72017-03-23 16:54:40 -04004761 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004762 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004763 return false;
4764 }
4765 }
4766
4767 return true;
4768}
4769
Jamie Madill5b772312018-03-08 20:28:32 -05004770bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004771{
4772 if (context->getExtensions().webglCompatibility && zNear > zFar)
4773 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004774 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004775 return false;
4776 }
4777
4778 return true;
4779}
4780
Jamie Madill5b772312018-03-08 20:28:32 -05004781bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004782 GLenum target,
4783 GLenum internalformat,
4784 GLsizei width,
4785 GLsizei height)
4786{
4787 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4788 height);
4789}
4790
Jamie Madill5b772312018-03-08 20:28:32 -05004791bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004792 GLenum target,
4793 GLsizei samples,
4794 GLenum internalformat,
4795 GLsizei width,
4796 GLsizei height)
4797{
4798 if (!context->getExtensions().framebufferMultisample)
4799 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004800 context->handleError(InvalidOperation()
4801 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004802 return false;
4803 }
4804
4805 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4806 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4807 // generated.
4808 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4809 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004810 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004811 return false;
4812 }
4813
4814 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4815 // the specified storage. This is different than ES 3.0 in which a sample number higher
4816 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4817 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4818 if (context->getClientMajorVersion() >= 3)
4819 {
4820 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4821 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4822 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004823 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004824 return false;
4825 }
4826 }
4827
4828 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4829 width, height);
4830}
4831
Jamie Madill5b772312018-03-08 20:28:32 -05004832bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004833{
Geoff Lange8afa902017-09-27 15:00:43 -04004834 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004835 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004836 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004837 return false;
4838 }
4839
4840 return true;
4841}
4842
Jamie Madill5b772312018-03-08 20:28:32 -05004843bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004844{
4845 return true;
4846}
4847
Jamie Madill5b772312018-03-08 20:28:32 -05004848bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004849{
4850 return true;
4851}
4852
Jamie Madill5b772312018-03-08 20:28:32 -05004853bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004854{
4855 return true;
4856}
4857
Jamie Madill5b772312018-03-08 20:28:32 -05004858bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004859 GLboolean red,
4860 GLboolean green,
4861 GLboolean blue,
4862 GLboolean alpha)
4863{
4864 return true;
4865}
4866
Jamie Madill5b772312018-03-08 20:28:32 -05004867bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004868{
4869 return true;
4870}
4871
Jamie Madill5b772312018-03-08 20:28:32 -05004872bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004873{
4874 return true;
4875}
4876
Jamie Madill5b772312018-03-08 20:28:32 -05004877bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004878{
4879 switch (mode)
4880 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004881 case CullFaceMode::Front:
4882 case CullFaceMode::Back:
4883 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004884 break;
4885
4886 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004887 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004888 return false;
4889 }
4890
4891 return true;
4892}
4893
Jamie Madill5b772312018-03-08 20:28:32 -05004894bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004895{
4896 if (program == 0)
4897 {
4898 return false;
4899 }
4900
4901 if (!context->getProgram(program))
4902 {
4903 if (context->getShader(program))
4904 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004905 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004906 return false;
4907 }
4908 else
4909 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004910 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004911 return false;
4912 }
4913 }
4914
4915 return true;
4916}
4917
Jamie Madill5b772312018-03-08 20:28:32 -05004918bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004919{
4920 if (shader == 0)
4921 {
4922 return false;
4923 }
4924
4925 if (!context->getShader(shader))
4926 {
4927 if (context->getProgram(shader))
4928 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004929 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004930 return false;
4931 }
4932 else
4933 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004934 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004935 return false;
4936 }
4937 }
4938
4939 return true;
4940}
4941
Jamie Madill5b772312018-03-08 20:28:32 -05004942bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004943{
4944 switch (func)
4945 {
4946 case GL_NEVER:
4947 case GL_ALWAYS:
4948 case GL_LESS:
4949 case GL_LEQUAL:
4950 case GL_EQUAL:
4951 case GL_GREATER:
4952 case GL_GEQUAL:
4953 case GL_NOTEQUAL:
4954 break;
4955
4956 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004957 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004958 return false;
4959 }
4960
4961 return true;
4962}
4963
Jamie Madill5b772312018-03-08 20:28:32 -05004964bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004965{
4966 return true;
4967}
4968
Jamie Madill5b772312018-03-08 20:28:32 -05004969bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004970{
4971 Program *programObject = GetValidProgram(context, program);
4972 if (!programObject)
4973 {
4974 return false;
4975 }
4976
4977 Shader *shaderObject = GetValidShader(context, shader);
4978 if (!shaderObject)
4979 {
4980 return false;
4981 }
4982
Jiawei Shao385b3e02018-03-21 09:43:28 +08004983 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004984 if (attachedShader != shaderObject)
4985 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004986 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004987 return false;
4988 }
4989
4990 return true;
4991}
4992
Jamie Madill5b772312018-03-08 20:28:32 -05004993bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004994{
4995 if (index >= MAX_VERTEX_ATTRIBS)
4996 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004997 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004998 return false;
4999 }
5000
5001 return true;
5002}
5003
Jamie Madill5b772312018-03-08 20:28:32 -05005004bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005005{
5006 if (index >= MAX_VERTEX_ATTRIBS)
5007 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005008 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005009 return false;
5010 }
5011
5012 return true;
5013}
5014
Jamie Madill5b772312018-03-08 20:28:32 -05005015bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005016{
5017 return true;
5018}
5019
Jamie Madill5b772312018-03-08 20:28:32 -05005020bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005021{
5022 return true;
5023}
5024
Jamie Madill5b772312018-03-08 20:28:32 -05005025bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005026{
5027 switch (mode)
5028 {
5029 case GL_CW:
5030 case GL_CCW:
5031 break;
5032 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005033 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005034 return false;
5035 }
5036
5037 return true;
5038}
5039
Jamie Madill5b772312018-03-08 20:28:32 -05005040bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005041 GLuint program,
5042 GLuint index,
5043 GLsizei bufsize,
5044 GLsizei *length,
5045 GLint *size,
5046 GLenum *type,
5047 GLchar *name)
5048{
5049 if (bufsize < 0)
5050 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005051 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005052 return false;
5053 }
5054
5055 Program *programObject = GetValidProgram(context, program);
5056
5057 if (!programObject)
5058 {
5059 return false;
5060 }
5061
5062 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5063 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005064 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005065 return false;
5066 }
5067
5068 return true;
5069}
5070
Jamie Madill5b772312018-03-08 20:28:32 -05005071bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005072 GLuint program,
5073 GLuint index,
5074 GLsizei bufsize,
5075 GLsizei *length,
5076 GLint *size,
5077 GLenum *type,
5078 GLchar *name)
5079{
5080 if (bufsize < 0)
5081 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005082 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005083 return false;
5084 }
5085
5086 Program *programObject = GetValidProgram(context, program);
5087
5088 if (!programObject)
5089 {
5090 return false;
5091 }
5092
5093 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5094 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005095 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005096 return false;
5097 }
5098
5099 return true;
5100}
5101
Jamie Madill5b772312018-03-08 20:28:32 -05005102bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005103 GLuint program,
5104 GLsizei maxcount,
5105 GLsizei *count,
5106 GLuint *shaders)
5107{
5108 if (maxcount < 0)
5109 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005110 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005111 return false;
5112 }
5113
5114 Program *programObject = GetValidProgram(context, program);
5115
5116 if (!programObject)
5117 {
5118 return false;
5119 }
5120
5121 return true;
5122}
5123
Jamie Madill5b772312018-03-08 20:28:32 -05005124bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005125{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005126 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5127 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005128 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005129 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005130 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005131 return false;
5132 }
5133
Jamie Madillc1d770e2017-04-13 17:31:24 -04005134 Program *programObject = GetValidProgram(context, program);
5135
5136 if (!programObject)
5137 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005138 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005139 return false;
5140 }
5141
5142 if (!programObject->isLinked())
5143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005145 return false;
5146 }
5147
5148 return true;
5149}
5150
Jamie Madill5b772312018-03-08 20:28:32 -05005151bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005152{
5153 GLenum nativeType;
5154 unsigned int numParams = 0;
5155 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5156}
5157
Jamie Madill5b772312018-03-08 20:28:32 -05005158bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005159{
5160 return true;
5161}
5162
Jamie Madill5b772312018-03-08 20:28:32 -05005163bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005164{
5165 GLenum nativeType;
5166 unsigned int numParams = 0;
5167 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5168}
5169
Jamie Madill5b772312018-03-08 20:28:32 -05005170bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005171{
5172 GLenum nativeType;
5173 unsigned int numParams = 0;
5174 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5175}
5176
Jamie Madill5b772312018-03-08 20:28:32 -05005177bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005178 GLuint program,
5179 GLsizei bufsize,
5180 GLsizei *length,
5181 GLchar *infolog)
5182{
5183 if (bufsize < 0)
5184 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005185 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005186 return false;
5187 }
5188
5189 Program *programObject = GetValidProgram(context, program);
5190 if (!programObject)
5191 {
5192 return false;
5193 }
5194
5195 return true;
5196}
5197
Jamie Madill5b772312018-03-08 20:28:32 -05005198bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005199 GLuint shader,
5200 GLsizei bufsize,
5201 GLsizei *length,
5202 GLchar *infolog)
5203{
5204 if (bufsize < 0)
5205 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005206 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005207 return false;
5208 }
5209
5210 Shader *shaderObject = GetValidShader(context, shader);
5211 if (!shaderObject)
5212 {
5213 return false;
5214 }
5215
5216 return true;
5217}
5218
Jamie Madill5b772312018-03-08 20:28:32 -05005219bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005220 GLenum shadertype,
5221 GLenum precisiontype,
5222 GLint *range,
5223 GLint *precision)
5224{
5225 switch (shadertype)
5226 {
5227 case GL_VERTEX_SHADER:
5228 case GL_FRAGMENT_SHADER:
5229 break;
5230 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005231 context->handleError(InvalidOperation()
5232 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005233 return false;
5234 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005235 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005236 return false;
5237 }
5238
5239 switch (precisiontype)
5240 {
5241 case GL_LOW_FLOAT:
5242 case GL_MEDIUM_FLOAT:
5243 case GL_HIGH_FLOAT:
5244 case GL_LOW_INT:
5245 case GL_MEDIUM_INT:
5246 case GL_HIGH_INT:
5247 break;
5248
5249 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005250 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005251 return false;
5252 }
5253
5254 return true;
5255}
5256
Jamie Madill5b772312018-03-08 20:28:32 -05005257bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005258 GLuint shader,
5259 GLsizei bufsize,
5260 GLsizei *length,
5261 GLchar *source)
5262{
5263 if (bufsize < 0)
5264 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005265 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005266 return false;
5267 }
5268
5269 Shader *shaderObject = GetValidShader(context, shader);
5270 if (!shaderObject)
5271 {
5272 return false;
5273 }
5274
5275 return true;
5276}
5277
Jamie Madill5b772312018-03-08 20:28:32 -05005278bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005279{
5280 if (strstr(name, "gl_") == name)
5281 {
5282 return false;
5283 }
5284
Geoff Langfc32e8b2017-05-31 14:16:59 -04005285 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5286 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005287 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005288 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005289 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005290 return false;
5291 }
5292
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293 Program *programObject = GetValidProgram(context, program);
5294
5295 if (!programObject)
5296 {
5297 return false;
5298 }
5299
5300 if (!programObject->isLinked())
5301 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005302 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005303 return false;
5304 }
5305
5306 return true;
5307}
5308
Jamie Madill5b772312018-03-08 20:28:32 -05005309bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005310{
5311 switch (mode)
5312 {
5313 case GL_FASTEST:
5314 case GL_NICEST:
5315 case GL_DONT_CARE:
5316 break;
5317
5318 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005319 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005320 return false;
5321 }
5322
5323 switch (target)
5324 {
5325 case GL_GENERATE_MIPMAP_HINT:
5326 break;
5327
Geoff Lange7bd2182017-06-16 16:13:13 -04005328 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5329 if (context->getClientVersion() < ES_3_0 &&
5330 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005331 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005332 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005333 return false;
5334 }
5335 break;
5336
5337 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005338 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005339 return false;
5340 }
5341
5342 return true;
5343}
5344
Jamie Madill5b772312018-03-08 20:28:32 -05005345bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005346{
5347 return true;
5348}
5349
Jamie Madill5b772312018-03-08 20:28:32 -05005350bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005351{
5352 return true;
5353}
5354
Jamie Madill5b772312018-03-08 20:28:32 -05005355bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005356{
5357 return true;
5358}
5359
Jamie Madill5b772312018-03-08 20:28:32 -05005360bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005361{
5362 return true;
5363}
5364
Jamie Madill5b772312018-03-08 20:28:32 -05005365bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005366{
5367 return true;
5368}
5369
Jamie Madill5b772312018-03-08 20:28:32 -05005370bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005371{
5372 return true;
5373}
5374
Jamie Madill5b772312018-03-08 20:28:32 -05005375bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005376{
5377 if (context->getClientMajorVersion() < 3)
5378 {
5379 switch (pname)
5380 {
5381 case GL_UNPACK_IMAGE_HEIGHT:
5382 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005383 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005384 return false;
5385
5386 case GL_UNPACK_ROW_LENGTH:
5387 case GL_UNPACK_SKIP_ROWS:
5388 case GL_UNPACK_SKIP_PIXELS:
5389 if (!context->getExtensions().unpackSubimage)
5390 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005391 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005392 return false;
5393 }
5394 break;
5395
5396 case GL_PACK_ROW_LENGTH:
5397 case GL_PACK_SKIP_ROWS:
5398 case GL_PACK_SKIP_PIXELS:
5399 if (!context->getExtensions().packSubimage)
5400 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005401 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005402 return false;
5403 }
5404 break;
5405 }
5406 }
5407
5408 if (param < 0)
5409 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005410 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005411 return false;
5412 }
5413
5414 switch (pname)
5415 {
5416 case GL_UNPACK_ALIGNMENT:
5417 if (param != 1 && param != 2 && param != 4 && param != 8)
5418 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005419 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005420 return false;
5421 }
5422 break;
5423
5424 case GL_PACK_ALIGNMENT:
5425 if (param != 1 && param != 2 && param != 4 && param != 8)
5426 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005427 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005428 return false;
5429 }
5430 break;
5431
5432 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005433 if (!context->getExtensions().packReverseRowOrder)
5434 {
5435 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5436 }
5437 break;
5438
Jamie Madillc1d770e2017-04-13 17:31:24 -04005439 case GL_UNPACK_ROW_LENGTH:
5440 case GL_UNPACK_IMAGE_HEIGHT:
5441 case GL_UNPACK_SKIP_IMAGES:
5442 case GL_UNPACK_SKIP_ROWS:
5443 case GL_UNPACK_SKIP_PIXELS:
5444 case GL_PACK_ROW_LENGTH:
5445 case GL_PACK_SKIP_ROWS:
5446 case GL_PACK_SKIP_PIXELS:
5447 break;
5448
5449 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005450 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005451 return false;
5452 }
5453
5454 return true;
5455}
5456
Jamie Madill5b772312018-03-08 20:28:32 -05005457bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005458{
5459 return true;
5460}
5461
Jamie Madill5b772312018-03-08 20:28:32 -05005462bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005463{
5464 return true;
5465}
5466
Jamie Madill5b772312018-03-08 20:28:32 -05005467bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005468{
5469 return true;
5470}
5471
Jamie Madill5b772312018-03-08 20:28:32 -05005472bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005473{
5474 if (width < 0 || height < 0)
5475 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005476 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477 return false;
5478 }
5479
5480 return true;
5481}
5482
Jamie Madill5b772312018-03-08 20:28:32 -05005483bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005484 GLsizei n,
5485 const GLuint *shaders,
5486 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005487 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005488 GLsizei length)
5489{
5490 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5491 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5492 shaderBinaryFormats.end())
5493 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005494 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005495 return false;
5496 }
5497
5498 return true;
5499}
5500
Jamie Madill5b772312018-03-08 20:28:32 -05005501bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005502 GLuint shader,
5503 GLsizei count,
5504 const GLchar *const *string,
5505 const GLint *length)
5506{
5507 if (count < 0)
5508 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005509 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005510 return false;
5511 }
5512
Geoff Langfc32e8b2017-05-31 14:16:59 -04005513 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5514 // shader-related entry points
5515 if (context->getExtensions().webglCompatibility)
5516 {
5517 for (GLsizei i = 0; i < count; i++)
5518 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005519 size_t len =
5520 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005521
5522 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005523 if (!IsValidESSLShaderSourceString(string[i], len,
5524 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005525 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005526 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005527 return false;
5528 }
5529 }
5530 }
5531
Jamie Madillc1d770e2017-04-13 17:31:24 -04005532 Shader *shaderObject = GetValidShader(context, shader);
5533 if (!shaderObject)
5534 {
5535 return false;
5536 }
5537
5538 return true;
5539}
5540
Jamie Madill5b772312018-03-08 20:28:32 -05005541bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005542{
5543 if (!IsValidStencilFunc(func))
5544 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005545 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005546 return false;
5547 }
5548
5549 return true;
5550}
5551
Jamie Madill5b772312018-03-08 20:28:32 -05005552bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005553{
5554 if (!IsValidStencilFace(face))
5555 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005556 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005557 return false;
5558 }
5559
5560 if (!IsValidStencilFunc(func))
5561 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005562 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005563 return false;
5564 }
5565
5566 return true;
5567}
5568
Jamie Madill5b772312018-03-08 20:28:32 -05005569bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005570{
5571 return true;
5572}
5573
Jamie Madill5b772312018-03-08 20:28:32 -05005574bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005575{
5576 if (!IsValidStencilFace(face))
5577 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005578 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005579 return false;
5580 }
5581
5582 return true;
5583}
5584
Jamie Madill5b772312018-03-08 20:28:32 -05005585bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005586{
5587 if (!IsValidStencilOp(fail))
5588 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005589 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005590 return false;
5591 }
5592
5593 if (!IsValidStencilOp(zfail))
5594 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005595 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596 return false;
5597 }
5598
5599 if (!IsValidStencilOp(zpass))
5600 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602 return false;
5603 }
5604
5605 return true;
5606}
5607
Jamie Madill5b772312018-03-08 20:28:32 -05005608bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005609 GLenum face,
5610 GLenum fail,
5611 GLenum zfail,
5612 GLenum zpass)
5613{
5614 if (!IsValidStencilFace(face))
5615 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005616 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005617 return false;
5618 }
5619
5620 return ValidateStencilOp(context, fail, zfail, zpass);
5621}
5622
Jamie Madill5b772312018-03-08 20:28:32 -05005623bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005624{
5625 return ValidateUniform(context, GL_FLOAT, location, 1);
5626}
5627
Jamie Madill5b772312018-03-08 20:28:32 -05005628bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629{
5630 return ValidateUniform(context, GL_FLOAT, location, count);
5631}
5632
Jamie Madill5b772312018-03-08 20:28:32 -05005633bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005634{
5635 return ValidateUniform1iv(context, location, 1, &x);
5636}
5637
Jamie Madill5b772312018-03-08 20:28:32 -05005638bool ValidateUniform2f(Context *context, GLint location, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005639{
5640 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5641}
5642
Jamie Madill5b772312018-03-08 20:28:32 -05005643bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005644{
5645 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5646}
5647
Jamie Madill5b772312018-03-08 20:28:32 -05005648bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005649{
5650 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5651}
5652
Jamie Madill5b772312018-03-08 20:28:32 -05005653bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005654{
5655 return ValidateUniform(context, GL_INT_VEC2, location, count);
5656}
5657
Jamie Madill5b772312018-03-08 20:28:32 -05005658bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005659{
5660 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5661}
5662
Jamie Madill5b772312018-03-08 20:28:32 -05005663bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005664{
5665 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5666}
5667
Jamie Madill5b772312018-03-08 20:28:32 -05005668bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005669{
5670 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5671}
5672
Jamie Madill5b772312018-03-08 20:28:32 -05005673bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005674{
5675 return ValidateUniform(context, GL_INT_VEC3, location, count);
5676}
5677
Jamie Madill5b772312018-03-08 20:28:32 -05005678bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005679{
5680 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5681}
5682
Jamie Madill5b772312018-03-08 20:28:32 -05005683bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005684{
5685 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5686}
5687
Jamie Madill5b772312018-03-08 20:28:32 -05005688bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005689{
5690 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5691}
5692
Jamie Madill5b772312018-03-08 20:28:32 -05005693bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005694{
5695 return ValidateUniform(context, GL_INT_VEC4, location, count);
5696}
5697
Jamie Madill5b772312018-03-08 20:28:32 -05005698bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005699 GLint location,
5700 GLsizei count,
5701 GLboolean transpose,
5702 const GLfloat *value)
5703{
5704 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5705}
5706
Jamie Madill5b772312018-03-08 20:28:32 -05005707bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005708 GLint location,
5709 GLsizei count,
5710 GLboolean transpose,
5711 const GLfloat *value)
5712{
5713 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5714}
5715
Jamie Madill5b772312018-03-08 20:28:32 -05005716bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005717 GLint location,
5718 GLsizei count,
5719 GLboolean transpose,
5720 const GLfloat *value)
5721{
5722 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5723}
5724
Jamie Madill5b772312018-03-08 20:28:32 -05005725bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005726{
5727 Program *programObject = GetValidProgram(context, program);
5728
5729 if (!programObject)
5730 {
5731 return false;
5732 }
5733
5734 return true;
5735}
5736
Jamie Madill5b772312018-03-08 20:28:32 -05005737bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005738{
5739 return ValidateVertexAttribIndex(context, index);
5740}
5741
Jamie Madill5b772312018-03-08 20:28:32 -05005742bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005743{
5744 return ValidateVertexAttribIndex(context, index);
5745}
5746
Jamie Madill5b772312018-03-08 20:28:32 -05005747bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005748{
5749 return ValidateVertexAttribIndex(context, index);
5750}
5751
Jamie Madill5b772312018-03-08 20:28:32 -05005752bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005753{
5754 return ValidateVertexAttribIndex(context, index);
5755}
5756
Jamie Madill5b772312018-03-08 20:28:32 -05005757bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005758{
5759 return ValidateVertexAttribIndex(context, index);
5760}
5761
Jamie Madill5b772312018-03-08 20:28:32 -05005762bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005763{
5764 return ValidateVertexAttribIndex(context, index);
5765}
5766
Jamie Madill5b772312018-03-08 20:28:32 -05005767bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005768 GLuint index,
5769 GLfloat x,
5770 GLfloat y,
5771 GLfloat z,
5772 GLfloat w)
5773{
5774 return ValidateVertexAttribIndex(context, index);
5775}
5776
Jamie Madill5b772312018-03-08 20:28:32 -05005777bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005778{
5779 return ValidateVertexAttribIndex(context, index);
5780}
5781
Jamie Madill5b772312018-03-08 20:28:32 -05005782bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005783{
5784 if (width < 0 || height < 0)
5785 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005786 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005787 return false;
5788 }
5789
5790 return true;
5791}
5792
Jamie Madill5b772312018-03-08 20:28:32 -05005793bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005794{
5795 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5796}
5797
Jamie Madill5b772312018-03-08 20:28:32 -05005798bool ValidateDrawElements(Context *context,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005799 GLenum mode,
5800 GLsizei count,
5801 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005802 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005803{
5804 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5805}
5806
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005807bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005808 GLenum target,
5809 GLenum attachment,
5810 GLenum pname,
5811 GLint *params)
5812{
5813 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5814 nullptr);
5815}
5816
Jamie Madill5b772312018-03-08 20:28:32 -05005817bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005818{
5819 return ValidateGetProgramivBase(context, program, pname, nullptr);
5820}
5821
Jamie Madill5b772312018-03-08 20:28:32 -05005822bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005823 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005824 GLint level,
5825 GLenum internalformat,
5826 GLint x,
5827 GLint y,
5828 GLsizei width,
5829 GLsizei height,
5830 GLint border)
5831{
5832 if (context->getClientMajorVersion() < 3)
5833 {
5834 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5835 0, x, y, width, height, border);
5836 }
5837
5838 ASSERT(context->getClientMajorVersion() == 3);
5839 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5840 0, x, y, width, height, border);
5841}
5842
5843bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005844 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005845 GLint level,
5846 GLint xoffset,
5847 GLint yoffset,
5848 GLint x,
5849 GLint y,
5850 GLsizei width,
5851 GLsizei height)
5852{
5853 if (context->getClientMajorVersion() < 3)
5854 {
5855 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5856 yoffset, x, y, width, height, 0);
5857 }
5858
5859 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5860 yoffset, 0, x, y, width, height, 0);
5861}
5862
5863bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5864{
5865 return ValidateGenOrDelete(context, n);
5866}
5867
5868bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5869{
5870 return ValidateGenOrDelete(context, n);
5871}
5872
5873bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5874{
5875 return ValidateGenOrDelete(context, n);
5876}
5877
5878bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5879{
5880 return ValidateGenOrDelete(context, n);
5881}
5882
5883bool ValidateDisable(Context *context, GLenum cap)
5884{
5885 if (!ValidCap(context, cap, false))
5886 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005887 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005888 return false;
5889 }
5890
5891 return true;
5892}
5893
5894bool ValidateEnable(Context *context, GLenum cap)
5895{
5896 if (!ValidCap(context, cap, false))
5897 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005898 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005899 return false;
5900 }
5901
5902 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5903 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5904 {
5905 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005906 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005907
5908 // We also output an error message to the debugger window if tracing is active, so that
5909 // developers can see the error message.
5910 ERR() << errorMessage;
5911 return false;
5912 }
5913
5914 return true;
5915}
5916
5917bool ValidateFramebufferRenderbuffer(Context *context,
5918 GLenum target,
5919 GLenum attachment,
5920 GLenum renderbuffertarget,
5921 GLuint renderbuffer)
5922{
Geoff Lange8afa902017-09-27 15:00:43 -04005923 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005924 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005925 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5926 return false;
5927 }
5928
5929 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5930 {
5931 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005932 return false;
5933 }
5934
5935 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5936 renderbuffertarget, renderbuffer);
5937}
5938
5939bool ValidateFramebufferTexture2D(Context *context,
5940 GLenum target,
5941 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005942 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005943 GLuint texture,
5944 GLint level)
5945{
5946 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5947 // extension
5948 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5949 level != 0)
5950 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005951 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005952 return false;
5953 }
5954
5955 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5956 {
5957 return false;
5958 }
5959
5960 if (texture != 0)
5961 {
5962 gl::Texture *tex = context->getTexture(texture);
5963 ASSERT(tex);
5964
5965 const gl::Caps &caps = context->getCaps();
5966
5967 switch (textarget)
5968 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005969 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005970 {
5971 if (level > gl::log2(caps.max2DTextureSize))
5972 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005973 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005974 return false;
5975 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005976 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005977 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005978 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005979 return false;
5980 }
5981 }
5982 break;
5983
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005984 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005985 {
5986 if (level != 0)
5987 {
5988 context->handleError(InvalidValue());
5989 return false;
5990 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005991 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005992 {
5993 context->handleError(InvalidOperation()
5994 << "Textarget must match the texture target type.");
5995 return false;
5996 }
5997 }
5998 break;
5999
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006000 case TextureTarget::CubeMapNegativeX:
6001 case TextureTarget::CubeMapNegativeY:
6002 case TextureTarget::CubeMapNegativeZ:
6003 case TextureTarget::CubeMapPositiveX:
6004 case TextureTarget::CubeMapPositiveY:
6005 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 {
6007 if (level > gl::log2(caps.maxCubeMapTextureSize))
6008 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006009 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006010 return false;
6011 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006012 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006014 context->handleError(InvalidOperation()
6015 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006016 return false;
6017 }
6018 }
6019 break;
6020
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006021 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006022 {
6023 if (context->getClientVersion() < ES_3_1)
6024 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006025 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006026 return false;
6027 }
6028
6029 if (level != 0)
6030 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006031 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006032 return false;
6033 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006034 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006036 context->handleError(InvalidOperation()
6037 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006038 return false;
6039 }
6040 }
6041 break;
6042
6043 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006044 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 return false;
6046 }
6047
6048 const Format &format = tex->getFormat(textarget, level);
6049 if (format.info->compressed)
6050 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006051 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006052 return false;
6053 }
6054 }
6055
6056 return true;
6057}
6058
6059bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6060{
6061 return ValidateGenOrDelete(context, n);
6062}
6063
6064bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6065{
6066 return ValidateGenOrDelete(context, n);
6067}
6068
6069bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6070{
6071 return ValidateGenOrDelete(context, n);
6072}
6073
6074bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6075{
6076 return ValidateGenOrDelete(context, n);
6077}
6078
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006079bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006080{
6081 if (!ValidTextureTarget(context, target))
6082 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006083 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006084 return false;
6085 }
6086
6087 Texture *texture = context->getTargetTexture(target);
6088
6089 if (texture == nullptr)
6090 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006091 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006092 return false;
6093 }
6094
6095 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6096
6097 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6098 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6099 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006101 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006102 return false;
6103 }
6104
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006105 TextureTarget baseTarget = (target == TextureType::CubeMap)
6106 ? TextureTarget::CubeMapPositiveX
6107 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006108 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6109 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6110 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006111 {
6112 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6113 return false;
6114 }
6115
Geoff Lang536eca12017-09-13 11:23:35 -04006116 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6117 bool formatUnsized = !format.sized;
6118 bool formatColorRenderableAndFilterable =
6119 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6120 format.renderSupport(context->getClientVersion(), context->getExtensions());
6121 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006122 {
Geoff Lang536eca12017-09-13 11:23:35 -04006123 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006124 return false;
6125 }
6126
Geoff Lang536eca12017-09-13 11:23:35 -04006127 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6128 // generation
6129 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6130 {
6131 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6132 return false;
6133 }
6134
6135 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6136 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006137 bool supportsSRGBMipmapGeneration =
6138 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006139 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006140 {
Geoff Lang536eca12017-09-13 11:23:35 -04006141 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006142 return false;
6143 }
6144
6145 // Non-power of 2 ES2 check
6146 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6147 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6148 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6149 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006150 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6151 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006152 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006153 return false;
6154 }
6155
6156 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006157 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006160 return false;
6161 }
6162
6163 return true;
6164}
6165
Jamie Madill5b772312018-03-08 20:28:32 -05006166bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006167 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006168 GLenum pname,
6169 GLint *params)
6170{
6171 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6172}
6173
6174bool ValidateGetRenderbufferParameteriv(Context *context,
6175 GLenum target,
6176 GLenum pname,
6177 GLint *params)
6178{
6179 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6180}
6181
6182bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6183{
6184 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6185}
6186
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006187bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006188{
6189 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6190}
6191
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006192bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006193{
6194 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6195}
6196
6197bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6198{
6199 return ValidateGetUniformBase(context, program, location);
6200}
6201
6202bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6203{
6204 return ValidateGetUniformBase(context, program, location);
6205}
6206
6207bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6208{
6209 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6210}
6211
6212bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6213{
6214 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6215}
6216
6217bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6218{
6219 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6220}
6221
6222bool ValidateIsEnabled(Context *context, GLenum cap)
6223{
6224 if (!ValidCap(context, cap, true))
6225 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006226 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006227 return false;
6228 }
6229
6230 return true;
6231}
6232
6233bool ValidateLinkProgram(Context *context, GLuint program)
6234{
6235 if (context->hasActiveTransformFeedback(program))
6236 {
6237 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006238 context->handleError(InvalidOperation() << "Cannot link program while program is "
6239 "associated with an active transform "
6240 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006241 return false;
6242 }
6243
6244 Program *programObject = GetValidProgram(context, program);
6245 if (!programObject)
6246 {
6247 return false;
6248 }
6249
6250 return true;
6251}
6252
Jamie Madill4928b7c2017-06-20 12:57:39 -04006253bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006254 GLint x,
6255 GLint y,
6256 GLsizei width,
6257 GLsizei height,
6258 GLenum format,
6259 GLenum type,
6260 void *pixels)
6261{
6262 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6263 nullptr, pixels);
6264}
6265
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006266bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006267{
6268 return ValidateTexParameterBase(context, target, pname, -1, &param);
6269}
6270
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006271bool ValidateTexParameterfv(Context *context,
6272 TextureType target,
6273 GLenum pname,
6274 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006275{
6276 return ValidateTexParameterBase(context, target, pname, -1, params);
6277}
6278
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006279bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006280{
6281 return ValidateTexParameterBase(context, target, pname, -1, &param);
6282}
6283
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006284bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006285{
6286 return ValidateTexParameterBase(context, target, pname, -1, params);
6287}
6288
6289bool ValidateUseProgram(Context *context, GLuint program)
6290{
6291 if (program != 0)
6292 {
6293 Program *programObject = context->getProgram(program);
6294 if (!programObject)
6295 {
6296 // ES 3.1.0 section 7.3 page 72
6297 if (context->getShader(program))
6298 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006299 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006300 return false;
6301 }
6302 else
6303 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006304 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006305 return false;
6306 }
6307 }
6308 if (!programObject->isLinked())
6309 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006310 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006311 return false;
6312 }
6313 }
6314 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6315 {
6316 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006317 context
6318 ->handleError(InvalidOperation()
6319 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006320 return false;
6321 }
6322
6323 return true;
6324}
6325
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006326bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6327{
6328 if (!context->getExtensions().fence)
6329 {
6330 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6331 return false;
6332 }
6333
6334 if (n < 0)
6335 {
6336 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6337 return false;
6338 }
6339
6340 return true;
6341}
6342
6343bool ValidateFinishFenceNV(Context *context, GLuint fence)
6344{
6345 if (!context->getExtensions().fence)
6346 {
6347 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6348 return false;
6349 }
6350
6351 FenceNV *fenceObject = context->getFenceNV(fence);
6352
6353 if (fenceObject == nullptr)
6354 {
6355 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6356 return false;
6357 }
6358
6359 if (!fenceObject->isSet())
6360 {
6361 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6362 return false;
6363 }
6364
6365 return true;
6366}
6367
6368bool ValidateGenFencesNV(Context *context, GLsizei n, 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 ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
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 switch (pname)
6408 {
6409 case GL_FENCE_STATUS_NV:
6410 case GL_FENCE_CONDITION_NV:
6411 break;
6412
6413 default:
6414 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6415 return false;
6416 }
6417
6418 return true;
6419}
6420
6421bool ValidateGetGraphicsResetStatusEXT(Context *context)
6422{
6423 if (!context->getExtensions().robustness)
6424 {
6425 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6426 return false;
6427 }
6428
6429 return true;
6430}
6431
6432bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6433 GLuint shader,
6434 GLsizei bufsize,
6435 GLsizei *length,
6436 GLchar *source)
6437{
6438 if (!context->getExtensions().translatedShaderSource)
6439 {
6440 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6441 return false;
6442 }
6443
6444 if (bufsize < 0)
6445 {
6446 context->handleError(InvalidValue());
6447 return false;
6448 }
6449
6450 Shader *shaderObject = context->getShader(shader);
6451
6452 if (!shaderObject)
6453 {
6454 context->handleError(InvalidOperation());
6455 return false;
6456 }
6457
6458 return true;
6459}
6460
6461bool ValidateIsFenceNV(Context *context, GLuint fence)
6462{
6463 if (!context->getExtensions().fence)
6464 {
6465 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6466 return false;
6467 }
6468
6469 return true;
6470}
6471
Jamie Madill007530e2017-12-28 14:27:04 -05006472bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6473{
6474 if (!context->getExtensions().fence)
6475 {
6476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6477 return false;
6478 }
6479
6480 if (condition != GL_ALL_COMPLETED_NV)
6481 {
6482 context->handleError(InvalidEnum());
6483 return false;
6484 }
6485
6486 FenceNV *fenceObject = context->getFenceNV(fence);
6487
6488 if (fenceObject == nullptr)
6489 {
6490 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6491 return false;
6492 }
6493
6494 return true;
6495}
6496
6497bool ValidateTestFenceNV(Context *context, GLuint fence)
6498{
6499 if (!context->getExtensions().fence)
6500 {
6501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6502 return false;
6503 }
6504
6505 FenceNV *fenceObject = context->getFenceNV(fence);
6506
6507 if (fenceObject == nullptr)
6508 {
6509 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6510 return false;
6511 }
6512
6513 if (fenceObject->isSet() != GL_TRUE)
6514 {
6515 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6516 return false;
6517 }
6518
6519 return true;
6520}
6521
6522bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006523 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006524 GLsizei levels,
6525 GLenum internalformat,
6526 GLsizei width,
6527 GLsizei height)
6528{
6529 if (!context->getExtensions().textureStorage)
6530 {
6531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6532 return false;
6533 }
6534
6535 if (context->getClientMajorVersion() < 3)
6536 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006537 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006538 height);
6539 }
6540
6541 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006542 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006543 1);
6544}
6545
6546bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6547{
6548 if (!context->getExtensions().instancedArrays)
6549 {
6550 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6551 return false;
6552 }
6553
6554 if (index >= MAX_VERTEX_ATTRIBS)
6555 {
6556 context->handleError(InvalidValue());
6557 return false;
6558 }
6559
6560 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6561 {
6562 if (index == 0 && divisor != 0)
6563 {
6564 const char *errorMessage =
6565 "The current context doesn't support setting a non-zero divisor on the "
6566 "attribute with index zero. "
6567 "Please reorder the attributes in your vertex shader so that attribute zero "
6568 "can have a zero divisor.";
6569 context->handleError(InvalidOperation() << errorMessage);
6570
6571 // We also output an error message to the debugger window if tracing is active, so
6572 // that developers can see the error message.
6573 ERR() << errorMessage;
6574 return false;
6575 }
6576 }
6577
6578 return true;
6579}
6580
6581bool ValidateTexImage3DOES(Context *context,
6582 GLenum target,
6583 GLint level,
6584 GLenum internalformat,
6585 GLsizei width,
6586 GLsizei height,
6587 GLsizei depth,
6588 GLint border,
6589 GLenum format,
6590 GLenum type,
6591 const void *pixels)
6592{
6593 UNIMPLEMENTED(); // FIXME
6594 return false;
6595}
6596
6597bool ValidatePopGroupMarkerEXT(Context *context)
6598{
6599 if (!context->getExtensions().debugMarker)
6600 {
6601 // The debug marker calls should not set error state
6602 // However, it seems reasonable to set an error state if the extension is not enabled
6603 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6604 return false;
6605 }
6606
6607 return true;
6608}
6609
Jamie Madillfa920eb2018-01-04 11:45:50 -05006610bool ValidateTexStorage1DEXT(Context *context,
6611 GLenum target,
6612 GLsizei levels,
6613 GLenum internalformat,
6614 GLsizei width)
6615{
6616 UNIMPLEMENTED();
6617 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6618 return false;
6619}
6620
6621bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006622 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006623 GLsizei levels,
6624 GLenum internalformat,
6625 GLsizei width,
6626 GLsizei height,
6627 GLsizei depth)
6628{
6629 if (!context->getExtensions().textureStorage)
6630 {
6631 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6632 return false;
6633 }
6634
6635 if (context->getClientMajorVersion() < 3)
6636 {
6637 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6638 return false;
6639 }
6640
6641 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6642 depth);
6643}
6644
Jamie Madillc29968b2016-01-20 11:17:23 -05006645} // namespace gl