blob: 5433c43e54f518605f9cdfd9bc10c4ecc6711fc6 [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 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700291 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400292 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700293 }
294
Geoff Langc0094ec2017-08-16 14:16:24 -0400295 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
296 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700297 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Langc0094ec2017-08-16 14:16:24 -0400298 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 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700304 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400305 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700306 }
307
308 return true;
309}
310
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800311bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700312{
313 switch (target)
314 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800315 case TextureTarget::_2D:
316 case TextureTarget::CubeMapNegativeX:
317 case TextureTarget::CubeMapNegativeY:
318 case TextureTarget::CubeMapNegativeZ:
319 case TextureTarget::CubeMapPositiveX:
320 case TextureTarget::CubeMapPositiveY:
321 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400322 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700323
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800324 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400325 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700326
327 default:
328 return false;
329 }
330}
331
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800332bool IsValidCopyTextureDestinationTarget(Context *context,
333 TextureType textureType,
334 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400335{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800336 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400337}
338
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800339bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700340{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800341 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700342 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800343 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400344 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800345 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400346 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400347
348 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
349 // supported
350
351 default:
352 return false;
353 }
354}
355
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800356bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400357{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800358 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400359 {
360 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700361 }
362
Geoff Lang4f0e0032017-05-01 16:04:35 -0400363 if (level > 0 && context->getClientVersion() < ES_3_0)
364 {
365 return false;
366 }
Geoff Lang97073d12016-04-20 10:42:34 -0700367
Geoff Lang4f0e0032017-05-01 16:04:35 -0400368 return true;
369}
370
371bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800372 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400373 GLint level,
374 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800375 GLsizei height,
376 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400377{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800378 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400379 {
380 return false;
381 }
382
Brandon Jones28783792018-03-05 09:37:32 -0800383 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
384 {
385 return false;
386 }
387
Geoff Lang4f0e0032017-05-01 16:04:35 -0400388 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800389 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400390 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800391 case TextureType::_2D:
392 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
393 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
394 case TextureType::Rectangle:
395 ASSERT(level == 0);
396 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
397 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400398
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800399 case TextureType::CubeMap:
400 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
401 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
402 default:
403 return true;
404 }
Geoff Lang97073d12016-04-20 10:42:34 -0700405}
406
Jamie Madillc1d770e2017-04-13 17:31:24 -0400407bool IsValidStencilFunc(GLenum func)
408{
409 switch (func)
410 {
411 case GL_NEVER:
412 case GL_ALWAYS:
413 case GL_LESS:
414 case GL_LEQUAL:
415 case GL_EQUAL:
416 case GL_GEQUAL:
417 case GL_GREATER:
418 case GL_NOTEQUAL:
419 return true;
420
421 default:
422 return false;
423 }
424}
425
426bool IsValidStencilFace(GLenum face)
427{
428 switch (face)
429 {
430 case GL_FRONT:
431 case GL_BACK:
432 case GL_FRONT_AND_BACK:
433 return true;
434
435 default:
436 return false;
437 }
438}
439
440bool IsValidStencilOp(GLenum op)
441{
442 switch (op)
443 {
444 case GL_ZERO:
445 case GL_KEEP:
446 case GL_REPLACE:
447 case GL_INCR:
448 case GL_DECR:
449 case GL_INVERT:
450 case GL_INCR_WRAP:
451 case GL_DECR_WRAP:
452 return true;
453
454 default:
455 return false;
456 }
457}
458
Jamie Madill5b772312018-03-08 20:28:32 -0500459bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800460 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400461 GLint level,
462 GLenum internalformat,
463 bool isSubImage,
464 GLint xoffset,
465 GLint yoffset,
466 GLint x,
467 GLint y,
468 GLsizei width,
469 GLsizei height,
470 GLint border)
471{
472 if (!ValidTexture2DDestinationTarget(context, target))
473 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700474 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400475 return false;
476 }
477
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800478 TextureType texType = TextureTargetToType(target);
479 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400480 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500481 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400482 return false;
483 }
484
485 Format textureFormat = Format::Invalid();
486 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
487 xoffset, yoffset, 0, x, y, width, height, border,
488 &textureFormat))
489 {
490 return false;
491 }
492
493 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
494 GLenum colorbufferFormat =
495 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
496 const auto &formatInfo = *textureFormat.info;
497
498 // [OpenGL ES 2.0.24] table 3.9
499 if (isSubImage)
500 {
501 switch (formatInfo.format)
502 {
503 case GL_ALPHA:
504 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400505 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
506 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400507 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400509 return false;
510 }
511 break;
512 case GL_LUMINANCE:
513 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
514 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
515 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400516 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
517 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400518 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700519 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400520 return false;
521 }
522 break;
523 case GL_RED_EXT:
524 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
525 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
526 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
527 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
528 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400529 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
530 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400531 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700532 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400533 return false;
534 }
535 break;
536 case GL_RG_EXT:
537 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
538 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
539 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
540 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400541 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
542 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400543 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700544 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400545 return false;
546 }
547 break;
548 case GL_RGB:
549 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
550 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
551 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400552 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
553 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400554 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700555 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400556 return false;
557 }
558 break;
559 case GL_LUMINANCE_ALPHA:
560 case GL_RGBA:
561 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400562 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
563 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400564 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700565 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400566 return false;
567 }
568 break;
569 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
571 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
572 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
573 case GL_ETC1_RGB8_OES:
574 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
575 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
578 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700579 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400580 return false;
581 case GL_DEPTH_COMPONENT:
582 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700583 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400584 return false;
585 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700586 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400587 return false;
588 }
589
590 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
591 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700592 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400593 return false;
594 }
595 }
596 else
597 {
598 switch (internalformat)
599 {
600 case GL_ALPHA:
601 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
602 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
603 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
604 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700605 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400606 return false;
607 }
608 break;
609 case GL_LUMINANCE:
610 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
611 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
612 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
613 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
614 colorbufferFormat != GL_BGR5_A1_ANGLEX)
615 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700616 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400617 return false;
618 }
619 break;
620 case GL_RED_EXT:
621 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
622 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
623 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
624 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
625 colorbufferFormat != GL_BGR5_A1_ANGLEX)
626 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700627 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400628 return false;
629 }
630 break;
631 case GL_RG_EXT:
632 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
633 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
634 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
635 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
636 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700637 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400638 return false;
639 }
640 break;
641 case GL_RGB:
642 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
643 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
644 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
645 colorbufferFormat != GL_BGR5_A1_ANGLEX)
646 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700647 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400648 return false;
649 }
650 break;
651 case GL_LUMINANCE_ALPHA:
652 case GL_RGBA:
653 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
654 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
655 colorbufferFormat != GL_BGR5_A1_ANGLEX)
656 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700657 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400658 return false;
659 }
660 break;
661 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
662 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
663 if (context->getExtensions().textureCompressionDXT1)
664 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700665 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400666 return false;
667 }
668 else
669 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700670 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400671 return false;
672 }
673 break;
674 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
675 if (context->getExtensions().textureCompressionDXT3)
676 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700677 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400678 return false;
679 }
680 else
681 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700682 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400683 return false;
684 }
685 break;
686 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
687 if (context->getExtensions().textureCompressionDXT5)
688 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700689 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400690 return false;
691 }
692 else
693 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700694 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400695 return false;
696 }
697 break;
698 case GL_ETC1_RGB8_OES:
699 if (context->getExtensions().compressedETC1RGB8Texture)
700 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500701 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400702 return false;
703 }
704 else
705 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500706 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400707 return false;
708 }
709 break;
710 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
711 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
715 if (context->getExtensions().lossyETCDecode)
716 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500717 context->handleError(InvalidOperation()
718 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400719 return false;
720 }
721 else
722 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500723 context->handleError(InvalidEnum()
724 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400725 return false;
726 }
727 break;
728 case GL_DEPTH_COMPONENT:
729 case GL_DEPTH_COMPONENT16:
730 case GL_DEPTH_COMPONENT32_OES:
731 case GL_DEPTH_STENCIL_OES:
732 case GL_DEPTH24_STENCIL8_OES:
733 if (context->getExtensions().depthTextures)
734 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500735 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400736 return false;
737 }
738 else
739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500740 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400741 return false;
742 }
743 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500744 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400745 return false;
746 }
747 }
748
749 // If width or height is zero, it is a no-op. Return false without setting an error.
750 return (width > 0 && height > 0);
751}
752
753bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
754{
755 switch (cap)
756 {
757 // EXT_multisample_compatibility
758 case GL_MULTISAMPLE_EXT:
759 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
760 return context->getExtensions().multisampleCompatibility;
761
762 case GL_CULL_FACE:
763 case GL_POLYGON_OFFSET_FILL:
764 case GL_SAMPLE_ALPHA_TO_COVERAGE:
765 case GL_SAMPLE_COVERAGE:
766 case GL_SCISSOR_TEST:
767 case GL_STENCIL_TEST:
768 case GL_DEPTH_TEST:
769 case GL_BLEND:
770 case GL_DITHER:
771 return true;
772
773 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
774 case GL_RASTERIZER_DISCARD:
775 return (context->getClientMajorVersion() >= 3);
776
777 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
778 case GL_DEBUG_OUTPUT:
779 return context->getExtensions().debug;
780
781 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
782 return queryOnly && context->getExtensions().bindGeneratesResource;
783
784 case GL_CLIENT_ARRAYS_ANGLE:
785 return queryOnly && context->getExtensions().clientArrays;
786
787 case GL_FRAMEBUFFER_SRGB_EXT:
788 return context->getExtensions().sRGBWriteControl;
789
790 case GL_SAMPLE_MASK:
791 return context->getClientVersion() >= Version(3, 1);
792
Geoff Langb433e872017-10-05 14:01:47 -0400793 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400794 return queryOnly && context->getExtensions().robustResourceInitialization;
795
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700796 // GLES1 emulation: GLES1-specific caps
797 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700798 case GL_VERTEX_ARRAY:
799 case GL_NORMAL_ARRAY:
800 case GL_COLOR_ARRAY:
801 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700802 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700803 case GL_LIGHTING:
804 case GL_LIGHT0:
805 case GL_LIGHT1:
806 case GL_LIGHT2:
807 case GL_LIGHT3:
808 case GL_LIGHT4:
809 case GL_LIGHT5:
810 case GL_LIGHT6:
811 case GL_LIGHT7:
812 case GL_NORMALIZE:
813 case GL_RESCALE_NORMAL:
814 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700815 case GL_CLIP_PLANE0:
816 case GL_CLIP_PLANE1:
817 case GL_CLIP_PLANE2:
818 case GL_CLIP_PLANE3:
819 case GL_CLIP_PLANE4:
820 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700821 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700822 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700823 case GL_LINE_SMOOTH:
824 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700825 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700826 case GL_POINT_SIZE_ARRAY_OES:
827 return context->getClientVersion() < Version(2, 0) &&
828 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700829 case GL_TEXTURE_CUBE_MAP:
830 return context->getClientVersion() < Version(2, 0) &&
831 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700832 case GL_POINT_SPRITE_OES:
833 return context->getClientVersion() < Version(2, 0) &&
834 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400835 default:
836 return false;
837 }
838}
839
Geoff Langfc32e8b2017-05-31 14:16:59 -0400840// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
841// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400842bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400843{
844 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400845 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
846 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400847 {
848 return true;
849 }
850
851 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
852 if (c >= 9 && c <= 13)
853 {
854 return true;
855 }
856
857 return false;
858}
859
Geoff Langcab92ee2017-07-19 17:32:07 -0400860bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400861{
Geoff Langa71a98e2017-06-19 15:15:00 -0400862 for (size_t i = 0; i < len; i++)
863 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400864 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400865 {
866 return false;
867 }
868 }
869
870 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400871}
872
Geoff Langcab92ee2017-07-19 17:32:07 -0400873bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
874{
875 enum class ParseState
876 {
877 // Have not seen an ASCII non-whitespace character yet on
878 // this line. Possible that we might see a preprocessor
879 // directive.
880 BEGINING_OF_LINE,
881
882 // Have seen at least one ASCII non-whitespace character
883 // on this line.
884 MIDDLE_OF_LINE,
885
886 // Handling a preprocessor directive. Passes through all
887 // characters up to the end of the line. Disables comment
888 // processing.
889 IN_PREPROCESSOR_DIRECTIVE,
890
891 // Handling a single-line comment. The comment text is
892 // replaced with a single space.
893 IN_SINGLE_LINE_COMMENT,
894
895 // Handling a multi-line comment. Newlines are passed
896 // through to preserve line numbers.
897 IN_MULTI_LINE_COMMENT
898 };
899
900 ParseState state = ParseState::BEGINING_OF_LINE;
901 size_t pos = 0;
902
903 while (pos < len)
904 {
905 char c = str[pos];
906 char next = pos + 1 < len ? str[pos + 1] : 0;
907
908 // Check for newlines
909 if (c == '\n' || c == '\r')
910 {
911 if (state != ParseState::IN_MULTI_LINE_COMMENT)
912 {
913 state = ParseState::BEGINING_OF_LINE;
914 }
915
916 pos++;
917 continue;
918 }
919
920 switch (state)
921 {
922 case ParseState::BEGINING_OF_LINE:
923 if (c == ' ')
924 {
925 // Maintain the BEGINING_OF_LINE state until a non-space is seen
926 pos++;
927 }
928 else if (c == '#')
929 {
930 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
931 pos++;
932 }
933 else
934 {
935 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
936 state = ParseState::MIDDLE_OF_LINE;
937 }
938 break;
939
940 case ParseState::MIDDLE_OF_LINE:
941 if (c == '/' && next == '/')
942 {
943 state = ParseState::IN_SINGLE_LINE_COMMENT;
944 pos++;
945 }
946 else if (c == '/' && next == '*')
947 {
948 state = ParseState::IN_MULTI_LINE_COMMENT;
949 pos++;
950 }
951 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
952 {
953 // Skip line continuation characters
954 }
955 else if (!IsValidESSLCharacter(c))
956 {
957 return false;
958 }
959 pos++;
960 break;
961
962 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700963 // Line-continuation characters may not be permitted.
964 // Otherwise, just pass it through. Do not parse comments in this state.
965 if (!lineContinuationAllowed && c == '\\')
966 {
967 return false;
968 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400969 pos++;
970 break;
971
972 case ParseState::IN_SINGLE_LINE_COMMENT:
973 // Line-continuation characters are processed before comment processing.
974 // Advance string if a new line character is immediately behind
975 // line-continuation character.
976 if (c == '\\' && (next == '\n' || next == '\r'))
977 {
978 pos++;
979 }
980 pos++;
981 break;
982
983 case ParseState::IN_MULTI_LINE_COMMENT:
984 if (c == '*' && next == '/')
985 {
986 state = ParseState::MIDDLE_OF_LINE;
987 pos++;
988 }
989 pos++;
990 break;
991 }
992 }
993
994 return true;
995}
996
Jamie Madill5b772312018-03-08 20:28:32 -0500997bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700998{
999 ASSERT(context->isWebGL());
1000
1001 // WebGL 1.0 [Section 6.16] GLSL Constructs
1002 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1003 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1004 {
1005 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1006 return false;
1007 }
1008
1009 return true;
1010}
1011
Jamie Madill5b772312018-03-08 20:28:32 -05001012bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001013{
1014 ASSERT(context->isWebGL());
1015
1016 if (context->isWebGL1() && length > 256)
1017 {
1018 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1019 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1020 // locations.
1021 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1022
1023 return false;
1024 }
1025 else if (length > 1024)
1026 {
1027 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1028 // uniform and attribute locations.
1029 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1030 return false;
1031 }
1032
1033 return true;
1034}
1035
Jamie Madill007530e2017-12-28 14:27:04 -05001036bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1037{
1038 if (!context->getExtensions().pathRendering)
1039 {
1040 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1041 return false;
1042 }
1043
1044 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1045 {
1046 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1047 return false;
1048 }
1049 return true;
1050}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001051
1052bool ValidBlendFunc(const Context *context, GLenum val)
1053{
1054 const gl::Extensions &ext = context->getExtensions();
1055
1056 // these are always valid for src and dst.
1057 switch (val)
1058 {
1059 case GL_ZERO:
1060 case GL_ONE:
1061 case GL_SRC_COLOR:
1062 case GL_ONE_MINUS_SRC_COLOR:
1063 case GL_DST_COLOR:
1064 case GL_ONE_MINUS_DST_COLOR:
1065 case GL_SRC_ALPHA:
1066 case GL_ONE_MINUS_SRC_ALPHA:
1067 case GL_DST_ALPHA:
1068 case GL_ONE_MINUS_DST_ALPHA:
1069 case GL_CONSTANT_COLOR:
1070 case GL_ONE_MINUS_CONSTANT_COLOR:
1071 case GL_CONSTANT_ALPHA:
1072 case GL_ONE_MINUS_CONSTANT_ALPHA:
1073 return true;
1074
1075 // EXT_blend_func_extended.
1076 case GL_SRC1_COLOR_EXT:
1077 case GL_SRC1_ALPHA_EXT:
1078 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1079 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1080 case GL_SRC_ALPHA_SATURATE_EXT:
1081 return ext.blendFuncExtended;
1082
1083 default:
1084 return false;
1085 }
1086}
1087
1088bool ValidSrcBlendFunc(const Context *context, GLenum val)
1089{
1090 if (ValidBlendFunc(context, val))
1091 return true;
1092
1093 if (val == GL_SRC_ALPHA_SATURATE)
1094 return true;
1095
1096 return false;
1097}
1098
1099bool ValidDstBlendFunc(const Context *context, GLenum val)
1100{
1101 if (ValidBlendFunc(context, val))
1102 return true;
1103
1104 if (val == GL_SRC_ALPHA_SATURATE)
1105 {
1106 if (context->getClientMajorVersion() >= 3)
1107 return true;
1108 }
1109
1110 return false;
1111}
1112
Jamie Madillc29968b2016-01-20 11:17:23 -05001113} // anonymous namespace
1114
Geoff Langff5b2d52016-09-07 11:32:23 -04001115bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001116 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001117 GLint level,
1118 GLenum internalformat,
1119 bool isCompressed,
1120 bool isSubImage,
1121 GLint xoffset,
1122 GLint yoffset,
1123 GLsizei width,
1124 GLsizei height,
1125 GLint border,
1126 GLenum format,
1127 GLenum type,
1128 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001129 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001130{
Jamie Madill6f38f822014-06-06 17:12:20 -04001131 if (!ValidTexture2DDestinationTarget(context, target))
1132 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001133 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001134 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001135 }
1136
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001137 TextureType texType = TextureTargetToType(target);
1138 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001140 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001141 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001142 }
1143
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001144 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001145 {
1146 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1147 return false;
1148 }
1149
1150 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001151 std::numeric_limits<GLsizei>::max() - yoffset < height)
1152 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001153 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001154 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001155 }
1156
Geoff Lang6e898aa2017-06-02 11:17:26 -04001157 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1158 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1159 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1160 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1161 // case.
1162 bool nonEqualFormatsAllowed =
1163 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1164 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1165
1166 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001168 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001169 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001170 }
1171
Geoff Langaae65a42014-05-26 12:43:44 -04001172 const gl::Caps &caps = context->getCaps();
1173
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001174 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001175 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001176 case TextureType::_2D:
1177 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1178 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1179 {
1180 context->handleError(InvalidValue());
1181 return false;
1182 }
1183 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001185 case TextureType::Rectangle:
1186 ASSERT(level == 0);
1187 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1188 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1189 {
1190 context->handleError(InvalidValue());
1191 return false;
1192 }
1193 if (isCompressed)
1194 {
1195 context->handleError(InvalidEnum()
1196 << "Rectangle texture cannot have a compressed format.");
1197 return false;
1198 }
1199 break;
1200
1201 case TextureType::CubeMap:
1202 if (!isSubImage && width != height)
1203 {
1204 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1205 return false;
1206 }
1207
1208 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1209 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1210 {
1211 context->handleError(InvalidValue());
1212 return false;
1213 }
1214 break;
1215
1216 default:
1217 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001218 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001219 }
1220
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001221 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001222 if (!texture)
1223 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001224 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001225 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001226 }
1227
Geoff Langa9be0dc2014-12-17 12:34:40 -05001228 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001229 {
Geoff Langca271392017-04-05 12:30:00 -04001230 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1231 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001232 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001233 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001234 return false;
1235 }
1236
Geoff Langa9be0dc2014-12-17 12:34:40 -05001237 if (format != GL_NONE)
1238 {
Geoff Langca271392017-04-05 12:30:00 -04001239 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1240 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001241 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001242 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001243 return false;
1244 }
1245 }
1246
1247 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1248 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1249 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001250 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001251 return false;
1252 }
Geoff Langfb052642017-10-24 13:42:09 -04001253
1254 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001255 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001256 {
1257 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1258 return false;
1259 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001260 }
1261 else
1262 {
Geoff Lang69cce582015-09-17 13:20:36 -04001263 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001264 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001265 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001266 return false;
1267 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001268 }
1269
1270 // Verify zero border
1271 if (border != 0)
1272 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001273 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001274 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001275 }
1276
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001277 if (isCompressed)
1278 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001279 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001280 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1281 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001282
1283 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1284
1285 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001286 {
Geoff Lange88e4542018-05-03 15:05:57 -04001287 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1288 return false;
1289 }
1290
1291 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1292 context->getExtensions()))
1293 {
1294 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1295 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001296 }
Geoff Lang966c9402017-04-18 12:38:27 -04001297
1298 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001299 {
Geoff Lange88e4542018-05-03 15:05:57 -04001300 // From the OES_compressed_ETC1_RGB8_texture spec:
1301 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1302 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1303 // ETC1_RGB8_OES.
1304 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1305 {
1306 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1307 return false;
1308 }
1309
Geoff Lang966c9402017-04-18 12:38:27 -04001310 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1311 height, texture->getWidth(target, level),
1312 texture->getHeight(target, level)))
1313 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001314 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001315 return false;
1316 }
1317
1318 if (format != actualInternalFormat)
1319 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001320 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001321 return false;
1322 }
1323 }
1324 else
1325 {
1326 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1327 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001328 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001329 return false;
1330 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001331 }
1332 }
1333 else
1334 {
1335 // validate <type> by itself (used as secondary key below)
1336 switch (type)
1337 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001338 case GL_UNSIGNED_BYTE:
1339 case GL_UNSIGNED_SHORT_5_6_5:
1340 case GL_UNSIGNED_SHORT_4_4_4_4:
1341 case GL_UNSIGNED_SHORT_5_5_5_1:
1342 case GL_UNSIGNED_SHORT:
1343 case GL_UNSIGNED_INT:
1344 case GL_UNSIGNED_INT_24_8_OES:
1345 case GL_HALF_FLOAT_OES:
1346 case GL_FLOAT:
1347 break;
1348 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001349 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001350 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001351 }
1352
1353 // validate <format> + <type> combinations
1354 // - invalid <format> -> sets INVALID_ENUM
1355 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1356 switch (format)
1357 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001358 case GL_ALPHA:
1359 case GL_LUMINANCE:
1360 case GL_LUMINANCE_ALPHA:
1361 switch (type)
1362 {
1363 case GL_UNSIGNED_BYTE:
1364 case GL_FLOAT:
1365 case GL_HALF_FLOAT_OES:
1366 break;
1367 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 return false;
1370 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001371 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001372 case GL_RED:
1373 case GL_RG:
1374 if (!context->getExtensions().textureRG)
1375 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001376 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001377 return false;
1378 }
1379 switch (type)
1380 {
1381 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001382 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001383 case GL_FLOAT:
1384 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001385 if (!context->getExtensions().textureFloat)
1386 {
1387 context->handleError(InvalidEnum());
1388 return false;
1389 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001390 break;
1391 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001392 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001393 return false;
1394 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001395 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001396 case GL_RGB:
1397 switch (type)
1398 {
1399 case GL_UNSIGNED_BYTE:
1400 case GL_UNSIGNED_SHORT_5_6_5:
1401 case GL_FLOAT:
1402 case GL_HALF_FLOAT_OES:
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 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001408 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001409 case GL_RGBA:
1410 switch (type)
1411 {
1412 case GL_UNSIGNED_BYTE:
1413 case GL_UNSIGNED_SHORT_4_4_4_4:
1414 case GL_UNSIGNED_SHORT_5_5_5_1:
1415 case GL_FLOAT:
1416 case GL_HALF_FLOAT_OES:
1417 break;
1418 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001419 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001420 return false;
1421 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001422 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001423 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001424 if (!context->getExtensions().textureFormatBGRA8888)
1425 {
1426 context->handleError(InvalidEnum());
1427 return false;
1428 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001429 switch (type)
1430 {
1431 case GL_UNSIGNED_BYTE:
1432 break;
1433 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001434 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001435 return false;
1436 }
1437 break;
1438 case GL_SRGB_EXT:
1439 case GL_SRGB_ALPHA_EXT:
1440 if (!context->getExtensions().sRGB)
1441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001442 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 switch (type)
1446 {
1447 case GL_UNSIGNED_BYTE:
1448 break;
1449 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001450 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 return false;
1452 }
1453 break;
1454 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1455 // handled below
1456 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1457 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1458 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1459 break;
1460 case GL_DEPTH_COMPONENT:
1461 switch (type)
1462 {
1463 case GL_UNSIGNED_SHORT:
1464 case GL_UNSIGNED_INT:
1465 break;
1466 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001467 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 return false;
1469 }
1470 break;
1471 case GL_DEPTH_STENCIL_OES:
1472 switch (type)
1473 {
1474 case GL_UNSIGNED_INT_24_8_OES:
1475 break;
1476 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001477 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001478 return false;
1479 }
1480 break;
1481 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001482 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001483 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001484 }
1485
1486 switch (format)
1487 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001488 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1489 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1490 if (context->getExtensions().textureCompressionDXT1)
1491 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001492 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001493 return false;
1494 }
1495 else
1496 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001497 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001498 return false;
1499 }
1500 break;
1501 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1502 if (context->getExtensions().textureCompressionDXT3)
1503 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001504 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001505 return false;
1506 }
1507 else
1508 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001509 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001510 return false;
1511 }
1512 break;
1513 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1514 if (context->getExtensions().textureCompressionDXT5)
1515 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001516 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001517 return false;
1518 }
1519 else
1520 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001521 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001522 return false;
1523 }
1524 break;
1525 case GL_ETC1_RGB8_OES:
1526 if (context->getExtensions().compressedETC1RGB8Texture)
1527 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001528 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001529 return false;
1530 }
1531 else
1532 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001533 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001534 return false;
1535 }
1536 break;
1537 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001538 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1539 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1540 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1541 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001542 if (context->getExtensions().lossyETCDecode)
1543 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001544 context->handleError(InvalidOperation()
1545 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001546 return false;
1547 }
1548 else
1549 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001550 context->handleError(InvalidEnum()
1551 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001552 return false;
1553 }
1554 break;
1555 case GL_DEPTH_COMPONENT:
1556 case GL_DEPTH_STENCIL_OES:
1557 if (!context->getExtensions().depthTextures)
1558 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001559 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001560 return false;
1561 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001562 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001563 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001564 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001565 return false;
1566 }
1567 // OES_depth_texture supports loading depth data and multiple levels,
1568 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001569 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001570 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001571 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1572 return false;
1573 }
1574 if (level != 0)
1575 {
1576 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001577 return false;
1578 }
1579 break;
1580 default:
1581 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001582 }
1583
Geoff Lang6e898aa2017-06-02 11:17:26 -04001584 if (!isSubImage)
1585 {
1586 switch (internalformat)
1587 {
1588 case GL_RGBA32F:
1589 if (!context->getExtensions().colorBufferFloatRGBA)
1590 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001591 context->handleError(InvalidValue()
1592 << "Sized GL_RGBA32F internal format requires "
1593 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001594 return false;
1595 }
1596 if (type != GL_FLOAT)
1597 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001598 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001599 return false;
1600 }
1601 if (format != GL_RGBA)
1602 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001603 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001604 return false;
1605 }
1606 break;
1607
1608 case GL_RGB32F:
1609 if (!context->getExtensions().colorBufferFloatRGB)
1610 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001611 context->handleError(InvalidValue()
1612 << "Sized GL_RGB32F internal format requires "
1613 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001614 return false;
1615 }
1616 if (type != GL_FLOAT)
1617 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001618 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001619 return false;
1620 }
1621 if (format != GL_RGB)
1622 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001623 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001624 return false;
1625 }
1626 break;
1627
1628 default:
1629 break;
1630 }
1631 }
1632
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 if (type == GL_FLOAT)
1634 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001635 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001637 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001638 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001639 }
1640 }
1641 else if (type == GL_HALF_FLOAT_OES)
1642 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001643 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001644 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001645 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001646 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001647 }
1648 }
1649 }
1650
Geoff Langdbcced82017-06-06 15:55:54 -04001651 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001652 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001653 imageSize))
1654 {
1655 return false;
1656 }
1657
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001658 return true;
1659}
1660
He Yunchaoced53ae2016-11-29 15:00:51 +08001661bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001662 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001663 GLsizei levels,
1664 GLenum internalformat,
1665 GLsizei width,
1666 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001667{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001668 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1669 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001670 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001671 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001672 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001673 }
1674
1675 if (width < 1 || height < 1 || levels < 1)
1676 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001677 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001678 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001679 }
1680
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001681 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001682 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001683 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001684 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001685 }
1686
1687 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1688 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001689 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001690 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001691 }
1692
Geoff Langca271392017-04-05 12:30:00 -04001693 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001694 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001695 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001696 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001697 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001698 }
1699
Geoff Langaae65a42014-05-26 12:43:44 -04001700 const gl::Caps &caps = context->getCaps();
1701
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001702 switch (target)
1703 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001704 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001705 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1706 static_cast<GLuint>(height) > caps.max2DTextureSize)
1707 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001708 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001709 return false;
1710 }
1711 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001712 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001713 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1714 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1715 {
1716 context->handleError(InvalidValue());
1717 return false;
1718 }
1719 if (formatInfo.compressed)
1720 {
1721 context->handleError(InvalidEnum()
1722 << "Rectangle texture cannot have a compressed format.");
1723 return false;
1724 }
1725 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001726 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001727 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1728 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1729 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001730 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001731 return false;
1732 }
1733 break;
1734 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001735 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001736 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001737 }
1738
Geoff Langc0b9ef42014-07-02 10:02:37 -04001739 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001740 {
1741 if (!gl::isPow2(width) || !gl::isPow2(height))
1742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001743 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001744 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001745 }
1746 }
1747
1748 switch (internalformat)
1749 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001750 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1751 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1752 if (!context->getExtensions().textureCompressionDXT1)
1753 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001754 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001755 return false;
1756 }
1757 break;
1758 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1759 if (!context->getExtensions().textureCompressionDXT3)
1760 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001761 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001762 return false;
1763 }
1764 break;
1765 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1766 if (!context->getExtensions().textureCompressionDXT5)
1767 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001768 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 return false;
1770 }
1771 break;
1772 case GL_ETC1_RGB8_OES:
1773 if (!context->getExtensions().compressedETC1RGB8Texture)
1774 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001775 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001776 return false;
1777 }
1778 break;
1779 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001780 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1781 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1782 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1783 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001784 if (!context->getExtensions().lossyETCDecode)
1785 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001786 context->handleError(InvalidEnum()
1787 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001788 return false;
1789 }
1790 break;
1791 case GL_RGBA32F_EXT:
1792 case GL_RGB32F_EXT:
1793 case GL_ALPHA32F_EXT:
1794 case GL_LUMINANCE32F_EXT:
1795 case GL_LUMINANCE_ALPHA32F_EXT:
1796 if (!context->getExtensions().textureFloat)
1797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001798 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001799 return false;
1800 }
1801 break;
1802 case GL_RGBA16F_EXT:
1803 case GL_RGB16F_EXT:
1804 case GL_ALPHA16F_EXT:
1805 case GL_LUMINANCE16F_EXT:
1806 case GL_LUMINANCE_ALPHA16F_EXT:
1807 if (!context->getExtensions().textureHalfFloat)
1808 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001809 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001810 return false;
1811 }
1812 break;
1813 case GL_R8_EXT:
1814 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001815 if (!context->getExtensions().textureRG)
1816 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001817 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001818 return false;
1819 }
1820 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001821 case GL_R16F_EXT:
1822 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001823 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1824 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001825 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001826 return false;
1827 }
1828 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001829 case GL_R32F_EXT:
1830 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001831 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001832 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001833 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001834 return false;
1835 }
1836 break;
1837 case GL_DEPTH_COMPONENT16:
1838 case GL_DEPTH_COMPONENT32_OES:
1839 case GL_DEPTH24_STENCIL8_OES:
1840 if (!context->getExtensions().depthTextures)
1841 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001842 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001843 return false;
1844 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001845 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001846 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001847 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001848 return false;
1849 }
1850 // ANGLE_depth_texture only supports 1-level textures
1851 if (levels != 1)
1852 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001853 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001854 return false;
1855 }
1856 break;
1857 default:
1858 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001859 }
1860
Geoff Lang691e58c2014-12-19 17:03:25 -05001861 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001862 if (!texture || texture->id() == 0)
1863 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001864 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001865 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001866 }
1867
Geoff Lang69cce582015-09-17 13:20:36 -04001868 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001869 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001870 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001871 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001872 }
1873
1874 return true;
1875}
1876
He Yunchaoced53ae2016-11-29 15:00:51 +08001877bool ValidateDiscardFramebufferEXT(Context *context,
1878 GLenum target,
1879 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001880 const GLenum *attachments)
1881{
Jamie Madillc29968b2016-01-20 11:17:23 -05001882 if (!context->getExtensions().discardFramebuffer)
1883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001884 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001885 return false;
1886 }
1887
Austin Kinross08332632015-05-05 13:35:47 -07001888 bool defaultFramebuffer = false;
1889
1890 switch (target)
1891 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001892 case GL_FRAMEBUFFER:
1893 defaultFramebuffer =
1894 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1895 break;
1896 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001897 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001898 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001899 }
1900
He Yunchaoced53ae2016-11-29 15:00:51 +08001901 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1902 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001903}
1904
Austin Kinrossbc781f32015-10-26 09:27:38 -07001905bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1906{
1907 if (!context->getExtensions().vertexArrayObject)
1908 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001909 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001910 return false;
1911 }
1912
1913 return ValidateBindVertexArrayBase(context, array);
1914}
1915
Jamie Madilld7576732017-08-26 18:49:50 -04001916bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001917{
1918 if (!context->getExtensions().vertexArrayObject)
1919 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001920 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001921 return false;
1922 }
1923
Olli Etuaho41997e72016-03-10 13:38:39 +02001924 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001925}
1926
Jamie Madilld7576732017-08-26 18:49:50 -04001927bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001928{
1929 if (!context->getExtensions().vertexArrayObject)
1930 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001931 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001932 return false;
1933 }
1934
Olli Etuaho41997e72016-03-10 13:38:39 +02001935 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001936}
1937
Jamie Madilld7576732017-08-26 18:49:50 -04001938bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001939{
1940 if (!context->getExtensions().vertexArrayObject)
1941 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001942 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001943 return false;
1944 }
1945
1946 return true;
1947}
Geoff Langc5629752015-12-07 16:29:04 -05001948
1949bool ValidateProgramBinaryOES(Context *context,
1950 GLuint program,
1951 GLenum binaryFormat,
1952 const void *binary,
1953 GLint length)
1954{
1955 if (!context->getExtensions().getProgramBinary)
1956 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001957 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001958 return false;
1959 }
1960
1961 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1962}
1963
1964bool ValidateGetProgramBinaryOES(Context *context,
1965 GLuint program,
1966 GLsizei bufSize,
1967 GLsizei *length,
1968 GLenum *binaryFormat,
1969 void *binary)
1970{
1971 if (!context->getExtensions().getProgramBinary)
1972 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001973 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001974 return false;
1975 }
1976
1977 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1978}
Geoff Lange102fee2015-12-10 11:23:30 -05001979
Geoff Lang70d0f492015-12-10 17:45:46 -05001980static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1981{
1982 switch (source)
1983 {
1984 case GL_DEBUG_SOURCE_API:
1985 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1986 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1987 case GL_DEBUG_SOURCE_OTHER:
1988 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1989 return !mustBeThirdPartyOrApplication;
1990
1991 case GL_DEBUG_SOURCE_THIRD_PARTY:
1992 case GL_DEBUG_SOURCE_APPLICATION:
1993 return true;
1994
1995 default:
1996 return false;
1997 }
1998}
1999
2000static bool ValidDebugType(GLenum type)
2001{
2002 switch (type)
2003 {
2004 case GL_DEBUG_TYPE_ERROR:
2005 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2006 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2007 case GL_DEBUG_TYPE_PERFORMANCE:
2008 case GL_DEBUG_TYPE_PORTABILITY:
2009 case GL_DEBUG_TYPE_OTHER:
2010 case GL_DEBUG_TYPE_MARKER:
2011 case GL_DEBUG_TYPE_PUSH_GROUP:
2012 case GL_DEBUG_TYPE_POP_GROUP:
2013 return true;
2014
2015 default:
2016 return false;
2017 }
2018}
2019
2020static bool ValidDebugSeverity(GLenum severity)
2021{
2022 switch (severity)
2023 {
2024 case GL_DEBUG_SEVERITY_HIGH:
2025 case GL_DEBUG_SEVERITY_MEDIUM:
2026 case GL_DEBUG_SEVERITY_LOW:
2027 case GL_DEBUG_SEVERITY_NOTIFICATION:
2028 return true;
2029
2030 default:
2031 return false;
2032 }
2033}
2034
Geoff Lange102fee2015-12-10 11:23:30 -05002035bool ValidateDebugMessageControlKHR(Context *context,
2036 GLenum source,
2037 GLenum type,
2038 GLenum severity,
2039 GLsizei count,
2040 const GLuint *ids,
2041 GLboolean enabled)
2042{
2043 if (!context->getExtensions().debug)
2044 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002045 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002046 return false;
2047 }
2048
Geoff Lang70d0f492015-12-10 17:45:46 -05002049 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2050 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002051 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002052 return false;
2053 }
2054
2055 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2056 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002057 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002058 return false;
2059 }
2060
2061 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2062 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002063 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002064 return false;
2065 }
2066
2067 if (count > 0)
2068 {
2069 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2070 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002071 context->handleError(
2072 InvalidOperation()
2073 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002074 return false;
2075 }
2076
2077 if (severity != GL_DONT_CARE)
2078 {
Jamie Madill437fa652016-05-03 15:13:24 -04002079 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002080 InvalidOperation()
2081 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002082 return false;
2083 }
2084 }
2085
Geoff Lange102fee2015-12-10 11:23:30 -05002086 return true;
2087}
2088
2089bool ValidateDebugMessageInsertKHR(Context *context,
2090 GLenum source,
2091 GLenum type,
2092 GLuint id,
2093 GLenum severity,
2094 GLsizei length,
2095 const GLchar *buf)
2096{
2097 if (!context->getExtensions().debug)
2098 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002099 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002100 return false;
2101 }
2102
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002103 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002104 {
2105 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2106 // not generate an error.
2107 return false;
2108 }
2109
2110 if (!ValidDebugSeverity(severity))
2111 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002112 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002113 return false;
2114 }
2115
2116 if (!ValidDebugType(type))
2117 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002118 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002119 return false;
2120 }
2121
2122 if (!ValidDebugSource(source, true))
2123 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002124 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002125 return false;
2126 }
2127
2128 size_t messageLength = (length < 0) ? strlen(buf) : length;
2129 if (messageLength > context->getExtensions().maxDebugMessageLength)
2130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002131 context->handleError(InvalidValue()
2132 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002133 return false;
2134 }
2135
Geoff Lange102fee2015-12-10 11:23:30 -05002136 return true;
2137}
2138
2139bool ValidateDebugMessageCallbackKHR(Context *context,
2140 GLDEBUGPROCKHR callback,
2141 const void *userParam)
2142{
2143 if (!context->getExtensions().debug)
2144 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002145 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002146 return false;
2147 }
2148
Geoff Lange102fee2015-12-10 11:23:30 -05002149 return true;
2150}
2151
2152bool ValidateGetDebugMessageLogKHR(Context *context,
2153 GLuint count,
2154 GLsizei bufSize,
2155 GLenum *sources,
2156 GLenum *types,
2157 GLuint *ids,
2158 GLenum *severities,
2159 GLsizei *lengths,
2160 GLchar *messageLog)
2161{
2162 if (!context->getExtensions().debug)
2163 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002164 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002165 return false;
2166 }
2167
Geoff Lang70d0f492015-12-10 17:45:46 -05002168 if (bufSize < 0 && messageLog != nullptr)
2169 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002170 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002171 return false;
2172 }
2173
Geoff Lange102fee2015-12-10 11:23:30 -05002174 return true;
2175}
2176
2177bool ValidatePushDebugGroupKHR(Context *context,
2178 GLenum source,
2179 GLuint id,
2180 GLsizei length,
2181 const GLchar *message)
2182{
2183 if (!context->getExtensions().debug)
2184 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002185 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002186 return false;
2187 }
2188
Geoff Lang70d0f492015-12-10 17:45:46 -05002189 if (!ValidDebugSource(source, true))
2190 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002191 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002192 return false;
2193 }
2194
2195 size_t messageLength = (length < 0) ? strlen(message) : length;
2196 if (messageLength > context->getExtensions().maxDebugMessageLength)
2197 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002198 context->handleError(InvalidValue()
2199 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002200 return false;
2201 }
2202
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002203 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002204 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002206 context
2207 ->handleError(StackOverflow()
2208 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002209 return false;
2210 }
2211
Geoff Lange102fee2015-12-10 11:23:30 -05002212 return true;
2213}
2214
2215bool ValidatePopDebugGroupKHR(Context *context)
2216{
2217 if (!context->getExtensions().debug)
2218 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002219 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002220 return false;
2221 }
2222
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002223 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002224 if (currentStackSize <= 1)
2225 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002226 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002227 return false;
2228 }
2229
2230 return true;
2231}
2232
2233static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2234{
2235 switch (identifier)
2236 {
2237 case GL_BUFFER:
2238 if (context->getBuffer(name) == nullptr)
2239 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002240 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002241 return false;
2242 }
2243 return true;
2244
2245 case GL_SHADER:
2246 if (context->getShader(name) == nullptr)
2247 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002248 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002249 return false;
2250 }
2251 return true;
2252
2253 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002254 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002255 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002256 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002257 return false;
2258 }
2259 return true;
2260
2261 case GL_VERTEX_ARRAY:
2262 if (context->getVertexArray(name) == nullptr)
2263 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002264 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002265 return false;
2266 }
2267 return true;
2268
2269 case GL_QUERY:
2270 if (context->getQuery(name) == nullptr)
2271 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002272 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002273 return false;
2274 }
2275 return true;
2276
2277 case GL_TRANSFORM_FEEDBACK:
2278 if (context->getTransformFeedback(name) == nullptr)
2279 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002280 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002281 return false;
2282 }
2283 return true;
2284
2285 case GL_SAMPLER:
2286 if (context->getSampler(name) == nullptr)
2287 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002288 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002289 return false;
2290 }
2291 return true;
2292
2293 case GL_TEXTURE:
2294 if (context->getTexture(name) == nullptr)
2295 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002296 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002297 return false;
2298 }
2299 return true;
2300
2301 case GL_RENDERBUFFER:
2302 if (context->getRenderbuffer(name) == nullptr)
2303 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002304 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002305 return false;
2306 }
2307 return true;
2308
2309 case GL_FRAMEBUFFER:
2310 if (context->getFramebuffer(name) == nullptr)
2311 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002312 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002313 return false;
2314 }
2315 return true;
2316
2317 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002318 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002319 return false;
2320 }
Geoff Lange102fee2015-12-10 11:23:30 -05002321}
2322
Martin Radev9d901792016-07-15 15:58:58 +03002323static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2324{
2325 size_t labelLength = 0;
2326
2327 if (length < 0)
2328 {
2329 if (label != nullptr)
2330 {
2331 labelLength = strlen(label);
2332 }
2333 }
2334 else
2335 {
2336 labelLength = static_cast<size_t>(length);
2337 }
2338
2339 if (labelLength > context->getExtensions().maxLabelLength)
2340 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002341 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002342 return false;
2343 }
2344
2345 return true;
2346}
2347
Geoff Lange102fee2015-12-10 11:23:30 -05002348bool ValidateObjectLabelKHR(Context *context,
2349 GLenum identifier,
2350 GLuint name,
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 (!ValidateObjectIdentifierAndName(context, identifier, name))
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 ValidateGetObjectLabelKHR(Context *context,
2374 GLenum identifier,
2375 GLuint name,
2376 GLsizei bufSize,
2377 GLsizei *length,
2378 GLchar *label)
2379{
2380 if (!context->getExtensions().debug)
2381 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002383 return false;
2384 }
2385
Geoff Lang70d0f492015-12-10 17:45:46 -05002386 if (bufSize < 0)
2387 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002388 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002389 return false;
2390 }
2391
2392 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2393 {
2394 return false;
2395 }
2396
Martin Radev9d901792016-07-15 15:58:58 +03002397 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002398}
2399
2400static bool ValidateObjectPtrName(Context *context, const void *ptr)
2401{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002402 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002403 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002404 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002405 return false;
2406 }
2407
Geoff Lange102fee2015-12-10 11:23:30 -05002408 return true;
2409}
2410
2411bool ValidateObjectPtrLabelKHR(Context *context,
2412 const void *ptr,
2413 GLsizei length,
2414 const GLchar *label)
2415{
2416 if (!context->getExtensions().debug)
2417 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002418 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002419 return false;
2420 }
2421
Geoff Lang70d0f492015-12-10 17:45:46 -05002422 if (!ValidateObjectPtrName(context, ptr))
2423 {
2424 return false;
2425 }
2426
Martin Radev9d901792016-07-15 15:58:58 +03002427 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002428 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002429 return false;
2430 }
2431
Geoff Lange102fee2015-12-10 11:23:30 -05002432 return true;
2433}
2434
2435bool ValidateGetObjectPtrLabelKHR(Context *context,
2436 const void *ptr,
2437 GLsizei bufSize,
2438 GLsizei *length,
2439 GLchar *label)
2440{
2441 if (!context->getExtensions().debug)
2442 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002444 return false;
2445 }
2446
Geoff Lang70d0f492015-12-10 17:45:46 -05002447 if (bufSize < 0)
2448 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002449 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002450 return false;
2451 }
2452
2453 if (!ValidateObjectPtrName(context, ptr))
2454 {
2455 return false;
2456 }
2457
Martin Radev9d901792016-07-15 15:58:58 +03002458 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002459}
2460
2461bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2462{
2463 if (!context->getExtensions().debug)
2464 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002465 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002466 return false;
2467 }
2468
Geoff Lang70d0f492015-12-10 17:45:46 -05002469 // TODO: represent this in Context::getQueryParameterInfo.
2470 switch (pname)
2471 {
2472 case GL_DEBUG_CALLBACK_FUNCTION:
2473 case GL_DEBUG_CALLBACK_USER_PARAM:
2474 break;
2475
2476 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002477 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002478 return false;
2479 }
2480
Geoff Lange102fee2015-12-10 11:23:30 -05002481 return true;
2482}
Jamie Madillc29968b2016-01-20 11:17:23 -05002483
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002484bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2485 GLenum pname,
2486 GLsizei bufSize,
2487 GLsizei *length,
2488 void **params)
2489{
2490 UNIMPLEMENTED();
2491 return false;
2492}
2493
Jamie Madillc29968b2016-01-20 11:17:23 -05002494bool ValidateBlitFramebufferANGLE(Context *context,
2495 GLint srcX0,
2496 GLint srcY0,
2497 GLint srcX1,
2498 GLint srcY1,
2499 GLint dstX0,
2500 GLint dstY0,
2501 GLint dstX1,
2502 GLint dstY1,
2503 GLbitfield mask,
2504 GLenum filter)
2505{
2506 if (!context->getExtensions().framebufferBlit)
2507 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002509 return false;
2510 }
2511
2512 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2513 {
2514 // TODO(jmadill): Determine if this should be available on other implementations.
Olli Etuahof0e3c192018-08-15 13:37:21 +03002515 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002516 return false;
2517 }
2518
2519 if (filter == GL_LINEAR)
2520 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002521 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002522 return false;
2523 }
2524
Jamie Madill51f40ec2016-06-15 14:06:00 -04002525 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2526 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002527
2528 if (mask & GL_COLOR_BUFFER_BIT)
2529 {
2530 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2531 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2532
2533 if (readColorAttachment && drawColorAttachment)
2534 {
2535 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002536 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002537 readColorAttachment->type() != GL_RENDERBUFFER &&
2538 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2539 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002540 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2541 BlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002542 return false;
2543 }
2544
Geoff Langa15472a2015-08-11 11:48:03 -04002545 for (size_t drawbufferIdx = 0;
2546 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002547 {
Geoff Langa15472a2015-08-11 11:48:03 -04002548 const FramebufferAttachment *attachment =
2549 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2550 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002551 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002552 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002553 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002554 attachment->type() != GL_RENDERBUFFER &&
2555 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2556 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002557 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2558 BlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002559 return false;
2560 }
2561
2562 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002563 if (!Format::EquivalentForBlit(attachment->getFormat(),
2564 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002565 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002566 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2567 BlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002568 return false;
2569 }
2570 }
2571 }
2572
Jamie Madill427064d2018-04-13 16:20:34 -04002573 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002574 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002575 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2576 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2577 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002578 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2579 BlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002580 return false;
2581 }
2582 }
2583 }
2584
2585 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2586 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2587 for (size_t i = 0; i < 2; i++)
2588 {
2589 if (mask & masks[i])
2590 {
2591 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002592 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002593 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002594 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002595
2596 if (readBuffer && drawBuffer)
2597 {
2598 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2599 dstX0, dstY0, dstX1, dstY1))
2600 {
2601 // only whole-buffer copies are permitted
Olli Etuahof0e3c192018-08-15 13:37:21 +03002602 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2603 BlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002604 return false;
2605 }
2606
2607 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2608 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002609 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2610 BlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002611 return false;
2612 }
2613 }
2614 }
2615 }
2616
2617 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2618 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002619}
Jamie Madillc29968b2016-01-20 11:17:23 -05002620
Jamie Madill5b772312018-03-08 20:28:32 -05002621bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002622{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002623 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002624 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002625
Jamie Madill427064d2018-04-13 16:20:34 -04002626 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002627 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002628 return false;
2629 }
2630
2631 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2632 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002633 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002634 return false;
2635 }
2636
Olli Etuaho94c91a92018-07-19 15:10:24 +03002637 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002638 {
2639 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2640 GL_SIGNED_NORMALIZED};
2641
Corentin Wallez59c41592017-07-11 13:19:54 -04002642 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002643 drawBufferIdx++)
2644 {
2645 if (!ValidateWebGLFramebufferAttachmentClearType(
2646 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2647 {
2648 return false;
2649 }
2650 }
2651 }
2652
Olli Etuaho94c91a92018-07-19 15:10:24 +03002653 if (extensions.multiview && extensions.disjointTimerQuery)
2654 {
2655 const State &state = context->getGLState();
2656 Framebuffer *framebuffer = state.getDrawFramebuffer();
2657 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2658 {
2659 context->handleError(InvalidOperation() << "There is an active query for target "
2660 "GL_TIME_ELAPSED_EXT when the number of "
2661 "views in the active draw framebuffer is "
2662 "greater than 1.");
2663 return false;
2664 }
2665 }
2666
Jamie Madillc29968b2016-01-20 11:17:23 -05002667 return true;
2668}
2669
Jamie Madill5b772312018-03-08 20:28:32 -05002670bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002671{
2672 if (!context->getExtensions().drawBuffers)
2673 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002674 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002675 return false;
2676 }
2677
2678 return ValidateDrawBuffersBase(context, n, bufs);
2679}
2680
Jamie Madill73a84962016-02-12 09:27:23 -05002681bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002682 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002683 GLint level,
2684 GLint internalformat,
2685 GLsizei width,
2686 GLsizei height,
2687 GLint border,
2688 GLenum format,
2689 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002690 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002691{
Martin Radev1be913c2016-07-11 17:59:16 +03002692 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002693 {
2694 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002695 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002696 }
2697
Martin Radev1be913c2016-07-11 17:59:16 +03002698 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002699 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002700 0, 0, width, height, 1, border, format, type, -1,
2701 pixels);
2702}
2703
Brandon Jones416aaf92018-04-10 08:10:16 -07002704bool ValidateTexImage2DRobustANGLE(Context *context,
2705 TextureTarget target,
2706 GLint level,
2707 GLint internalformat,
2708 GLsizei width,
2709 GLsizei height,
2710 GLint border,
2711 GLenum format,
2712 GLenum type,
2713 GLsizei bufSize,
2714 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002715{
2716 if (!ValidateRobustEntryPoint(context, bufSize))
2717 {
2718 return false;
2719 }
2720
2721 if (context->getClientMajorVersion() < 3)
2722 {
2723 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2724 0, 0, width, height, border, format, type, bufSize,
2725 pixels);
2726 }
2727
2728 ASSERT(context->getClientMajorVersion() >= 3);
2729 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2730 0, 0, width, height, 1, border, format, type, bufSize,
2731 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002732}
2733
2734bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002735 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002736 GLint level,
2737 GLint xoffset,
2738 GLint yoffset,
2739 GLsizei width,
2740 GLsizei height,
2741 GLenum format,
2742 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002743 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002744{
2745
Martin Radev1be913c2016-07-11 17:59:16 +03002746 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002747 {
2748 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002749 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002750 }
2751
Martin Radev1be913c2016-07-11 17:59:16 +03002752 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002753 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002754 yoffset, 0, width, height, 1, 0, format, type, -1,
2755 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002756}
2757
Geoff Langc52f6f12016-10-14 10:18:00 -04002758bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002759 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002760 GLint level,
2761 GLint xoffset,
2762 GLint yoffset,
2763 GLsizei width,
2764 GLsizei height,
2765 GLenum format,
2766 GLenum type,
2767 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002768 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002769{
2770 if (!ValidateRobustEntryPoint(context, bufSize))
2771 {
2772 return false;
2773 }
2774
2775 if (context->getClientMajorVersion() < 3)
2776 {
2777 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2778 yoffset, width, height, 0, format, type, bufSize,
2779 pixels);
2780 }
2781
2782 ASSERT(context->getClientMajorVersion() >= 3);
2783 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2784 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2785 pixels);
2786}
2787
Jamie Madill73a84962016-02-12 09:27:23 -05002788bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002789 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002790 GLint level,
2791 GLenum internalformat,
2792 GLsizei width,
2793 GLsizei height,
2794 GLint border,
2795 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002796 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002797{
Martin Radev1be913c2016-07-11 17:59:16 +03002798 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002799 {
2800 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002801 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002802 {
2803 return false;
2804 }
2805 }
2806 else
2807 {
Martin Radev1be913c2016-07-11 17:59:16 +03002808 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002809 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002810 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002811 data))
2812 {
2813 return false;
2814 }
2815 }
2816
Geoff Langca271392017-04-05 12:30:00 -04002817 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002818
2819 GLuint blockSize = 0;
2820 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002821 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002822 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002823 return false;
2824 }
2825
Jamie Madillca2ff382018-07-11 09:01:17 -04002826 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002827 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002828 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002829 return false;
2830 }
2831
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002832 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002833 {
2834 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2835 return false;
2836 }
2837
Jamie Madill73a84962016-02-12 09:27:23 -05002838 return true;
2839}
2840
Corentin Wallezb2931602017-04-11 15:58:57 -04002841bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002842 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002843 GLint level,
2844 GLenum internalformat,
2845 GLsizei width,
2846 GLsizei height,
2847 GLint border,
2848 GLsizei imageSize,
2849 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002850 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002851{
2852 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2853 {
2854 return false;
2855 }
2856
2857 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2858 border, imageSize, data);
2859}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002860
Corentin Wallezb2931602017-04-11 15:58:57 -04002861bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002862 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002863 GLint level,
2864 GLint xoffset,
2865 GLint yoffset,
2866 GLsizei width,
2867 GLsizei height,
2868 GLenum format,
2869 GLsizei imageSize,
2870 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002871 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002872{
2873 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2874 {
2875 return false;
2876 }
2877
2878 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2879 format, imageSize, data);
2880}
2881
Jamie Madill73a84962016-02-12 09:27:23 -05002882bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002883 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002884 GLint level,
2885 GLint xoffset,
2886 GLint yoffset,
2887 GLsizei width,
2888 GLsizei height,
2889 GLenum format,
2890 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002891 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002892{
Martin Radev1be913c2016-07-11 17:59:16 +03002893 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002894 {
2895 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002896 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002897 {
2898 return false;
2899 }
2900 }
2901 else
2902 {
Martin Radev1be913c2016-07-11 17:59:16 +03002903 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002904 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002905 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002906 data))
2907 {
2908 return false;
2909 }
2910 }
2911
Geoff Langca271392017-04-05 12:30:00 -04002912 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002913 GLuint blockSize = 0;
2914 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002915 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002916 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002917 return false;
2918 }
2919
Jamie Madillca2ff382018-07-11 09:01:17 -04002920 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002921 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002922 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002923 return false;
2924 }
2925
2926 return true;
2927}
2928
Corentin Wallez336129f2017-10-17 15:55:40 -04002929bool ValidateGetBufferPointervOES(Context *context,
2930 BufferBinding target,
2931 GLenum pname,
2932 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002933{
Geoff Lang496c02d2016-10-20 11:38:11 -07002934 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002935}
2936
Corentin Wallez336129f2017-10-17 15:55:40 -04002937bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002938{
2939 if (!context->getExtensions().mapBuffer)
2940 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002941 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002942 return false;
2943 }
2944
Corentin Walleze4477002017-12-01 14:39:58 -05002945 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002946 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002947 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002948 return false;
2949 }
2950
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002951 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002952
2953 if (buffer == nullptr)
2954 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002955 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002956 return false;
2957 }
2958
2959 if (access != GL_WRITE_ONLY_OES)
2960 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002961 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002962 return false;
2963 }
2964
2965 if (buffer->isMapped())
2966 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002967 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002968 return false;
2969 }
2970
Geoff Lang79f71042017-08-14 16:43:43 -04002971 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002972}
2973
Corentin Wallez336129f2017-10-17 15:55:40 -04002974bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002975{
2976 if (!context->getExtensions().mapBuffer)
2977 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002978 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002979 return false;
2980 }
2981
2982 return ValidateUnmapBufferBase(context, target);
2983}
2984
2985bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002986 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002987 GLintptr offset,
2988 GLsizeiptr length,
2989 GLbitfield access)
2990{
2991 if (!context->getExtensions().mapBufferRange)
2992 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002993 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002994 return false;
2995 }
2996
2997 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2998}
2999
Corentin Wallez336129f2017-10-17 15:55:40 -04003000bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003001{
3002 Buffer *buffer = context->getGLState().getTargetBuffer(target);
3003 ASSERT(buffer != nullptr);
3004
3005 // Check if this buffer is currently being used as a transform feedback output buffer
3006 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3007 if (transformFeedback != nullptr && transformFeedback->isActive())
3008 {
3009 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3010 {
3011 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3012 if (transformFeedbackBuffer.get() == buffer)
3013 {
3014 context->handleError(InvalidOperation()
3015 << "Buffer is currently bound for transform feedback.");
3016 return false;
3017 }
3018 }
3019 }
3020
James Darpiniane8a93c62018-01-04 18:02:24 -08003021 if (context->getExtensions().webglCompatibility &&
3022 buffer->isBoundForTransformFeedbackAndOtherUse())
3023 {
3024 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
3025 return false;
3026 }
3027
Geoff Lang79f71042017-08-14 16:43:43 -04003028 return true;
3029}
3030
Olli Etuaho4f667482016-03-30 15:56:35 +03003031bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003032 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003033 GLintptr offset,
3034 GLsizeiptr length)
3035{
3036 if (!context->getExtensions().mapBufferRange)
3037 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003038 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003039 return false;
3040 }
3041
3042 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3043}
3044
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003045bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05003046{
Ian Ewell54f87462016-03-10 13:47:21 -05003047 switch (target)
3048 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003049 case TextureType::_2D:
3050 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05003051 break;
3052
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003053 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04003054 if (!context->getExtensions().textureRectangle)
3055 {
3056 context->handleError(InvalidEnum()
3057 << "Context does not support GL_ANGLE_texture_rectangle");
3058 return false;
3059 }
3060 break;
3061
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003062 case TextureType::_3D:
3063 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03003064 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05003065 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003066 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05003067 return false;
3068 }
3069 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003070
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003071 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04003072 if (context->getClientVersion() < Version(3, 1))
3073 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003074 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04003075 return false;
3076 }
Geoff Lang3b573612016-10-31 14:08:10 -04003077 break;
Olli Etuahod310a432018-08-24 15:40:23 +03003078 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +03003079 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03003080 {
3081 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
3082 return false;
3083 }
3084 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003085 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003086 if (!context->getExtensions().eglImageExternal &&
3087 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003088 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003089 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003090 return false;
3091 }
3092 break;
3093 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003094 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003095 return false;
3096 }
3097
Jamie Madill0fdb9562018-09-17 17:18:43 -04003098 if (texture == 0)
3099 {
3100 return true;
3101 }
3102
3103 Texture *textureObject = context->getTexture(texture);
3104 if (textureObject && textureObject->getType() != target)
3105 {
3106 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
3107 return false;
3108 }
3109
3110 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3111 !context->isTextureGenerated(texture))
3112 {
3113 context->handleError(InvalidOperation() << "Texture was not generated");
3114 return false;
3115 }
3116
Ian Ewell54f87462016-03-10 13:47:21 -05003117 return true;
3118}
3119
Geoff Langd8605522016-04-13 10:19:12 -04003120bool ValidateBindUniformLocationCHROMIUM(Context *context,
3121 GLuint program,
3122 GLint location,
3123 const GLchar *name)
3124{
3125 if (!context->getExtensions().bindUniformLocation)
3126 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003127 context->handleError(InvalidOperation()
3128 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003129 return false;
3130 }
3131
3132 Program *programObject = GetValidProgram(context, program);
3133 if (!programObject)
3134 {
3135 return false;
3136 }
3137
3138 if (location < 0)
3139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003140 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003141 return false;
3142 }
3143
3144 const Caps &caps = context->getCaps();
3145 if (static_cast<size_t>(location) >=
3146 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003148 context->handleError(InvalidValue() << "Location must be less than "
3149 "(MAX_VERTEX_UNIFORM_VECTORS + "
3150 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003151 return false;
3152 }
3153
Geoff Langfc32e8b2017-05-31 14:16:59 -04003154 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3155 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003156 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003157 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003158 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003159 return false;
3160 }
3161
Geoff Langd8605522016-04-13 10:19:12 -04003162 if (strncmp(name, "gl_", 3) == 0)
3163 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003164 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003165 return false;
3166 }
3167
3168 return true;
3169}
3170
Jamie Madille2e406c2016-06-02 13:04:10 -04003171bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003172{
3173 if (!context->getExtensions().framebufferMixedSamples)
3174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003175 context->handleError(InvalidOperation()
3176 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003177 return false;
3178 }
3179 switch (components)
3180 {
3181 case GL_RGB:
3182 case GL_RGBA:
3183 case GL_ALPHA:
3184 case GL_NONE:
3185 break;
3186 default:
3187 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003188 InvalidEnum()
3189 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003190 return false;
3191 }
3192
3193 return true;
3194}
3195
Sami Väisänene45e53b2016-05-25 10:36:04 +03003196// CHROMIUM_path_rendering
3197
Jamie Madill007530e2017-12-28 14:27:04 -05003198bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003199{
Jamie Madill007530e2017-12-28 14:27:04 -05003200 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003201 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003202 return false;
3203 }
Jamie Madill007530e2017-12-28 14:27:04 -05003204
Sami Väisänene45e53b2016-05-25 10:36:04 +03003205 if (matrix == nullptr)
3206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003207 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003208 return false;
3209 }
Jamie Madill007530e2017-12-28 14:27:04 -05003210
Sami Väisänene45e53b2016-05-25 10:36:04 +03003211 return true;
3212}
3213
Jamie Madill007530e2017-12-28 14:27:04 -05003214bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003215{
Jamie Madill007530e2017-12-28 14:27:04 -05003216 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003217}
3218
Jamie Madill007530e2017-12-28 14:27:04 -05003219bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003220{
3221 if (!context->getExtensions().pathRendering)
3222 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003223 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003224 return false;
3225 }
3226
3227 // range = 0 is undefined in NV_path_rendering.
3228 // we add stricter semantic check here and require a non zero positive range.
3229 if (range <= 0)
3230 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003231 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003232 return false;
3233 }
3234
3235 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3236 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003237 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003238 return false;
3239 }
3240
3241 return true;
3242}
3243
Jamie Madill007530e2017-12-28 14:27:04 -05003244bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003245{
3246 if (!context->getExtensions().pathRendering)
3247 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003248 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003249 return false;
3250 }
3251
3252 // range = 0 is undefined in NV_path_rendering.
3253 // we add stricter semantic check here and require a non zero positive range.
3254 if (range <= 0)
3255 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003256 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003257 return false;
3258 }
3259
3260 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3261 checkedRange += range;
3262
3263 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3264 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003265 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003266 return false;
3267 }
3268 return true;
3269}
3270
Jamie Madill007530e2017-12-28 14:27:04 -05003271bool ValidatePathCommandsCHROMIUM(Context *context,
3272 GLuint path,
3273 GLsizei numCommands,
3274 const GLubyte *commands,
3275 GLsizei numCoords,
3276 GLenum coordType,
3277 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003278{
3279 if (!context->getExtensions().pathRendering)
3280 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003281 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003282 return false;
3283 }
Brandon Jones59770802018-04-02 13:18:42 -07003284 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003285 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003286 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003287 return false;
3288 }
3289
3290 if (numCommands < 0)
3291 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003292 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003293 return false;
3294 }
3295 else if (numCommands > 0)
3296 {
3297 if (!commands)
3298 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003299 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003300 return false;
3301 }
3302 }
3303
3304 if (numCoords < 0)
3305 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003306 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003307 return false;
3308 }
3309 else if (numCoords > 0)
3310 {
3311 if (!coords)
3312 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003313 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003314 return false;
3315 }
3316 }
3317
3318 std::uint32_t coordTypeSize = 0;
3319 switch (coordType)
3320 {
3321 case GL_BYTE:
3322 coordTypeSize = sizeof(GLbyte);
3323 break;
3324
3325 case GL_UNSIGNED_BYTE:
3326 coordTypeSize = sizeof(GLubyte);
3327 break;
3328
3329 case GL_SHORT:
3330 coordTypeSize = sizeof(GLshort);
3331 break;
3332
3333 case GL_UNSIGNED_SHORT:
3334 coordTypeSize = sizeof(GLushort);
3335 break;
3336
3337 case GL_FLOAT:
3338 coordTypeSize = sizeof(GLfloat);
3339 break;
3340
3341 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003342 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003343 return false;
3344 }
3345
3346 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3347 checkedSize += (coordTypeSize * numCoords);
3348 if (!checkedSize.IsValid())
3349 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003351 return false;
3352 }
3353
3354 // early return skips command data validation when it doesn't exist.
3355 if (!commands)
3356 return true;
3357
3358 GLsizei expectedNumCoords = 0;
3359 for (GLsizei i = 0; i < numCommands; ++i)
3360 {
3361 switch (commands[i])
3362 {
3363 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3364 break;
3365 case GL_MOVE_TO_CHROMIUM:
3366 case GL_LINE_TO_CHROMIUM:
3367 expectedNumCoords += 2;
3368 break;
3369 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3370 expectedNumCoords += 4;
3371 break;
3372 case GL_CUBIC_CURVE_TO_CHROMIUM:
3373 expectedNumCoords += 6;
3374 break;
3375 case GL_CONIC_CURVE_TO_CHROMIUM:
3376 expectedNumCoords += 5;
3377 break;
3378 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003379 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003380 return false;
3381 }
3382 }
3383 if (expectedNumCoords != numCoords)
3384 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003385 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003386 return false;
3387 }
3388
3389 return true;
3390}
3391
Jamie Madill007530e2017-12-28 14:27:04 -05003392bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003393{
3394 if (!context->getExtensions().pathRendering)
3395 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003396 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003397 return false;
3398 }
Brandon Jones59770802018-04-02 13:18:42 -07003399 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003400 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003401 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003402 return false;
3403 }
3404
3405 switch (pname)
3406 {
3407 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3408 if (value < 0.0f)
3409 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003410 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003411 return false;
3412 }
3413 break;
3414 case GL_PATH_END_CAPS_CHROMIUM:
3415 switch (static_cast<GLenum>(value))
3416 {
3417 case GL_FLAT_CHROMIUM:
3418 case GL_SQUARE_CHROMIUM:
3419 case GL_ROUND_CHROMIUM:
3420 break;
3421 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003422 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003423 return false;
3424 }
3425 break;
3426 case GL_PATH_JOIN_STYLE_CHROMIUM:
3427 switch (static_cast<GLenum>(value))
3428 {
3429 case GL_MITER_REVERT_CHROMIUM:
3430 case GL_BEVEL_CHROMIUM:
3431 case GL_ROUND_CHROMIUM:
3432 break;
3433 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003434 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003435 return false;
3436 }
Nico Weber41b072b2018-02-09 10:01:32 -05003437 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003438 case GL_PATH_MITER_LIMIT_CHROMIUM:
3439 if (value < 0.0f)
3440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003441 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003442 return false;
3443 }
3444 break;
3445
3446 case GL_PATH_STROKE_BOUND_CHROMIUM:
3447 // no errors, only clamping.
3448 break;
3449
3450 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003451 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003452 return false;
3453 }
3454 return true;
3455}
3456
Jamie Madill007530e2017-12-28 14:27:04 -05003457bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3458{
3459 // TODO(jmadill): Use proper clamping cast.
3460 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3461}
3462
3463bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003464{
3465 if (!context->getExtensions().pathRendering)
3466 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003467 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003468 return false;
3469 }
3470
Brandon Jones59770802018-04-02 13:18:42 -07003471 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003472 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003473 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474 return false;
3475 }
3476 if (!value)
3477 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003478 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003479 return false;
3480 }
3481
3482 switch (pname)
3483 {
3484 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3485 case GL_PATH_END_CAPS_CHROMIUM:
3486 case GL_PATH_JOIN_STYLE_CHROMIUM:
3487 case GL_PATH_MITER_LIMIT_CHROMIUM:
3488 case GL_PATH_STROKE_BOUND_CHROMIUM:
3489 break;
3490
3491 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003492 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003493 return false;
3494 }
3495
3496 return true;
3497}
3498
Jamie Madill007530e2017-12-28 14:27:04 -05003499bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3500{
3501 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3502 reinterpret_cast<GLfloat *>(value));
3503}
3504
3505bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003506{
3507 if (!context->getExtensions().pathRendering)
3508 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003509 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510 return false;
3511 }
3512
3513 switch (func)
3514 {
3515 case GL_NEVER:
3516 case GL_ALWAYS:
3517 case GL_LESS:
3518 case GL_LEQUAL:
3519 case GL_EQUAL:
3520 case GL_GEQUAL:
3521 case GL_GREATER:
3522 case GL_NOTEQUAL:
3523 break;
3524 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003525 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003526 return false;
3527 }
3528
3529 return true;
3530}
3531
3532// Note that the spec specifies that for the path drawing commands
3533// if the path object is not an existing path object the command
3534// does nothing and no error is generated.
3535// However if the path object exists but has not been specified any
3536// commands then an error is generated.
3537
Jamie Madill007530e2017-12-28 14:27:04 -05003538bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003539{
3540 if (!context->getExtensions().pathRendering)
3541 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003542 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003543 return false;
3544 }
Brandon Jones59770802018-04-02 13:18:42 -07003545 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003547 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003548 return false;
3549 }
3550
3551 switch (fillMode)
3552 {
3553 case GL_COUNT_UP_CHROMIUM:
3554 case GL_COUNT_DOWN_CHROMIUM:
3555 break;
3556 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003557 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003558 return false;
3559 }
3560
3561 if (!isPow2(mask + 1))
3562 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003563 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003564 return false;
3565 }
3566
3567 return true;
3568}
3569
Jamie Madill007530e2017-12-28 14:27:04 -05003570bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003571{
3572 if (!context->getExtensions().pathRendering)
3573 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003574 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003575 return false;
3576 }
Brandon Jones59770802018-04-02 13:18:42 -07003577 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003578 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003579 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003580 return false;
3581 }
3582
3583 return true;
3584}
3585
Brandon Jonesd1049182018-03-28 10:02:20 -07003586bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3587{
3588 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3589}
3590
3591bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3592{
3593 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3594}
3595
Jamie Madill007530e2017-12-28 14:27:04 -05003596bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003597{
3598 if (!context->getExtensions().pathRendering)
3599 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003600 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003601 return false;
3602 }
Brandon Jones59770802018-04-02 13:18:42 -07003603 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003604 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003605 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003606 return false;
3607 }
3608
3609 switch (coverMode)
3610 {
3611 case GL_CONVEX_HULL_CHROMIUM:
3612 case GL_BOUNDING_BOX_CHROMIUM:
3613 break;
3614 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003615 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003616 return false;
3617 }
3618 return true;
3619}
3620
Jamie Madill007530e2017-12-28 14:27:04 -05003621bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3622 GLuint path,
3623 GLenum fillMode,
3624 GLuint mask,
3625 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003626{
Jamie Madill007530e2017-12-28 14:27:04 -05003627 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3628 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003629}
3630
Jamie Madill007530e2017-12-28 14:27:04 -05003631bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3632 GLuint path,
3633 GLint reference,
3634 GLuint mask,
3635 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003636{
Jamie Madill007530e2017-12-28 14:27:04 -05003637 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3638 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003639}
3640
Brandon Jonesd1049182018-03-28 10:02:20 -07003641bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003642{
3643 if (!context->getExtensions().pathRendering)
3644 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003645 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003646 return false;
3647 }
3648 return true;
3649}
3650
Jamie Madill007530e2017-12-28 14:27:04 -05003651bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3652 GLsizei numPaths,
3653 GLenum pathNameType,
3654 const void *paths,
3655 GLuint pathBase,
3656 GLenum coverMode,
3657 GLenum transformType,
3658 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003659{
3660 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3661 transformType, transformValues))
3662 return false;
3663
3664 switch (coverMode)
3665 {
3666 case GL_CONVEX_HULL_CHROMIUM:
3667 case GL_BOUNDING_BOX_CHROMIUM:
3668 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3669 break;
3670 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003671 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003672 return false;
3673 }
3674
3675 return true;
3676}
3677
Jamie Madill007530e2017-12-28 14:27:04 -05003678bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3679 GLsizei numPaths,
3680 GLenum pathNameType,
3681 const void *paths,
3682 GLuint pathBase,
3683 GLenum coverMode,
3684 GLenum transformType,
3685 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003686{
3687 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3688 transformType, transformValues))
3689 return false;
3690
3691 switch (coverMode)
3692 {
3693 case GL_CONVEX_HULL_CHROMIUM:
3694 case GL_BOUNDING_BOX_CHROMIUM:
3695 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3696 break;
3697 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003698 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003699 return false;
3700 }
3701
3702 return true;
3703}
3704
Jamie Madill007530e2017-12-28 14:27:04 -05003705bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3706 GLsizei numPaths,
3707 GLenum pathNameType,
3708 const void *paths,
3709 GLuint pathBase,
3710 GLenum fillMode,
3711 GLuint mask,
3712 GLenum transformType,
3713 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003714{
3715
3716 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3717 transformType, transformValues))
3718 return false;
3719
3720 switch (fillMode)
3721 {
3722 case GL_COUNT_UP_CHROMIUM:
3723 case GL_COUNT_DOWN_CHROMIUM:
3724 break;
3725 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003726 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003727 return false;
3728 }
3729 if (!isPow2(mask + 1))
3730 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003731 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003732 return false;
3733 }
3734 return true;
3735}
3736
Jamie Madill007530e2017-12-28 14:27:04 -05003737bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3738 GLsizei numPaths,
3739 GLenum pathNameType,
3740 const void *paths,
3741 GLuint pathBase,
3742 GLint reference,
3743 GLuint mask,
3744 GLenum transformType,
3745 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003746{
3747 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3748 transformType, transformValues))
3749 return false;
3750
3751 // no more validation here.
3752
3753 return true;
3754}
3755
Jamie Madill007530e2017-12-28 14:27:04 -05003756bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3757 GLsizei numPaths,
3758 GLenum pathNameType,
3759 const void *paths,
3760 GLuint pathBase,
3761 GLenum fillMode,
3762 GLuint mask,
3763 GLenum coverMode,
3764 GLenum transformType,
3765 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003766{
3767 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3768 transformType, transformValues))
3769 return false;
3770
3771 switch (coverMode)
3772 {
3773 case GL_CONVEX_HULL_CHROMIUM:
3774 case GL_BOUNDING_BOX_CHROMIUM:
3775 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3776 break;
3777 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003778 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003779 return false;
3780 }
3781
3782 switch (fillMode)
3783 {
3784 case GL_COUNT_UP_CHROMIUM:
3785 case GL_COUNT_DOWN_CHROMIUM:
3786 break;
3787 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003788 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003789 return false;
3790 }
3791 if (!isPow2(mask + 1))
3792 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003793 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003794 return false;
3795 }
3796
3797 return true;
3798}
3799
Jamie Madill007530e2017-12-28 14:27:04 -05003800bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3801 GLsizei numPaths,
3802 GLenum pathNameType,
3803 const void *paths,
3804 GLuint pathBase,
3805 GLint reference,
3806 GLuint mask,
3807 GLenum coverMode,
3808 GLenum transformType,
3809 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003810{
3811 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3812 transformType, transformValues))
3813 return false;
3814
3815 switch (coverMode)
3816 {
3817 case GL_CONVEX_HULL_CHROMIUM:
3818 case GL_BOUNDING_BOX_CHROMIUM:
3819 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3820 break;
3821 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003822 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003823 return false;
3824 }
3825
3826 return true;
3827}
3828
Jamie Madill007530e2017-12-28 14:27:04 -05003829bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3830 GLuint program,
3831 GLint location,
3832 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003833{
3834 if (!context->getExtensions().pathRendering)
3835 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003836 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003837 return false;
3838 }
3839
3840 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3841 if (location >= MaxLocation)
3842 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003843 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003844 return false;
3845 }
3846
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003847 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003848 if (!programObject)
3849 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003850 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003851 return false;
3852 }
3853
3854 if (!name)
3855 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003856 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003857 return false;
3858 }
3859
3860 if (angle::BeginsWith(name, "gl_"))
3861 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003862 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003863 return false;
3864 }
3865
3866 return true;
3867}
3868
Jamie Madill007530e2017-12-28 14:27:04 -05003869bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3870 GLuint program,
3871 GLint location,
3872 GLenum genMode,
3873 GLint components,
3874 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003875{
3876 if (!context->getExtensions().pathRendering)
3877 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003878 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003879 return false;
3880 }
3881
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003882 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003883 if (!programObject || programObject->isFlaggedForDeletion())
3884 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003885 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003886 return false;
3887 }
3888
3889 if (!programObject->isLinked())
3890 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003891 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003892 return false;
3893 }
3894
3895 switch (genMode)
3896 {
3897 case GL_NONE:
3898 if (components != 0)
3899 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003900 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003901 return false;
3902 }
3903 break;
3904
3905 case GL_OBJECT_LINEAR_CHROMIUM:
3906 case GL_EYE_LINEAR_CHROMIUM:
3907 case GL_CONSTANT_CHROMIUM:
3908 if (components < 1 || components > 4)
3909 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003910 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003911 return false;
3912 }
3913 if (!coeffs)
3914 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003915 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003916 return false;
3917 }
3918 break;
3919
3920 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003921 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003922 return false;
3923 }
3924
3925 // If the location is -1 then the command is silently ignored
3926 // and no further validation is needed.
3927 if (location == -1)
3928 return true;
3929
jchen103fd614d2018-08-13 12:21:58 +08003930 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003931
3932 if (!binding.valid)
3933 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003934 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003935 return false;
3936 }
3937
3938 if (binding.type != GL_NONE)
3939 {
3940 GLint expectedComponents = 0;
3941 switch (binding.type)
3942 {
3943 case GL_FLOAT:
3944 expectedComponents = 1;
3945 break;
3946 case GL_FLOAT_VEC2:
3947 expectedComponents = 2;
3948 break;
3949 case GL_FLOAT_VEC3:
3950 expectedComponents = 3;
3951 break;
3952 case GL_FLOAT_VEC4:
3953 expectedComponents = 4;
3954 break;
3955 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003956 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003957 InvalidOperation()
3958 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003959 return false;
3960 }
3961 if (expectedComponents != components && genMode != GL_NONE)
3962 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003963 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003964 return false;
3965 }
3966 }
3967 return true;
3968}
3969
Geoff Lang97073d12016-04-20 10:42:34 -07003970bool ValidateCopyTextureCHROMIUM(Context *context,
3971 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003972 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003973 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003974 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003975 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003976 GLint internalFormat,
3977 GLenum destType,
3978 GLboolean unpackFlipY,
3979 GLboolean unpackPremultiplyAlpha,
3980 GLboolean unpackUnmultiplyAlpha)
3981{
3982 if (!context->getExtensions().copyTexture)
3983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003984 context->handleError(InvalidOperation()
3985 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003986 return false;
3987 }
3988
Geoff Lang4f0e0032017-05-01 16:04:35 -04003989 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003990 if (source == nullptr)
3991 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003992 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003993 return false;
3994 }
3995
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003996 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003997 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07003998 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003999 return false;
4000 }
4001
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004002 TextureType sourceType = source->getType();
4003 ASSERT(sourceType != TextureType::CubeMap);
4004 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004005
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004006 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004008 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004009 return false;
4010 }
4011
Geoff Lang4f0e0032017-05-01 16:04:35 -04004012 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4013 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4014 if (sourceWidth == 0 || sourceHeight == 0)
4015 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004016 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004017 return false;
4018 }
4019
4020 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4021 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004022 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004023 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004024 return false;
4025 }
4026
Geoff Lang63458a32017-10-30 15:16:53 -04004027 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4028 {
4029 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4030 return false;
4031 }
4032
Geoff Lang4f0e0032017-05-01 16:04:35 -04004033 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004034 if (dest == nullptr)
4035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004036 context->handleError(InvalidValue()
4037 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004038 return false;
4039 }
4040
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004041 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004043 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004044 return false;
4045 }
4046
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004047 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004048 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004049 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004050 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004051 return false;
4052 }
4053
Geoff Lang97073d12016-04-20 10:42:34 -07004054 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4055 {
Geoff Lang97073d12016-04-20 10:42:34 -07004056 return false;
4057 }
4058
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004059 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004060 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004061 context->handleError(
4062 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004063 return false;
4064 }
4065
Geoff Lang97073d12016-04-20 10:42:34 -07004066 if (dest->getImmutableFormat())
4067 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004068 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07004069 return false;
4070 }
4071
4072 return true;
4073}
4074
4075bool ValidateCopySubTextureCHROMIUM(Context *context,
4076 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004077 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004078 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004079 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004080 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004081 GLint xoffset,
4082 GLint yoffset,
4083 GLint x,
4084 GLint y,
4085 GLsizei width,
4086 GLsizei height,
4087 GLboolean unpackFlipY,
4088 GLboolean unpackPremultiplyAlpha,
4089 GLboolean unpackUnmultiplyAlpha)
4090{
4091 if (!context->getExtensions().copyTexture)
4092 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004093 context->handleError(InvalidOperation()
4094 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004095 return false;
4096 }
4097
Geoff Lang4f0e0032017-05-01 16:04:35 -04004098 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004099 if (source == nullptr)
4100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004101 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004102 return false;
4103 }
4104
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004105 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004107 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004108 return false;
4109 }
4110
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004111 TextureType sourceType = source->getType();
4112 ASSERT(sourceType != TextureType::CubeMap);
4113 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004114
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004115 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004116 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004117 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004118 return false;
4119 }
4120
4121 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4122 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004124 context->handleError(InvalidValue()
4125 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004126 return false;
4127 }
4128
4129 if (x < 0 || y < 0)
4130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004131 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004132 return false;
4133 }
4134
4135 if (width < 0 || height < 0)
4136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004137 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004138 return false;
4139 }
4140
Geoff Lang4f0e0032017-05-01 16:04:35 -04004141 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4142 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004144 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004145 return false;
4146 }
4147
Geoff Lang4f0e0032017-05-01 16:04:35 -04004148 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4149 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004150 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004152 return false;
4153 }
4154
Geoff Lang63458a32017-10-30 15:16:53 -04004155 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4156 {
4157 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4158 return false;
4159 }
4160
Geoff Lang4f0e0032017-05-01 16:04:35 -04004161 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004162 if (dest == nullptr)
4163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004164 context->handleError(InvalidValue()
4165 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004166 return false;
4167 }
4168
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004169 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004171 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004172 return false;
4173 }
4174
Brandon Jones28783792018-03-05 09:37:32 -08004175 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4176 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004177 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004178 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004179 return false;
4180 }
4181
Geoff Lang4f0e0032017-05-01 16:04:35 -04004182 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4183 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004184 context
4185 ->handleError(InvalidOperation()
4186 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004187 return false;
4188 }
4189
4190 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4191 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004193 context->handleError(InvalidOperation()
4194 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004195 return false;
4196 }
4197
4198 if (xoffset < 0 || yoffset < 0)
4199 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004200 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004201 return false;
4202 }
4203
Geoff Lang4f0e0032017-05-01 16:04:35 -04004204 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4205 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004207 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004208 return false;
4209 }
4210
4211 return true;
4212}
4213
Geoff Lang47110bf2016-04-20 11:13:22 -07004214bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4215{
4216 if (!context->getExtensions().copyCompressedTexture)
4217 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004218 context->handleError(InvalidOperation()
4219 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004220 return false;
4221 }
4222
4223 const gl::Texture *source = context->getTexture(sourceId);
4224 if (source == nullptr)
4225 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004226 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004227 return false;
4228 }
4229
Corentin Wallez99d492c2018-02-27 15:17:10 -05004230 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004231 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004232 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004233 return false;
4234 }
4235
Corentin Wallez99d492c2018-02-27 15:17:10 -05004236 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4237 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004239 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004240 return false;
4241 }
4242
Corentin Wallez99d492c2018-02-27 15:17:10 -05004243 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004244 if (!sourceFormat.info->compressed)
4245 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004246 context->handleError(InvalidOperation()
4247 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004248 return false;
4249 }
4250
4251 const gl::Texture *dest = context->getTexture(destId);
4252 if (dest == nullptr)
4253 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004254 context->handleError(InvalidValue()
4255 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004256 return false;
4257 }
4258
Corentin Wallez99d492c2018-02-27 15:17:10 -05004259 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004260 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004261 context->handleError(InvalidValue()
4262 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004263 return false;
4264 }
4265
4266 if (dest->getImmutableFormat())
4267 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004268 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004269 return false;
4270 }
4271
4272 return true;
4273}
4274
Jiawei Shao385b3e02018-03-21 09:43:28 +08004275bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004276{
4277 switch (type)
4278 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004279 case ShaderType::Vertex:
4280 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004281 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004282
Jiawei Shao385b3e02018-03-21 09:43:28 +08004283 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004284 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004285 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004286 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004287 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004288 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004289 break;
4290
Jiawei Shao385b3e02018-03-21 09:43:28 +08004291 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004292 if (!context->getExtensions().geometryShader)
4293 {
4294 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4295 return false;
4296 }
4297 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004298 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004299 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004300 return false;
4301 }
Jamie Madill29639852016-09-02 15:00:09 -04004302
4303 return true;
4304}
4305
Jamie Madill5b772312018-03-08 20:28:32 -05004306bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004307 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004308 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004309 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004310 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004311{
4312 if (size < 0)
4313 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004314 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004315 return false;
4316 }
4317
4318 switch (usage)
4319 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004320 case BufferUsage::StreamDraw:
4321 case BufferUsage::StaticDraw:
4322 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004323 break;
4324
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004325 case BufferUsage::StreamRead:
4326 case BufferUsage::StaticRead:
4327 case BufferUsage::DynamicRead:
4328 case BufferUsage::StreamCopy:
4329 case BufferUsage::StaticCopy:
4330 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004331 if (context->getClientMajorVersion() < 3)
4332 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004333 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004334 return false;
4335 }
4336 break;
4337
4338 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004339 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004340 return false;
4341 }
4342
Corentin Walleze4477002017-12-01 14:39:58 -05004343 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004344 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004345 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004346 return false;
4347 }
4348
4349 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4350
4351 if (!buffer)
4352 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004354 return false;
4355 }
4356
James Darpiniane8a93c62018-01-04 18:02:24 -08004357 if (context->getExtensions().webglCompatibility &&
4358 buffer->isBoundForTransformFeedbackAndOtherUse())
4359 {
4360 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4361 return false;
4362 }
4363
Jamie Madill29639852016-09-02 15:00:09 -04004364 return true;
4365}
4366
Jamie Madill5b772312018-03-08 20:28:32 -05004367bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004368 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004369 GLintptr offset,
4370 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004371 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004372{
Brandon Jones6cad5662017-06-14 13:25:13 -07004373 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004374 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004375 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4376 return false;
4377 }
4378
4379 if (offset < 0)
4380 {
4381 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004382 return false;
4383 }
4384
Corentin Walleze4477002017-12-01 14:39:58 -05004385 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004386 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004387 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004388 return false;
4389 }
4390
4391 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4392
4393 if (!buffer)
4394 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004396 return false;
4397 }
4398
4399 if (buffer->isMapped())
4400 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004401 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004402 return false;
4403 }
4404
James Darpiniane8a93c62018-01-04 18:02:24 -08004405 if (context->getExtensions().webglCompatibility &&
4406 buffer->isBoundForTransformFeedbackAndOtherUse())
4407 {
4408 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4409 return false;
4410 }
4411
Jamie Madill29639852016-09-02 15:00:09 -04004412 // Check for possible overflow of size + offset
4413 angle::CheckedNumeric<size_t> checkedSize(size);
4414 checkedSize += offset;
4415 if (!checkedSize.IsValid())
4416 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004417 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004418 return false;
4419 }
4420
4421 if (size + offset > buffer->getSize())
4422 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004423 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004424 return false;
4425 }
4426
Martin Radev4c4c8e72016-08-04 12:25:34 +03004427 return true;
4428}
4429
Geoff Lang111a99e2017-10-17 10:58:41 -04004430bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004431{
Geoff Langc339c4e2016-11-29 10:37:36 -05004432 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004434 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004435 return false;
4436 }
4437
Geoff Lang111a99e2017-10-17 10:58:41 -04004438 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004439 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004440 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004441 return false;
4442 }
4443
4444 return true;
4445}
4446
Jamie Madill5b772312018-03-08 20:28:32 -05004447bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004448{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004449 if (context->getClientMajorVersion() < 2)
4450 {
4451 return ValidateMultitextureUnit(context, texture);
4452 }
4453
Jamie Madillef300b12016-10-07 15:12:09 -04004454 if (texture < GL_TEXTURE0 ||
4455 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4456 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004457 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004458 return false;
4459 }
4460
4461 return true;
4462}
4463
Jamie Madill5b772312018-03-08 20:28:32 -05004464bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004465{
4466 Program *programObject = GetValidProgram(context, program);
4467 if (!programObject)
4468 {
4469 return false;
4470 }
4471
4472 Shader *shaderObject = GetValidShader(context, shader);
4473 if (!shaderObject)
4474 {
4475 return false;
4476 }
4477
Jiawei Shao385b3e02018-03-21 09:43:28 +08004478 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004479 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004480 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4481 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004482 }
4483
4484 return true;
4485}
4486
Jamie Madill5b772312018-03-08 20:28:32 -05004487bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004488{
4489 if (index >= MAX_VERTEX_ATTRIBS)
4490 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004491 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004492 return false;
4493 }
4494
4495 if (strncmp(name, "gl_", 3) == 0)
4496 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004497 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004498 return false;
4499 }
4500
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004501 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004502 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004503 const size_t length = strlen(name);
4504
4505 if (!IsValidESSLString(name, length))
4506 {
4507 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4508 // for shader-related entry points
4509 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4510 return false;
4511 }
4512
4513 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4514 {
4515 return false;
4516 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004517 }
4518
Jamie Madill01a80ee2016-11-07 12:06:18 -05004519 return GetValidProgram(context, program) != nullptr;
4520}
4521
Jamie Madill5b772312018-03-08 20:28:32 -05004522bool ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004523{
Corentin Walleze4477002017-12-01 14:39:58 -05004524 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004525 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004526 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004527 return false;
4528 }
4529
4530 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4531 !context->isBufferGenerated(buffer))
4532 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004533 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004534 return false;
4535 }
4536
4537 return true;
4538}
4539
Jamie Madill5b772312018-03-08 20:28:32 -05004540bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004541{
Geoff Lange8afa902017-09-27 15:00:43 -04004542 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004543 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004544 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004545 return false;
4546 }
4547
4548 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4549 !context->isFramebufferGenerated(framebuffer))
4550 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004551 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004552 return false;
4553 }
4554
4555 return true;
4556}
4557
Jamie Madill5b772312018-03-08 20:28:32 -05004558bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004559{
4560 if (target != GL_RENDERBUFFER)
4561 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004562 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004563 return false;
4564 }
4565
4566 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4567 !context->isRenderbufferGenerated(renderbuffer))
4568 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004569 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004570 return false;
4571 }
4572
4573 return true;
4574}
4575
Jamie Madill5b772312018-03-08 20:28:32 -05004576static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004577{
4578 switch (mode)
4579 {
4580 case GL_FUNC_ADD:
4581 case GL_FUNC_SUBTRACT:
4582 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004583 return true;
4584
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004585 case GL_MIN:
4586 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004587 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004588
4589 default:
4590 return false;
4591 }
4592}
4593
Jamie Madill5b772312018-03-08 20:28:32 -05004594bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004595{
4596 return true;
4597}
4598
Jamie Madill5b772312018-03-08 20:28:32 -05004599bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004600{
Geoff Lang50cac572017-09-26 17:37:43 -04004601 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004602 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004603 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004604 return false;
4605 }
4606
4607 return true;
4608}
4609
Jamie Madill5b772312018-03-08 20:28:32 -05004610bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004611{
Geoff Lang50cac572017-09-26 17:37:43 -04004612 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004613 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004614 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004615 return false;
4616 }
4617
Geoff Lang50cac572017-09-26 17:37:43 -04004618 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004619 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004620 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004621 return false;
4622 }
4623
4624 return true;
4625}
4626
Jamie Madill5b772312018-03-08 20:28:32 -05004627bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004628{
4629 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4630}
4631
Jamie Madill5b772312018-03-08 20:28:32 -05004632bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004633 GLenum srcRGB,
4634 GLenum dstRGB,
4635 GLenum srcAlpha,
4636 GLenum dstAlpha)
4637{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004638 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004639 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004640 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004641 return false;
4642 }
4643
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004644 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004645 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004646 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004647 return false;
4648 }
4649
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004650 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004651 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004652 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004653 return false;
4654 }
4655
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004656 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004657 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004658 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004659 return false;
4660 }
4661
Frank Henigman146e8a12017-03-02 23:22:37 -05004662 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4663 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004664 {
4665 bool constantColorUsed =
4666 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4667 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4668
4669 bool constantAlphaUsed =
4670 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4671 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4672
4673 if (constantColorUsed && constantAlphaUsed)
4674 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004675 const char *msg;
4676 if (context->getExtensions().webglCompatibility)
4677 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004678 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004679 }
4680 else
4681 {
4682 msg =
4683 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4684 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4685 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004686 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004687 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004688 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004689 return false;
4690 }
4691 }
4692
4693 return true;
4694}
4695
Geoff Langc339c4e2016-11-29 10:37:36 -05004696bool ValidateGetString(Context *context, GLenum name)
4697{
4698 switch (name)
4699 {
4700 case GL_VENDOR:
4701 case GL_RENDERER:
4702 case GL_VERSION:
4703 case GL_SHADING_LANGUAGE_VERSION:
4704 case GL_EXTENSIONS:
4705 break;
4706
4707 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4708 if (!context->getExtensions().requestExtension)
4709 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004710 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004711 return false;
4712 }
4713 break;
4714
4715 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004716 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004717 return false;
4718 }
4719
4720 return true;
4721}
4722
Jamie Madill5b772312018-03-08 20:28:32 -05004723bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004724{
4725 if (width <= 0.0f || isNaN(width))
4726 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004727 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004728 return false;
4729 }
4730
4731 return true;
4732}
4733
Jamie Madill5b772312018-03-08 20:28:32 -05004734bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004735 GLuint index,
4736 GLint size,
4737 GLenum type,
4738 GLboolean normalized,
4739 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004740 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004741{
Shao80957d92017-02-20 21:25:59 +08004742 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004743 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004744 return false;
4745 }
4746
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004747 if (stride < 0)
4748 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004749 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004750 return false;
4751 }
4752
Shao80957d92017-02-20 21:25:59 +08004753 const Caps &caps = context->getCaps();
4754 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004755 {
Shao80957d92017-02-20 21:25:59 +08004756 if (stride > caps.maxVertexAttribStride)
4757 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004758 context->handleError(InvalidValue()
4759 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004760 return false;
4761 }
4762
4763 if (index >= caps.maxVertexAttribBindings)
4764 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004765 context->handleError(InvalidValue()
4766 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004767 return false;
4768 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004769 }
4770
4771 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4772 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4773 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4774 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004775 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4776 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004777 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4778 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004779 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004780 context
4781 ->handleError(InvalidOperation()
4782 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004783 return false;
4784 }
4785
4786 if (context->getExtensions().webglCompatibility)
4787 {
4788 // WebGL 1.0 [Section 6.14] Fixed point support
4789 // The WebGL API does not support the GL_FIXED data type.
4790 if (type == GL_FIXED)
4791 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004792 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004793 return false;
4794 }
4795
Geoff Lang2d62ab72017-03-23 16:54:40 -04004796 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004797 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004798 return false;
4799 }
4800 }
4801
4802 return true;
4803}
4804
Jamie Madill5b772312018-03-08 20:28:32 -05004805bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004806{
4807 if (context->getExtensions().webglCompatibility && zNear > zFar)
4808 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004809 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004810 return false;
4811 }
4812
4813 return true;
4814}
4815
Jamie Madill5b772312018-03-08 20:28:32 -05004816bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004817 GLenum target,
4818 GLenum internalformat,
4819 GLsizei width,
4820 GLsizei height)
4821{
4822 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4823 height);
4824}
4825
Jamie Madill5b772312018-03-08 20:28:32 -05004826bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004827 GLenum target,
4828 GLsizei samples,
4829 GLenum internalformat,
4830 GLsizei width,
4831 GLsizei height)
4832{
4833 if (!context->getExtensions().framebufferMultisample)
4834 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004835 context->handleError(InvalidOperation()
4836 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004837 return false;
4838 }
4839
4840 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4841 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4842 // generated.
4843 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4844 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004845 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004846 return false;
4847 }
4848
4849 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4850 // the specified storage. This is different than ES 3.0 in which a sample number higher
4851 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4852 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4853 if (context->getClientMajorVersion() >= 3)
4854 {
4855 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4856 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4857 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004858 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004859 return false;
4860 }
4861 }
4862
4863 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4864 width, height);
4865}
4866
Jamie Madill5b772312018-03-08 20:28:32 -05004867bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004868{
Geoff Lange8afa902017-09-27 15:00:43 -04004869 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004870 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004871 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004872 return false;
4873 }
4874
4875 return true;
4876}
4877
Jamie Madill5b772312018-03-08 20:28:32 -05004878bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004879{
4880 return true;
4881}
4882
Jamie Madill5b772312018-03-08 20:28:32 -05004883bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004884{
4885 return true;
4886}
4887
Jamie Madill5b772312018-03-08 20:28:32 -05004888bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004889{
4890 return true;
4891}
4892
Jamie Madill5b772312018-03-08 20:28:32 -05004893bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894 GLboolean red,
4895 GLboolean green,
4896 GLboolean blue,
4897 GLboolean alpha)
4898{
4899 return true;
4900}
4901
Jamie Madill5b772312018-03-08 20:28:32 -05004902bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004903{
4904 return true;
4905}
4906
Jamie Madill5b772312018-03-08 20:28:32 -05004907bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004908{
4909 return true;
4910}
4911
Jamie Madill5b772312018-03-08 20:28:32 -05004912bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004913{
4914 switch (mode)
4915 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004916 case CullFaceMode::Front:
4917 case CullFaceMode::Back:
4918 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004919 break;
4920
4921 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004922 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004923 return false;
4924 }
4925
4926 return true;
4927}
4928
Jamie Madill5b772312018-03-08 20:28:32 -05004929bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004930{
4931 if (program == 0)
4932 {
4933 return false;
4934 }
4935
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004936 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004937 {
4938 if (context->getShader(program))
4939 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004940 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004941 return false;
4942 }
4943 else
4944 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004945 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004946 return false;
4947 }
4948 }
4949
4950 return true;
4951}
4952
Jamie Madill5b772312018-03-08 20:28:32 -05004953bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004954{
4955 if (shader == 0)
4956 {
4957 return false;
4958 }
4959
4960 if (!context->getShader(shader))
4961 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004962 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004963 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004964 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004965 return false;
4966 }
4967 else
4968 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004969 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004970 return false;
4971 }
4972 }
4973
4974 return true;
4975}
4976
Jamie Madill5b772312018-03-08 20:28:32 -05004977bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004978{
4979 switch (func)
4980 {
4981 case GL_NEVER:
4982 case GL_ALWAYS:
4983 case GL_LESS:
4984 case GL_LEQUAL:
4985 case GL_EQUAL:
4986 case GL_GREATER:
4987 case GL_GEQUAL:
4988 case GL_NOTEQUAL:
4989 break;
4990
4991 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004992 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004993 return false;
4994 }
4995
4996 return true;
4997}
4998
Jamie Madill5b772312018-03-08 20:28:32 -05004999bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005000{
5001 return true;
5002}
5003
Jamie Madill5b772312018-03-08 20:28:32 -05005004bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005005{
5006 Program *programObject = GetValidProgram(context, program);
5007 if (!programObject)
5008 {
5009 return false;
5010 }
5011
5012 Shader *shaderObject = GetValidShader(context, shader);
5013 if (!shaderObject)
5014 {
5015 return false;
5016 }
5017
Jiawei Shao385b3e02018-03-21 09:43:28 +08005018 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005019 if (attachedShader != shaderObject)
5020 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005021 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005022 return false;
5023 }
5024
5025 return true;
5026}
5027
Jamie Madill5b772312018-03-08 20:28:32 -05005028bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005029{
5030 if (index >= MAX_VERTEX_ATTRIBS)
5031 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005032 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005033 return false;
5034 }
5035
5036 return true;
5037}
5038
Jamie Madill5b772312018-03-08 20:28:32 -05005039bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005040{
5041 if (index >= MAX_VERTEX_ATTRIBS)
5042 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005043 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005044 return false;
5045 }
5046
5047 return true;
5048}
5049
Jamie Madill5b772312018-03-08 20:28:32 -05005050bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005051{
5052 return true;
5053}
5054
Jamie Madill5b772312018-03-08 20:28:32 -05005055bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005056{
5057 return true;
5058}
5059
Jamie Madill5b772312018-03-08 20:28:32 -05005060bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005061{
5062 switch (mode)
5063 {
5064 case GL_CW:
5065 case GL_CCW:
5066 break;
5067 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005068 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005069 return false;
5070 }
5071
5072 return true;
5073}
5074
Jamie Madill5b772312018-03-08 20:28:32 -05005075bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005076 GLuint program,
5077 GLuint index,
5078 GLsizei bufsize,
5079 GLsizei *length,
5080 GLint *size,
5081 GLenum *type,
5082 GLchar *name)
5083{
5084 if (bufsize < 0)
5085 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005086 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005087 return false;
5088 }
5089
5090 Program *programObject = GetValidProgram(context, program);
5091
5092 if (!programObject)
5093 {
5094 return false;
5095 }
5096
5097 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5098 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005099 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005100 return false;
5101 }
5102
5103 return true;
5104}
5105
Jamie Madill5b772312018-03-08 20:28:32 -05005106bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005107 GLuint program,
5108 GLuint index,
5109 GLsizei bufsize,
5110 GLsizei *length,
5111 GLint *size,
5112 GLenum *type,
5113 GLchar *name)
5114{
5115 if (bufsize < 0)
5116 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005117 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005118 return false;
5119 }
5120
5121 Program *programObject = GetValidProgram(context, program);
5122
5123 if (!programObject)
5124 {
5125 return false;
5126 }
5127
5128 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5129 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005130 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005131 return false;
5132 }
5133
5134 return true;
5135}
5136
Jamie Madill5b772312018-03-08 20:28:32 -05005137bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005138 GLuint program,
5139 GLsizei maxcount,
5140 GLsizei *count,
5141 GLuint *shaders)
5142{
5143 if (maxcount < 0)
5144 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005145 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005146 return false;
5147 }
5148
5149 Program *programObject = GetValidProgram(context, program);
5150
5151 if (!programObject)
5152 {
5153 return false;
5154 }
5155
5156 return true;
5157}
5158
Jamie Madill5b772312018-03-08 20:28:32 -05005159bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005160{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005161 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5162 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005163 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005165 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005166 return false;
5167 }
5168
Jamie Madillc1d770e2017-04-13 17:31:24 -04005169 Program *programObject = GetValidProgram(context, program);
5170
5171 if (!programObject)
5172 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005173 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005174 return false;
5175 }
5176
5177 if (!programObject->isLinked())
5178 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005179 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005180 return false;
5181 }
5182
5183 return true;
5184}
5185
Jamie Madill5b772312018-03-08 20:28:32 -05005186bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005187{
5188 GLenum nativeType;
5189 unsigned int numParams = 0;
5190 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5191}
5192
Jamie Madill5b772312018-03-08 20:28:32 -05005193bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005194{
5195 return true;
5196}
5197
Jamie Madill5b772312018-03-08 20:28:32 -05005198bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005199{
5200 GLenum nativeType;
5201 unsigned int numParams = 0;
5202 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5203}
5204
Jamie Madill5b772312018-03-08 20:28:32 -05005205bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005206{
5207 GLenum nativeType;
5208 unsigned int numParams = 0;
5209 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5210}
5211
Jamie Madill5b772312018-03-08 20:28:32 -05005212bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 GLuint program,
5214 GLsizei bufsize,
5215 GLsizei *length,
5216 GLchar *infolog)
5217{
5218 if (bufsize < 0)
5219 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005220 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005221 return false;
5222 }
5223
5224 Program *programObject = GetValidProgram(context, program);
5225 if (!programObject)
5226 {
5227 return false;
5228 }
5229
5230 return true;
5231}
5232
Jamie Madill5b772312018-03-08 20:28:32 -05005233bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005234 GLuint shader,
5235 GLsizei bufsize,
5236 GLsizei *length,
5237 GLchar *infolog)
5238{
5239 if (bufsize < 0)
5240 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005241 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005242 return false;
5243 }
5244
5245 Shader *shaderObject = GetValidShader(context, shader);
5246 if (!shaderObject)
5247 {
5248 return false;
5249 }
5250
5251 return true;
5252}
5253
Jamie Madill5b772312018-03-08 20:28:32 -05005254bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005255 GLenum shadertype,
5256 GLenum precisiontype,
5257 GLint *range,
5258 GLint *precision)
5259{
5260 switch (shadertype)
5261 {
5262 case GL_VERTEX_SHADER:
5263 case GL_FRAGMENT_SHADER:
5264 break;
5265 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005266 context->handleError(InvalidOperation()
5267 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005268 return false;
5269 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005270 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005271 return false;
5272 }
5273
5274 switch (precisiontype)
5275 {
5276 case GL_LOW_FLOAT:
5277 case GL_MEDIUM_FLOAT:
5278 case GL_HIGH_FLOAT:
5279 case GL_LOW_INT:
5280 case GL_MEDIUM_INT:
5281 case GL_HIGH_INT:
5282 break;
5283
5284 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005285 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005286 return false;
5287 }
5288
5289 return true;
5290}
5291
Jamie Madill5b772312018-03-08 20:28:32 -05005292bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293 GLuint shader,
5294 GLsizei bufsize,
5295 GLsizei *length,
5296 GLchar *source)
5297{
5298 if (bufsize < 0)
5299 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005300 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005301 return false;
5302 }
5303
5304 Shader *shaderObject = GetValidShader(context, shader);
5305 if (!shaderObject)
5306 {
5307 return false;
5308 }
5309
5310 return true;
5311}
5312
Jamie Madill5b772312018-03-08 20:28:32 -05005313bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005314{
5315 if (strstr(name, "gl_") == name)
5316 {
5317 return false;
5318 }
5319
Geoff Langfc32e8b2017-05-31 14:16:59 -04005320 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5321 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005322 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005323 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005324 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005325 return false;
5326 }
5327
Jamie Madillc1d770e2017-04-13 17:31:24 -04005328 Program *programObject = GetValidProgram(context, program);
5329
5330 if (!programObject)
5331 {
5332 return false;
5333 }
5334
5335 if (!programObject->isLinked())
5336 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005337 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005338 return false;
5339 }
5340
5341 return true;
5342}
5343
Jamie Madill5b772312018-03-08 20:28:32 -05005344bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345{
5346 switch (mode)
5347 {
5348 case GL_FASTEST:
5349 case GL_NICEST:
5350 case GL_DONT_CARE:
5351 break;
5352
5353 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005354 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005355 return false;
5356 }
5357
5358 switch (target)
5359 {
5360 case GL_GENERATE_MIPMAP_HINT:
5361 break;
5362
Geoff Lange7bd2182017-06-16 16:13:13 -04005363 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5364 if (context->getClientVersion() < ES_3_0 &&
5365 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005366 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005367 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005368 return false;
5369 }
5370 break;
5371
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005372 case GL_PERSPECTIVE_CORRECTION_HINT:
5373 case GL_POINT_SMOOTH_HINT:
5374 case GL_LINE_SMOOTH_HINT:
5375 case GL_FOG_HINT:
5376 if (context->getClientMajorVersion() >= 2)
5377 {
5378 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5379 return false;
5380 }
5381 break;
5382
Jamie Madillc1d770e2017-04-13 17:31:24 -04005383 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005384 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385 return false;
5386 }
5387
5388 return true;
5389}
5390
Jamie Madill5b772312018-03-08 20:28:32 -05005391bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005392{
5393 return true;
5394}
5395
Jamie Madill5b772312018-03-08 20:28:32 -05005396bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397{
5398 return true;
5399}
5400
Jamie Madill5b772312018-03-08 20:28:32 -05005401bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005402{
5403 return true;
5404}
5405
Jamie Madill5b772312018-03-08 20:28:32 -05005406bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005407{
5408 return true;
5409}
5410
Jamie Madill5b772312018-03-08 20:28:32 -05005411bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005412{
5413 return true;
5414}
5415
Jamie Madill5b772312018-03-08 20:28:32 -05005416bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005417{
5418 return true;
5419}
5420
Jamie Madill5b772312018-03-08 20:28:32 -05005421bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005422{
5423 if (context->getClientMajorVersion() < 3)
5424 {
5425 switch (pname)
5426 {
5427 case GL_UNPACK_IMAGE_HEIGHT:
5428 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005429 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005430 return false;
5431
5432 case GL_UNPACK_ROW_LENGTH:
5433 case GL_UNPACK_SKIP_ROWS:
5434 case GL_UNPACK_SKIP_PIXELS:
5435 if (!context->getExtensions().unpackSubimage)
5436 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005437 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005438 return false;
5439 }
5440 break;
5441
5442 case GL_PACK_ROW_LENGTH:
5443 case GL_PACK_SKIP_ROWS:
5444 case GL_PACK_SKIP_PIXELS:
5445 if (!context->getExtensions().packSubimage)
5446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005447 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005448 return false;
5449 }
5450 break;
5451 }
5452 }
5453
5454 if (param < 0)
5455 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005456 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005457 return false;
5458 }
5459
5460 switch (pname)
5461 {
5462 case GL_UNPACK_ALIGNMENT:
5463 if (param != 1 && param != 2 && param != 4 && param != 8)
5464 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005465 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005466 return false;
5467 }
5468 break;
5469
5470 case GL_PACK_ALIGNMENT:
5471 if (param != 1 && param != 2 && param != 4 && param != 8)
5472 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005473 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005474 return false;
5475 }
5476 break;
5477
5478 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005479 if (!context->getExtensions().packReverseRowOrder)
5480 {
5481 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5482 }
5483 break;
5484
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485 case GL_UNPACK_ROW_LENGTH:
5486 case GL_UNPACK_IMAGE_HEIGHT:
5487 case GL_UNPACK_SKIP_IMAGES:
5488 case GL_UNPACK_SKIP_ROWS:
5489 case GL_UNPACK_SKIP_PIXELS:
5490 case GL_PACK_ROW_LENGTH:
5491 case GL_PACK_SKIP_ROWS:
5492 case GL_PACK_SKIP_PIXELS:
5493 break;
5494
5495 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005496 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005497 return false;
5498 }
5499
5500 return true;
5501}
5502
Jamie Madill5b772312018-03-08 20:28:32 -05005503bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005504{
5505 return true;
5506}
5507
Jamie Madill5b772312018-03-08 20:28:32 -05005508bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005509{
5510 return true;
5511}
5512
Jamie Madill5b772312018-03-08 20:28:32 -05005513bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005514{
5515 return true;
5516}
5517
Jamie Madill5b772312018-03-08 20:28:32 -05005518bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005519{
5520 if (width < 0 || height < 0)
5521 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005522 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005523 return false;
5524 }
5525
5526 return true;
5527}
5528
Jamie Madill5b772312018-03-08 20:28:32 -05005529bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005530 GLsizei n,
5531 const GLuint *shaders,
5532 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005533 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005534 GLsizei length)
5535{
5536 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5537 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5538 shaderBinaryFormats.end())
5539 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005540 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005541 return false;
5542 }
5543
5544 return true;
5545}
5546
Jamie Madill5b772312018-03-08 20:28:32 -05005547bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005548 GLuint shader,
5549 GLsizei count,
5550 const GLchar *const *string,
5551 const GLint *length)
5552{
5553 if (count < 0)
5554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005555 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556 return false;
5557 }
5558
Geoff Langfc32e8b2017-05-31 14:16:59 -04005559 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5560 // shader-related entry points
5561 if (context->getExtensions().webglCompatibility)
5562 {
5563 for (GLsizei i = 0; i < count; i++)
5564 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005565 size_t len =
5566 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005567
5568 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005569 if (!IsValidESSLShaderSourceString(string[i], len,
5570 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005571 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005572 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005573 return false;
5574 }
5575 }
5576 }
5577
Jamie Madillc1d770e2017-04-13 17:31:24 -04005578 Shader *shaderObject = GetValidShader(context, shader);
5579 if (!shaderObject)
5580 {
5581 return false;
5582 }
5583
5584 return true;
5585}
5586
Jamie Madill5b772312018-03-08 20:28:32 -05005587bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005588{
5589 if (!IsValidStencilFunc(func))
5590 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005591 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005592 return false;
5593 }
5594
5595 return true;
5596}
5597
Jamie Madill5b772312018-03-08 20:28:32 -05005598bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005599{
5600 if (!IsValidStencilFace(face))
5601 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005602 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005603 return false;
5604 }
5605
5606 if (!IsValidStencilFunc(func))
5607 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005609 return false;
5610 }
5611
5612 return true;
5613}
5614
Jamie Madill5b772312018-03-08 20:28:32 -05005615bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005616{
5617 return true;
5618}
5619
Jamie Madill5b772312018-03-08 20:28:32 -05005620bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005621{
5622 if (!IsValidStencilFace(face))
5623 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005624 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005625 return false;
5626 }
5627
5628 return true;
5629}
5630
Jamie Madill5b772312018-03-08 20:28:32 -05005631bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005632{
5633 if (!IsValidStencilOp(fail))
5634 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005635 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005636 return false;
5637 }
5638
5639 if (!IsValidStencilOp(zfail))
5640 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005641 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005642 return false;
5643 }
5644
5645 if (!IsValidStencilOp(zpass))
5646 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005647 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005648 return false;
5649 }
5650
5651 return true;
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655 GLenum face,
5656 GLenum fail,
5657 GLenum zfail,
5658 GLenum zpass)
5659{
5660 if (!IsValidStencilFace(face))
5661 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005662 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005663 return false;
5664 }
5665
5666 return ValidateStencilOp(context, fail, zfail, zpass);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670{
5671 return ValidateUniform(context, GL_FLOAT, location, 1);
5672}
5673
Jamie Madill5b772312018-03-08 20:28:32 -05005674bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675{
5676 return ValidateUniform(context, GL_FLOAT, location, count);
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005680{
5681 return ValidateUniform1iv(context, location, 1, &x);
5682}
5683
Jamie Madill5b772312018-03-08 20:28:32 -05005684bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005685{
5686 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5687}
5688
Jamie Madill5b772312018-03-08 20:28:32 -05005689bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005690{
5691 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5692}
5693
Jamie Madill5b772312018-03-08 20:28:32 -05005694bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005695{
5696 return ValidateUniform(context, GL_INT_VEC2, location, count);
5697}
5698
Jamie Madill5b772312018-03-08 20:28:32 -05005699bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005700{
5701 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5702}
5703
Jamie Madill5b772312018-03-08 20:28:32 -05005704bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005705{
5706 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5707}
5708
Jamie Madill5b772312018-03-08 20:28:32 -05005709bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005710{
5711 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5712}
5713
Jamie Madill5b772312018-03-08 20:28:32 -05005714bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005715{
5716 return ValidateUniform(context, GL_INT_VEC3, location, count);
5717}
5718
Jamie Madill5b772312018-03-08 20:28:32 -05005719bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005720{
5721 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5722}
5723
Jamie Madill5b772312018-03-08 20:28:32 -05005724bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005725{
5726 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5727}
5728
Jamie Madill5b772312018-03-08 20:28:32 -05005729bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005730{
5731 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5732}
5733
Jamie Madill5b772312018-03-08 20:28:32 -05005734bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005735{
5736 return ValidateUniform(context, GL_INT_VEC4, location, count);
5737}
5738
Jamie Madill5b772312018-03-08 20:28:32 -05005739bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005740 GLint location,
5741 GLsizei count,
5742 GLboolean transpose,
5743 const GLfloat *value)
5744{
5745 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5746}
5747
Jamie Madill5b772312018-03-08 20:28:32 -05005748bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005749 GLint location,
5750 GLsizei count,
5751 GLboolean transpose,
5752 const GLfloat *value)
5753{
5754 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5755}
5756
Jamie Madill5b772312018-03-08 20:28:32 -05005757bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005758 GLint location,
5759 GLsizei count,
5760 GLboolean transpose,
5761 const GLfloat *value)
5762{
5763 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5764}
5765
Jamie Madill5b772312018-03-08 20:28:32 -05005766bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005767{
5768 Program *programObject = GetValidProgram(context, program);
5769
5770 if (!programObject)
5771 {
5772 return false;
5773 }
5774
5775 return true;
5776}
5777
Jamie Madill5b772312018-03-08 20:28:32 -05005778bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005779{
5780 return ValidateVertexAttribIndex(context, index);
5781}
5782
Jamie Madill5b772312018-03-08 20:28:32 -05005783bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005784{
5785 return ValidateVertexAttribIndex(context, index);
5786}
5787
Jamie Madill5b772312018-03-08 20:28:32 -05005788bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005789{
5790 return ValidateVertexAttribIndex(context, index);
5791}
5792
Jamie Madill5b772312018-03-08 20:28:32 -05005793bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005794{
5795 return ValidateVertexAttribIndex(context, index);
5796}
5797
Jamie Madill5b772312018-03-08 20:28:32 -05005798bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005799{
5800 return ValidateVertexAttribIndex(context, index);
5801}
5802
Jamie Madill5b772312018-03-08 20:28:32 -05005803bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005804{
5805 return ValidateVertexAttribIndex(context, index);
5806}
5807
Jamie Madill5b772312018-03-08 20:28:32 -05005808bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005809 GLuint index,
5810 GLfloat x,
5811 GLfloat y,
5812 GLfloat z,
5813 GLfloat w)
5814{
5815 return ValidateVertexAttribIndex(context, index);
5816}
5817
Jamie Madill5b772312018-03-08 20:28:32 -05005818bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005819{
5820 return ValidateVertexAttribIndex(context, index);
5821}
5822
Jamie Madill5b772312018-03-08 20:28:32 -05005823bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005824{
5825 if (width < 0 || height < 0)
5826 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005827 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005828 return false;
5829 }
5830
5831 return true;
5832}
5833
Jamie Madill5b772312018-03-08 20:28:32 -05005834bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005835 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005836 GLsizei count,
5837 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005838 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005839{
5840 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5841}
5842
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005843bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005844 GLenum target,
5845 GLenum attachment,
5846 GLenum pname,
5847 GLint *params)
5848{
5849 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5850 nullptr);
5851}
5852
Jamie Madill5b772312018-03-08 20:28:32 -05005853bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005854{
5855 return ValidateGetProgramivBase(context, program, pname, nullptr);
5856}
5857
Jamie Madill5b772312018-03-08 20:28:32 -05005858bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005859 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005860 GLint level,
5861 GLenum internalformat,
5862 GLint x,
5863 GLint y,
5864 GLsizei width,
5865 GLsizei height,
5866 GLint border)
5867{
5868 if (context->getClientMajorVersion() < 3)
5869 {
5870 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5871 0, x, y, width, height, border);
5872 }
5873
5874 ASSERT(context->getClientMajorVersion() == 3);
5875 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5876 0, x, y, width, height, border);
5877}
5878
5879bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005880 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005881 GLint level,
5882 GLint xoffset,
5883 GLint yoffset,
5884 GLint x,
5885 GLint y,
5886 GLsizei width,
5887 GLsizei height)
5888{
5889 if (context->getClientMajorVersion() < 3)
5890 {
5891 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5892 yoffset, x, y, width, height, 0);
5893 }
5894
5895 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5896 yoffset, 0, x, y, width, height, 0);
5897}
5898
5899bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5900{
5901 return ValidateGenOrDelete(context, n);
5902}
5903
5904bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5905{
5906 return ValidateGenOrDelete(context, n);
5907}
5908
5909bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5910{
5911 return ValidateGenOrDelete(context, n);
5912}
5913
5914bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5915{
5916 return ValidateGenOrDelete(context, n);
5917}
5918
5919bool ValidateDisable(Context *context, GLenum cap)
5920{
5921 if (!ValidCap(context, cap, false))
5922 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005923 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005924 return false;
5925 }
5926
5927 return true;
5928}
5929
5930bool ValidateEnable(Context *context, GLenum cap)
5931{
5932 if (!ValidCap(context, cap, false))
5933 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005934 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005935 return false;
5936 }
5937
5938 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5939 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5940 {
5941 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005942 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005943
5944 // We also output an error message to the debugger window if tracing is active, so that
5945 // developers can see the error message.
5946 ERR() << errorMessage;
5947 return false;
5948 }
5949
5950 return true;
5951}
5952
5953bool ValidateFramebufferRenderbuffer(Context *context,
5954 GLenum target,
5955 GLenum attachment,
5956 GLenum renderbuffertarget,
5957 GLuint renderbuffer)
5958{
Geoff Lange8afa902017-09-27 15:00:43 -04005959 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005960 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005961 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5962 return false;
5963 }
5964
5965 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5966 {
5967 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005968 return false;
5969 }
5970
5971 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5972 renderbuffertarget, renderbuffer);
5973}
5974
5975bool ValidateFramebufferTexture2D(Context *context,
5976 GLenum target,
5977 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005978 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005979 GLuint texture,
5980 GLint level)
5981{
5982 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5983 // extension
5984 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5985 level != 0)
5986 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005987 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005988 return false;
5989 }
5990
5991 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5992 {
5993 return false;
5994 }
5995
5996 if (texture != 0)
5997 {
5998 gl::Texture *tex = context->getTexture(texture);
5999 ASSERT(tex);
6000
6001 const gl::Caps &caps = context->getCaps();
6002
6003 switch (textarget)
6004 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006005 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 {
6007 if (level > gl::log2(caps.max2DTextureSize))
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::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006014 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006015 return false;
6016 }
6017 }
6018 break;
6019
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006020 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006021 {
6022 if (level != 0)
6023 {
6024 context->handleError(InvalidValue());
6025 return false;
6026 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006027 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006028 {
6029 context->handleError(InvalidOperation()
6030 << "Textarget must match the texture target type.");
6031 return false;
6032 }
6033 }
6034 break;
6035
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006036 case TextureTarget::CubeMapNegativeX:
6037 case TextureTarget::CubeMapNegativeY:
6038 case TextureTarget::CubeMapNegativeZ:
6039 case TextureTarget::CubeMapPositiveX:
6040 case TextureTarget::CubeMapPositiveY:
6041 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 {
6043 if (level > gl::log2(caps.maxCubeMapTextureSize))
6044 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006045 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006046 return false;
6047 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006048 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006050 context->handleError(InvalidOperation()
6051 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006052 return false;
6053 }
6054 }
6055 break;
6056
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006057 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 {
6059 if (context->getClientVersion() < ES_3_1)
6060 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006061 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006062 return false;
6063 }
6064
6065 if (level != 0)
6066 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006067 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006068 return false;
6069 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006070 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006072 context->handleError(InvalidOperation()
6073 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006074 return false;
6075 }
6076 }
6077 break;
6078
6079 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006080 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006081 return false;
6082 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006083 }
6084
6085 return true;
6086}
6087
6088bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6089{
6090 return ValidateGenOrDelete(context, n);
6091}
6092
6093bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6094{
6095 return ValidateGenOrDelete(context, n);
6096}
6097
6098bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6099{
6100 return ValidateGenOrDelete(context, n);
6101}
6102
6103bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6104{
6105 return ValidateGenOrDelete(context, n);
6106}
6107
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006108bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006109{
6110 if (!ValidTextureTarget(context, target))
6111 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006112 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006113 return false;
6114 }
6115
6116 Texture *texture = context->getTargetTexture(target);
6117
6118 if (texture == nullptr)
6119 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006120 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006121 return false;
6122 }
6123
6124 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6125
6126 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6127 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6128 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6129 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006130 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006131 return false;
6132 }
6133
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006134 TextureTarget baseTarget = (target == TextureType::CubeMap)
6135 ? TextureTarget::CubeMapPositiveX
6136 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006137 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6138 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6139 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006140 {
6141 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6142 return false;
6143 }
6144
Geoff Lang536eca12017-09-13 11:23:35 -04006145 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6146 bool formatUnsized = !format.sized;
6147 bool formatColorRenderableAndFilterable =
6148 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006149 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006150 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006151 {
Geoff Lang536eca12017-09-13 11:23:35 -04006152 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006153 return false;
6154 }
6155
Geoff Lang536eca12017-09-13 11:23:35 -04006156 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6157 // generation
6158 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6159 {
6160 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6161 return false;
6162 }
6163
Jiange2c00842018-07-13 16:50:49 +08006164 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6165 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6166 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006167 {
Geoff Lang536eca12017-09-13 11:23:35 -04006168 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006169 return false;
6170 }
6171
6172 // Non-power of 2 ES2 check
6173 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6174 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6175 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6176 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006177 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6178 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006179 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006180 return false;
6181 }
6182
6183 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006184 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006185 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006186 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006187 return false;
6188 }
6189
6190 return true;
6191}
6192
Jamie Madill5b772312018-03-08 20:28:32 -05006193bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006194 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006195 GLenum pname,
6196 GLint *params)
6197{
6198 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6199}
6200
6201bool ValidateGetRenderbufferParameteriv(Context *context,
6202 GLenum target,
6203 GLenum pname,
6204 GLint *params)
6205{
6206 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6207}
6208
6209bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6210{
6211 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6212}
6213
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006214bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006215{
6216 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6217}
6218
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006219bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006220{
6221 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6222}
6223
6224bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6225{
6226 return ValidateGetUniformBase(context, program, location);
6227}
6228
6229bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6230{
6231 return ValidateGetUniformBase(context, program, location);
6232}
6233
6234bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6235{
6236 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6237}
6238
6239bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6240{
6241 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6242}
6243
6244bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6245{
6246 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6247}
6248
6249bool ValidateIsEnabled(Context *context, GLenum cap)
6250{
6251 if (!ValidCap(context, cap, true))
6252 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006253 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006254 return false;
6255 }
6256
6257 return true;
6258}
6259
6260bool ValidateLinkProgram(Context *context, GLuint program)
6261{
6262 if (context->hasActiveTransformFeedback(program))
6263 {
6264 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006265 context->handleError(InvalidOperation() << "Cannot link program while program is "
6266 "associated with an active transform "
6267 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006268 return false;
6269 }
6270
6271 Program *programObject = GetValidProgram(context, program);
6272 if (!programObject)
6273 {
6274 return false;
6275 }
6276
6277 return true;
6278}
6279
Jamie Madill4928b7c2017-06-20 12:57:39 -04006280bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006281 GLint x,
6282 GLint y,
6283 GLsizei width,
6284 GLsizei height,
6285 GLenum format,
6286 GLenum type,
6287 void *pixels)
6288{
6289 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6290 nullptr, pixels);
6291}
6292
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006293bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006294{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006295 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006296}
6297
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006298bool ValidateTexParameterfv(Context *context,
6299 TextureType target,
6300 GLenum pname,
6301 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006302{
6303 return ValidateTexParameterBase(context, target, pname, -1, params);
6304}
6305
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006306bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006307{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006308 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006309}
6310
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006311bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006312{
6313 return ValidateTexParameterBase(context, target, pname, -1, params);
6314}
6315
6316bool ValidateUseProgram(Context *context, GLuint program)
6317{
6318 if (program != 0)
6319 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006320 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006321 if (!programObject)
6322 {
6323 // ES 3.1.0 section 7.3 page 72
6324 if (context->getShader(program))
6325 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006326 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006327 return false;
6328 }
6329 else
6330 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006331 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006332 return false;
6333 }
6334 }
6335 if (!programObject->isLinked())
6336 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006337 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006338 return false;
6339 }
6340 }
6341 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6342 {
6343 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006344 context
6345 ->handleError(InvalidOperation()
6346 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006347 return false;
6348 }
6349
6350 return true;
6351}
6352
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006353bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6354{
6355 if (!context->getExtensions().fence)
6356 {
6357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6358 return false;
6359 }
6360
6361 if (n < 0)
6362 {
6363 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6364 return false;
6365 }
6366
6367 return true;
6368}
6369
6370bool ValidateFinishFenceNV(Context *context, GLuint fence)
6371{
6372 if (!context->getExtensions().fence)
6373 {
6374 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6375 return false;
6376 }
6377
6378 FenceNV *fenceObject = context->getFenceNV(fence);
6379
6380 if (fenceObject == nullptr)
6381 {
6382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6383 return false;
6384 }
6385
6386 if (!fenceObject->isSet())
6387 {
6388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6389 return false;
6390 }
6391
6392 return true;
6393}
6394
6395bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6396{
6397 if (!context->getExtensions().fence)
6398 {
6399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6400 return false;
6401 }
6402
6403 if (n < 0)
6404 {
6405 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6406 return false;
6407 }
6408
6409 return true;
6410}
6411
6412bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6413{
6414 if (!context->getExtensions().fence)
6415 {
6416 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6417 return false;
6418 }
6419
6420 FenceNV *fenceObject = context->getFenceNV(fence);
6421
6422 if (fenceObject == nullptr)
6423 {
6424 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6425 return false;
6426 }
6427
6428 if (!fenceObject->isSet())
6429 {
6430 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6431 return false;
6432 }
6433
6434 switch (pname)
6435 {
6436 case GL_FENCE_STATUS_NV:
6437 case GL_FENCE_CONDITION_NV:
6438 break;
6439
6440 default:
6441 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6442 return false;
6443 }
6444
6445 return true;
6446}
6447
6448bool ValidateGetGraphicsResetStatusEXT(Context *context)
6449{
6450 if (!context->getExtensions().robustness)
6451 {
6452 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6453 return false;
6454 }
6455
6456 return true;
6457}
6458
6459bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6460 GLuint shader,
6461 GLsizei bufsize,
6462 GLsizei *length,
6463 GLchar *source)
6464{
6465 if (!context->getExtensions().translatedShaderSource)
6466 {
6467 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6468 return false;
6469 }
6470
6471 if (bufsize < 0)
6472 {
6473 context->handleError(InvalidValue());
6474 return false;
6475 }
6476
6477 Shader *shaderObject = context->getShader(shader);
6478
6479 if (!shaderObject)
6480 {
6481 context->handleError(InvalidOperation());
6482 return false;
6483 }
6484
6485 return true;
6486}
6487
6488bool ValidateIsFenceNV(Context *context, GLuint fence)
6489{
6490 if (!context->getExtensions().fence)
6491 {
6492 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6493 return false;
6494 }
6495
6496 return true;
6497}
6498
Jamie Madill007530e2017-12-28 14:27:04 -05006499bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6500{
6501 if (!context->getExtensions().fence)
6502 {
6503 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6504 return false;
6505 }
6506
6507 if (condition != GL_ALL_COMPLETED_NV)
6508 {
6509 context->handleError(InvalidEnum());
6510 return false;
6511 }
6512
6513 FenceNV *fenceObject = context->getFenceNV(fence);
6514
6515 if (fenceObject == nullptr)
6516 {
6517 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6518 return false;
6519 }
6520
6521 return true;
6522}
6523
6524bool ValidateTestFenceNV(Context *context, GLuint fence)
6525{
6526 if (!context->getExtensions().fence)
6527 {
6528 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6529 return false;
6530 }
6531
6532 FenceNV *fenceObject = context->getFenceNV(fence);
6533
6534 if (fenceObject == nullptr)
6535 {
6536 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6537 return false;
6538 }
6539
6540 if (fenceObject->isSet() != GL_TRUE)
6541 {
6542 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6543 return false;
6544 }
6545
6546 return true;
6547}
6548
6549bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006550 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006551 GLsizei levels,
6552 GLenum internalformat,
6553 GLsizei width,
6554 GLsizei height)
6555{
6556 if (!context->getExtensions().textureStorage)
6557 {
6558 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6559 return false;
6560 }
6561
6562 if (context->getClientMajorVersion() < 3)
6563 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006564 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006565 height);
6566 }
6567
6568 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006569 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006570 1);
6571}
6572
6573bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6574{
6575 if (!context->getExtensions().instancedArrays)
6576 {
6577 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6578 return false;
6579 }
6580
6581 if (index >= MAX_VERTEX_ATTRIBS)
6582 {
6583 context->handleError(InvalidValue());
6584 return false;
6585 }
6586
6587 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6588 {
6589 if (index == 0 && divisor != 0)
6590 {
6591 const char *errorMessage =
6592 "The current context doesn't support setting a non-zero divisor on the "
6593 "attribute with index zero. "
6594 "Please reorder the attributes in your vertex shader so that attribute zero "
6595 "can have a zero divisor.";
6596 context->handleError(InvalidOperation() << errorMessage);
6597
6598 // We also output an error message to the debugger window if tracing is active, so
6599 // that developers can see the error message.
6600 ERR() << errorMessage;
6601 return false;
6602 }
6603 }
6604
6605 return true;
6606}
6607
6608bool ValidateTexImage3DOES(Context *context,
6609 GLenum target,
6610 GLint level,
6611 GLenum internalformat,
6612 GLsizei width,
6613 GLsizei height,
6614 GLsizei depth,
6615 GLint border,
6616 GLenum format,
6617 GLenum type,
6618 const void *pixels)
6619{
6620 UNIMPLEMENTED(); // FIXME
6621 return false;
6622}
6623
6624bool ValidatePopGroupMarkerEXT(Context *context)
6625{
6626 if (!context->getExtensions().debugMarker)
6627 {
6628 // The debug marker calls should not set error state
6629 // However, it seems reasonable to set an error state if the extension is not enabled
6630 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6631 return false;
6632 }
6633
6634 return true;
6635}
6636
Jamie Madillfa920eb2018-01-04 11:45:50 -05006637bool ValidateTexStorage1DEXT(Context *context,
6638 GLenum target,
6639 GLsizei levels,
6640 GLenum internalformat,
6641 GLsizei width)
6642{
6643 UNIMPLEMENTED();
6644 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6645 return false;
6646}
6647
6648bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006649 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006650 GLsizei levels,
6651 GLenum internalformat,
6652 GLsizei width,
6653 GLsizei height,
6654 GLsizei depth)
6655{
6656 if (!context->getExtensions().textureStorage)
6657 {
6658 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6659 return false;
6660 }
6661
6662 if (context->getClientMajorVersion() < 3)
6663 {
6664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6665 return false;
6666 }
6667
6668 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6669 depth);
6670}
6671
jchen1082af6202018-06-22 10:59:52 +08006672bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6673{
6674 if (!context->getExtensions().parallelShaderCompile)
6675 {
6676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6677 return false;
6678 }
6679 return true;
6680}
6681
Jamie Madillc29968b2016-01-20 11:17:23 -05006682} // namespace gl