blob: 2bcfd24fe1f251632cc875639f474c7ef47fd0af [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:
Olli Etuahof2ed2992018-10-04 13:54:42 +0300579 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
580 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
581 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
582 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
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 case GL_DEPTH_COMPONENT:
586 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700587 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400588 return false;
589 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700590 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400591 return false;
592 }
593
594 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
595 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700596 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400597 return false;
598 }
599 }
600 else
601 {
602 switch (internalformat)
603 {
604 case GL_ALPHA:
605 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
606 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
607 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
608 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700609 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400610 return false;
611 }
612 break;
613 case GL_LUMINANCE:
614 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
615 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
616 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
617 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
618 colorbufferFormat != GL_BGR5_A1_ANGLEX)
619 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700620 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400621 return false;
622 }
623 break;
624 case GL_RED_EXT:
625 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
626 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
627 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
628 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
629 colorbufferFormat != GL_BGR5_A1_ANGLEX)
630 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700631 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400632 return false;
633 }
634 break;
635 case GL_RG_EXT:
636 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
637 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
638 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
639 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
640 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700641 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400642 return false;
643 }
644 break;
645 case GL_RGB:
646 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
647 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
648 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
649 colorbufferFormat != GL_BGR5_A1_ANGLEX)
650 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700651 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400652 return false;
653 }
654 break;
655 case GL_LUMINANCE_ALPHA:
656 case GL_RGBA:
657 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
658 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
659 colorbufferFormat != GL_BGR5_A1_ANGLEX)
660 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700661 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400662 return false;
663 }
664 break;
665 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
666 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
667 if (context->getExtensions().textureCompressionDXT1)
668 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700669 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 else
673 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700674 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400675 return false;
676 }
677 break;
678 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
679 if (context->getExtensions().textureCompressionDXT3)
680 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700681 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 else
685 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700686 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400687 return false;
688 }
689 break;
690 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
691 if (context->getExtensions().textureCompressionDXT5)
692 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700693 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 else
697 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700698 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400699 return false;
700 }
701 break;
702 case GL_ETC1_RGB8_OES:
703 if (context->getExtensions().compressedETC1RGB8Texture)
704 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500705 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 else
709 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500710 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400711 return false;
712 }
713 break;
714 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
715 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
716 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
717 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
718 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
719 if (context->getExtensions().lossyETCDecode)
720 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500721 context->handleError(InvalidOperation()
722 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400723 return false;
724 }
725 else
726 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500727 context->handleError(InvalidEnum()
728 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400729 return false;
730 }
731 break;
732 case GL_DEPTH_COMPONENT:
733 case GL_DEPTH_COMPONENT16:
734 case GL_DEPTH_COMPONENT32_OES:
735 case GL_DEPTH_STENCIL_OES:
736 case GL_DEPTH24_STENCIL8_OES:
737 if (context->getExtensions().depthTextures)
738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500739 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400740 return false;
741 }
742 else
743 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500744 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400745 return false;
746 }
747 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500748 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400749 return false;
750 }
751 }
752
753 // If width or height is zero, it is a no-op. Return false without setting an error.
754 return (width > 0 && height > 0);
755}
756
757bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
758{
759 switch (cap)
760 {
761 // EXT_multisample_compatibility
762 case GL_MULTISAMPLE_EXT:
763 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
764 return context->getExtensions().multisampleCompatibility;
765
766 case GL_CULL_FACE:
767 case GL_POLYGON_OFFSET_FILL:
768 case GL_SAMPLE_ALPHA_TO_COVERAGE:
769 case GL_SAMPLE_COVERAGE:
770 case GL_SCISSOR_TEST:
771 case GL_STENCIL_TEST:
772 case GL_DEPTH_TEST:
773 case GL_BLEND:
774 case GL_DITHER:
775 return true;
776
777 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
778 case GL_RASTERIZER_DISCARD:
779 return (context->getClientMajorVersion() >= 3);
780
781 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
782 case GL_DEBUG_OUTPUT:
783 return context->getExtensions().debug;
784
785 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
786 return queryOnly && context->getExtensions().bindGeneratesResource;
787
788 case GL_CLIENT_ARRAYS_ANGLE:
789 return queryOnly && context->getExtensions().clientArrays;
790
791 case GL_FRAMEBUFFER_SRGB_EXT:
792 return context->getExtensions().sRGBWriteControl;
793
794 case GL_SAMPLE_MASK:
795 return context->getClientVersion() >= Version(3, 1);
796
Geoff Langb433e872017-10-05 14:01:47 -0400797 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400798 return queryOnly && context->getExtensions().robustResourceInitialization;
799
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700800 // GLES1 emulation: GLES1-specific caps
801 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700802 case GL_VERTEX_ARRAY:
803 case GL_NORMAL_ARRAY:
804 case GL_COLOR_ARRAY:
805 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700806 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700807 case GL_LIGHTING:
808 case GL_LIGHT0:
809 case GL_LIGHT1:
810 case GL_LIGHT2:
811 case GL_LIGHT3:
812 case GL_LIGHT4:
813 case GL_LIGHT5:
814 case GL_LIGHT6:
815 case GL_LIGHT7:
816 case GL_NORMALIZE:
817 case GL_RESCALE_NORMAL:
818 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700819 case GL_CLIP_PLANE0:
820 case GL_CLIP_PLANE1:
821 case GL_CLIP_PLANE2:
822 case GL_CLIP_PLANE3:
823 case GL_CLIP_PLANE4:
824 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700825 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700826 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700827 case GL_LINE_SMOOTH:
828 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700829 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700830 case GL_POINT_SIZE_ARRAY_OES:
831 return context->getClientVersion() < Version(2, 0) &&
832 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700833 case GL_TEXTURE_CUBE_MAP:
834 return context->getClientVersion() < Version(2, 0) &&
835 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700836 case GL_POINT_SPRITE_OES:
837 return context->getClientVersion() < Version(2, 0) &&
838 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400839 default:
840 return false;
841 }
842}
843
Geoff Langfc32e8b2017-05-31 14:16:59 -0400844// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
845// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400846bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400847{
848 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400849 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
850 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400851 {
852 return true;
853 }
854
855 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
856 if (c >= 9 && c <= 13)
857 {
858 return true;
859 }
860
861 return false;
862}
863
Geoff Langcab92ee2017-07-19 17:32:07 -0400864bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400865{
Geoff Langa71a98e2017-06-19 15:15:00 -0400866 for (size_t i = 0; i < len; i++)
867 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400868 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400869 {
870 return false;
871 }
872 }
873
874 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400875}
876
Geoff Langcab92ee2017-07-19 17:32:07 -0400877bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
878{
879 enum class ParseState
880 {
881 // Have not seen an ASCII non-whitespace character yet on
882 // this line. Possible that we might see a preprocessor
883 // directive.
884 BEGINING_OF_LINE,
885
886 // Have seen at least one ASCII non-whitespace character
887 // on this line.
888 MIDDLE_OF_LINE,
889
890 // Handling a preprocessor directive. Passes through all
891 // characters up to the end of the line. Disables comment
892 // processing.
893 IN_PREPROCESSOR_DIRECTIVE,
894
895 // Handling a single-line comment. The comment text is
896 // replaced with a single space.
897 IN_SINGLE_LINE_COMMENT,
898
899 // Handling a multi-line comment. Newlines are passed
900 // through to preserve line numbers.
901 IN_MULTI_LINE_COMMENT
902 };
903
904 ParseState state = ParseState::BEGINING_OF_LINE;
905 size_t pos = 0;
906
907 while (pos < len)
908 {
909 char c = str[pos];
910 char next = pos + 1 < len ? str[pos + 1] : 0;
911
912 // Check for newlines
913 if (c == '\n' || c == '\r')
914 {
915 if (state != ParseState::IN_MULTI_LINE_COMMENT)
916 {
917 state = ParseState::BEGINING_OF_LINE;
918 }
919
920 pos++;
921 continue;
922 }
923
924 switch (state)
925 {
926 case ParseState::BEGINING_OF_LINE:
927 if (c == ' ')
928 {
929 // Maintain the BEGINING_OF_LINE state until a non-space is seen
930 pos++;
931 }
932 else if (c == '#')
933 {
934 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
935 pos++;
936 }
937 else
938 {
939 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
940 state = ParseState::MIDDLE_OF_LINE;
941 }
942 break;
943
944 case ParseState::MIDDLE_OF_LINE:
945 if (c == '/' && next == '/')
946 {
947 state = ParseState::IN_SINGLE_LINE_COMMENT;
948 pos++;
949 }
950 else if (c == '/' && next == '*')
951 {
952 state = ParseState::IN_MULTI_LINE_COMMENT;
953 pos++;
954 }
955 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
956 {
957 // Skip line continuation characters
958 }
959 else if (!IsValidESSLCharacter(c))
960 {
961 return false;
962 }
963 pos++;
964 break;
965
966 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700967 // Line-continuation characters may not be permitted.
968 // Otherwise, just pass it through. Do not parse comments in this state.
969 if (!lineContinuationAllowed && c == '\\')
970 {
971 return false;
972 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400973 pos++;
974 break;
975
976 case ParseState::IN_SINGLE_LINE_COMMENT:
977 // Line-continuation characters are processed before comment processing.
978 // Advance string if a new line character is immediately behind
979 // line-continuation character.
980 if (c == '\\' && (next == '\n' || next == '\r'))
981 {
982 pos++;
983 }
984 pos++;
985 break;
986
987 case ParseState::IN_MULTI_LINE_COMMENT:
988 if (c == '*' && next == '/')
989 {
990 state = ParseState::MIDDLE_OF_LINE;
991 pos++;
992 }
993 pos++;
994 break;
995 }
996 }
997
998 return true;
999}
1000
Jamie Madill5b772312018-03-08 20:28:32 -05001001bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001002{
1003 ASSERT(context->isWebGL());
1004
1005 // WebGL 1.0 [Section 6.16] GLSL Constructs
1006 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1007 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1008 {
1009 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1010 return false;
1011 }
1012
1013 return true;
1014}
1015
Jamie Madill5b772312018-03-08 20:28:32 -05001016bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001017{
1018 ASSERT(context->isWebGL());
1019
1020 if (context->isWebGL1() && length > 256)
1021 {
1022 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1023 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1024 // locations.
1025 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1026
1027 return false;
1028 }
1029 else if (length > 1024)
1030 {
1031 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1032 // uniform and attribute locations.
1033 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1034 return false;
1035 }
1036
1037 return true;
1038}
1039
Jamie Madill007530e2017-12-28 14:27:04 -05001040bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1041{
1042 if (!context->getExtensions().pathRendering)
1043 {
1044 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1045 return false;
1046 }
1047
1048 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1049 {
1050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1051 return false;
1052 }
1053 return true;
1054}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001055
1056bool ValidBlendFunc(const Context *context, GLenum val)
1057{
1058 const gl::Extensions &ext = context->getExtensions();
1059
1060 // these are always valid for src and dst.
1061 switch (val)
1062 {
1063 case GL_ZERO:
1064 case GL_ONE:
1065 case GL_SRC_COLOR:
1066 case GL_ONE_MINUS_SRC_COLOR:
1067 case GL_DST_COLOR:
1068 case GL_ONE_MINUS_DST_COLOR:
1069 case GL_SRC_ALPHA:
1070 case GL_ONE_MINUS_SRC_ALPHA:
1071 case GL_DST_ALPHA:
1072 case GL_ONE_MINUS_DST_ALPHA:
1073 case GL_CONSTANT_COLOR:
1074 case GL_ONE_MINUS_CONSTANT_COLOR:
1075 case GL_CONSTANT_ALPHA:
1076 case GL_ONE_MINUS_CONSTANT_ALPHA:
1077 return true;
1078
1079 // EXT_blend_func_extended.
1080 case GL_SRC1_COLOR_EXT:
1081 case GL_SRC1_ALPHA_EXT:
1082 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1083 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1084 case GL_SRC_ALPHA_SATURATE_EXT:
1085 return ext.blendFuncExtended;
1086
1087 default:
1088 return false;
1089 }
1090}
1091
1092bool ValidSrcBlendFunc(const Context *context, GLenum val)
1093{
1094 if (ValidBlendFunc(context, val))
1095 return true;
1096
1097 if (val == GL_SRC_ALPHA_SATURATE)
1098 return true;
1099
1100 return false;
1101}
1102
1103bool ValidDstBlendFunc(const Context *context, GLenum val)
1104{
1105 if (ValidBlendFunc(context, val))
1106 return true;
1107
1108 if (val == GL_SRC_ALPHA_SATURATE)
1109 {
1110 if (context->getClientMajorVersion() >= 3)
1111 return true;
1112 }
1113
1114 return false;
1115}
1116
Jamie Madillac66f982018-10-09 18:30:01 -04001117void RecordBindTextureTypeError(Context *context, TextureType target)
1118{
1119 ASSERT(!context->getStateCache().isValidBindTextureType(target));
1120
1121 switch (target)
1122 {
1123 case TextureType::Rectangle:
1124 ASSERT(!context->getExtensions().textureRectangle);
1125 context->handleError(InvalidEnum()
1126 << "Context does not support GL_ANGLE_texture_rectangle");
1127 break;
1128
1129 case TextureType::_3D:
1130 case TextureType::_2DArray:
1131 ASSERT(context->getClientMajorVersion() < 3);
1132 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
1133 break;
1134
1135 case TextureType::_2DMultisample:
1136 ASSERT(context->getClientVersion() < Version(3, 1));
1137 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
1138 break;
1139
1140 case TextureType::_2DMultisampleArray:
1141 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
1142 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
1143 break;
1144
1145 case TextureType::External:
1146 ASSERT(!context->getExtensions().eglImageExternal &&
1147 !context->getExtensions().eglStreamConsumerExternal);
1148 context->handleError(InvalidEnum() << "External texture extension not enabled");
1149 break;
1150
1151 default:
1152 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
1153 }
1154}
Jamie Madillc29968b2016-01-20 11:17:23 -05001155} // anonymous namespace
1156
Geoff Langff5b2d52016-09-07 11:32:23 -04001157bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001158 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001159 GLint level,
1160 GLenum internalformat,
1161 bool isCompressed,
1162 bool isSubImage,
1163 GLint xoffset,
1164 GLint yoffset,
1165 GLsizei width,
1166 GLsizei height,
1167 GLint border,
1168 GLenum format,
1169 GLenum type,
1170 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001171 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001172{
Jamie Madill6f38f822014-06-06 17:12:20 -04001173 if (!ValidTexture2DDestinationTarget(context, target))
1174 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001175 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001176 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001177 }
1178
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001179 TextureType texType = TextureTargetToType(target);
1180 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001182 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001183 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184 }
1185
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001186 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001187 {
1188 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1189 return false;
1190 }
1191
1192 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001193 std::numeric_limits<GLsizei>::max() - yoffset < height)
1194 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001195 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001196 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001197 }
1198
Geoff Lang6e898aa2017-06-02 11:17:26 -04001199 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1200 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1201 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1202 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1203 // case.
1204 bool nonEqualFormatsAllowed =
1205 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1206 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1207
1208 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001209 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001210 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001211 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001212 }
1213
Geoff Langaae65a42014-05-26 12:43:44 -04001214 const gl::Caps &caps = context->getCaps();
1215
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001216 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001217 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001218 case TextureType::_2D:
1219 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1220 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1221 {
1222 context->handleError(InvalidValue());
1223 return false;
1224 }
1225 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001226
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001227 case TextureType::Rectangle:
1228 ASSERT(level == 0);
1229 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1230 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1231 {
1232 context->handleError(InvalidValue());
1233 return false;
1234 }
1235 if (isCompressed)
1236 {
1237 context->handleError(InvalidEnum()
1238 << "Rectangle texture cannot have a compressed format.");
1239 return false;
1240 }
1241 break;
1242
1243 case TextureType::CubeMap:
1244 if (!isSubImage && width != height)
1245 {
1246 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1247 return false;
1248 }
1249
1250 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1251 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1252 {
1253 context->handleError(InvalidValue());
1254 return false;
1255 }
1256 break;
1257
1258 default:
1259 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001260 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001261 }
1262
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001263 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001264 if (!texture)
1265 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001266 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001267 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001268 }
1269
Geoff Langa9be0dc2014-12-17 12:34:40 -05001270 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001271 {
Geoff Langca271392017-04-05 12:30:00 -04001272 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1273 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001274 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001275 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001276 return false;
1277 }
1278
Geoff Langa9be0dc2014-12-17 12:34:40 -05001279 if (format != GL_NONE)
1280 {
Geoff Langca271392017-04-05 12:30:00 -04001281 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1282 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001283 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001284 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001285 return false;
1286 }
1287 }
1288
1289 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1290 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1291 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001292 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001293 return false;
1294 }
Geoff Langfb052642017-10-24 13:42:09 -04001295
1296 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001297 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001298 {
1299 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1300 return false;
1301 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001302 }
1303 else
1304 {
Geoff Lang69cce582015-09-17 13:20:36 -04001305 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001306 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001307 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001308 return false;
1309 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001310 }
1311
1312 // Verify zero border
1313 if (border != 0)
1314 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001315 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001316 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001317 }
1318
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001319 if (isCompressed)
1320 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001321 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001322 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1323 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001324
1325 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1326
1327 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001328 {
Geoff Lange88e4542018-05-03 15:05:57 -04001329 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1330 return false;
1331 }
1332
1333 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1334 context->getExtensions()))
1335 {
1336 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1337 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001338 }
Geoff Lang966c9402017-04-18 12:38:27 -04001339
1340 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001341 {
Geoff Lange88e4542018-05-03 15:05:57 -04001342 // From the OES_compressed_ETC1_RGB8_texture spec:
1343 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1344 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1345 // ETC1_RGB8_OES.
1346 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1347 {
1348 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1349 return false;
1350 }
1351
Geoff Lang966c9402017-04-18 12:38:27 -04001352 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1353 height, texture->getWidth(target, level),
1354 texture->getHeight(target, level)))
1355 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001356 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001357 return false;
1358 }
1359
1360 if (format != actualInternalFormat)
1361 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001362 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001363 return false;
1364 }
1365 }
1366 else
1367 {
1368 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1369 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001370 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001371 return false;
1372 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001373 }
1374 }
1375 else
1376 {
1377 // validate <type> by itself (used as secondary key below)
1378 switch (type)
1379 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001380 case GL_UNSIGNED_BYTE:
1381 case GL_UNSIGNED_SHORT_5_6_5:
1382 case GL_UNSIGNED_SHORT_4_4_4_4:
1383 case GL_UNSIGNED_SHORT_5_5_5_1:
1384 case GL_UNSIGNED_SHORT:
1385 case GL_UNSIGNED_INT:
1386 case GL_UNSIGNED_INT_24_8_OES:
1387 case GL_HALF_FLOAT_OES:
1388 case GL_FLOAT:
1389 break;
1390 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001391 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001392 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001393 }
1394
1395 // validate <format> + <type> combinations
1396 // - invalid <format> -> sets INVALID_ENUM
1397 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1398 switch (format)
1399 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001400 case GL_ALPHA:
1401 case GL_LUMINANCE:
1402 case GL_LUMINANCE_ALPHA:
1403 switch (type)
1404 {
1405 case GL_UNSIGNED_BYTE:
1406 case GL_FLOAT:
1407 case GL_HALF_FLOAT_OES:
1408 break;
1409 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001410 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001411 return false;
1412 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001413 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001414 case GL_RED:
1415 case GL_RG:
1416 if (!context->getExtensions().textureRG)
1417 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001418 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001419 return false;
1420 }
1421 switch (type)
1422 {
1423 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001424 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001425 case GL_FLOAT:
1426 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001427 if (!context->getExtensions().textureFloat)
1428 {
1429 context->handleError(InvalidEnum());
1430 return false;
1431 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001432 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 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001437 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001438 case GL_RGB:
1439 switch (type)
1440 {
1441 case GL_UNSIGNED_BYTE:
1442 case GL_UNSIGNED_SHORT_5_6_5:
1443 case GL_FLOAT:
1444 case GL_HALF_FLOAT_OES:
1445 break;
1446 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001447 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001448 return false;
1449 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001450 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 case GL_RGBA:
1452 switch (type)
1453 {
1454 case GL_UNSIGNED_BYTE:
1455 case GL_UNSIGNED_SHORT_4_4_4_4:
1456 case GL_UNSIGNED_SHORT_5_5_5_1:
1457 case GL_FLOAT:
1458 case GL_HALF_FLOAT_OES:
1459 break;
1460 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001461 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001462 return false;
1463 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001464 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001465 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001466 if (!context->getExtensions().textureFormatBGRA8888)
1467 {
1468 context->handleError(InvalidEnum());
1469 return false;
1470 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001471 switch (type)
1472 {
1473 case GL_UNSIGNED_BYTE:
1474 break;
1475 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001477 return false;
1478 }
1479 break;
1480 case GL_SRGB_EXT:
1481 case GL_SRGB_ALPHA_EXT:
1482 if (!context->getExtensions().sRGB)
1483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001484 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001485 return false;
1486 }
1487 switch (type)
1488 {
1489 case GL_UNSIGNED_BYTE:
1490 break;
1491 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001492 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001493 return false;
1494 }
1495 break;
1496 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1497 // handled below
1498 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1499 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1500 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1501 break;
1502 case GL_DEPTH_COMPONENT:
1503 switch (type)
1504 {
1505 case GL_UNSIGNED_SHORT:
1506 case GL_UNSIGNED_INT:
1507 break;
1508 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001509 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001510 return false;
1511 }
1512 break;
1513 case GL_DEPTH_STENCIL_OES:
1514 switch (type)
1515 {
1516 case GL_UNSIGNED_INT_24_8_OES:
1517 break;
1518 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001519 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001520 return false;
1521 }
1522 break;
1523 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001524 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001525 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001526 }
1527
1528 switch (format)
1529 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001530 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1531 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1532 if (context->getExtensions().textureCompressionDXT1)
1533 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001534 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001535 return false;
1536 }
1537 else
1538 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001539 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001540 return false;
1541 }
1542 break;
1543 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1544 if (context->getExtensions().textureCompressionDXT3)
1545 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001546 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001547 return false;
1548 }
1549 else
1550 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001551 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001552 return false;
1553 }
1554 break;
1555 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1556 if (context->getExtensions().textureCompressionDXT5)
1557 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001558 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001559 return false;
1560 }
1561 else
1562 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001563 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001564 return false;
1565 }
1566 break;
1567 case GL_ETC1_RGB8_OES:
1568 if (context->getExtensions().compressedETC1RGB8Texture)
1569 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001570 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001571 return false;
1572 }
1573 else
1574 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001575 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001576 return false;
1577 }
1578 break;
1579 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001580 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1581 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1582 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1583 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001584 if (context->getExtensions().lossyETCDecode)
1585 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001586 context->handleError(InvalidOperation()
1587 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001588 return false;
1589 }
1590 else
1591 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001592 context->handleError(InvalidEnum()
1593 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001594 return false;
1595 }
1596 break;
1597 case GL_DEPTH_COMPONENT:
1598 case GL_DEPTH_STENCIL_OES:
1599 if (!context->getExtensions().depthTextures)
1600 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001601 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001602 return false;
1603 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001604 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001605 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001606 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001607 return false;
1608 }
1609 // OES_depth_texture supports loading depth data and multiple levels,
1610 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001611 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001612 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001613 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1614 return false;
1615 }
1616 if (level != 0)
1617 {
1618 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001619 return false;
1620 }
1621 break;
1622 default:
1623 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001624 }
1625
Geoff Lang6e898aa2017-06-02 11:17:26 -04001626 if (!isSubImage)
1627 {
1628 switch (internalformat)
1629 {
1630 case GL_RGBA32F:
1631 if (!context->getExtensions().colorBufferFloatRGBA)
1632 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001633 context->handleError(InvalidValue()
1634 << "Sized GL_RGBA32F internal format requires "
1635 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001636 return false;
1637 }
1638 if (type != GL_FLOAT)
1639 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001640 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001641 return false;
1642 }
1643 if (format != GL_RGBA)
1644 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001645 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001646 return false;
1647 }
1648 break;
1649
1650 case GL_RGB32F:
1651 if (!context->getExtensions().colorBufferFloatRGB)
1652 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001653 context->handleError(InvalidValue()
1654 << "Sized GL_RGB32F internal format requires "
1655 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001656 return false;
1657 }
1658 if (type != GL_FLOAT)
1659 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001660 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001661 return false;
1662 }
1663 if (format != GL_RGB)
1664 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001665 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001666 return false;
1667 }
1668 break;
1669
1670 default:
1671 break;
1672 }
1673 }
1674
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001675 if (type == GL_FLOAT)
1676 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001677 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001678 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001679 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001680 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001681 }
1682 }
1683 else if (type == GL_HALF_FLOAT_OES)
1684 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001685 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001686 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001687 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001688 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001689 }
1690 }
1691 }
1692
Geoff Langdbcced82017-06-06 15:55:54 -04001693 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001694 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001695 imageSize))
1696 {
1697 return false;
1698 }
1699
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001700 return true;
1701}
1702
He Yunchaoced53ae2016-11-29 15:00:51 +08001703bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001704 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001705 GLsizei levels,
1706 GLenum internalformat,
1707 GLsizei width,
1708 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001709{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001710 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1711 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001713 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001714 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001715 }
1716
1717 if (width < 1 || height < 1 || levels < 1)
1718 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001719 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001720 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001721 }
1722
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001723 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001724 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001725 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001726 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001727 }
1728
1729 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1730 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001731 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001732 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001733 }
1734
Geoff Langca271392017-04-05 12:30:00 -04001735 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001736 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001737 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001738 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001739 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001740 }
1741
Geoff Langaae65a42014-05-26 12:43:44 -04001742 const gl::Caps &caps = context->getCaps();
1743
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001744 switch (target)
1745 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001746 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001747 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1748 static_cast<GLuint>(height) > caps.max2DTextureSize)
1749 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001750 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001751 return false;
1752 }
1753 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001754 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001755 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1756 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1757 {
1758 context->handleError(InvalidValue());
1759 return false;
1760 }
1761 if (formatInfo.compressed)
1762 {
1763 context->handleError(InvalidEnum()
1764 << "Rectangle texture cannot have a compressed format.");
1765 return false;
1766 }
1767 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001768 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1770 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1771 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001772 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001773 return false;
1774 }
1775 break;
1776 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001777 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001778 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001779 }
1780
Geoff Langc0b9ef42014-07-02 10:02:37 -04001781 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001782 {
1783 if (!gl::isPow2(width) || !gl::isPow2(height))
1784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001785 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001786 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001787 }
1788 }
1789
1790 switch (internalformat)
1791 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001792 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1793 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1794 if (!context->getExtensions().textureCompressionDXT1)
1795 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001796 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001797 return false;
1798 }
1799 break;
1800 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1801 if (!context->getExtensions().textureCompressionDXT3)
1802 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001803 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001804 return false;
1805 }
1806 break;
1807 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1808 if (!context->getExtensions().textureCompressionDXT5)
1809 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001810 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001811 return false;
1812 }
1813 break;
1814 case GL_ETC1_RGB8_OES:
1815 if (!context->getExtensions().compressedETC1RGB8Texture)
1816 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001817 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001818 return false;
1819 }
1820 break;
1821 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001822 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1823 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1824 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1825 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001826 if (!context->getExtensions().lossyETCDecode)
1827 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001828 context->handleError(InvalidEnum()
1829 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001830 return false;
1831 }
1832 break;
1833 case GL_RGBA32F_EXT:
1834 case GL_RGB32F_EXT:
1835 case GL_ALPHA32F_EXT:
1836 case GL_LUMINANCE32F_EXT:
1837 case GL_LUMINANCE_ALPHA32F_EXT:
1838 if (!context->getExtensions().textureFloat)
1839 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001840 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001841 return false;
1842 }
1843 break;
1844 case GL_RGBA16F_EXT:
1845 case GL_RGB16F_EXT:
1846 case GL_ALPHA16F_EXT:
1847 case GL_LUMINANCE16F_EXT:
1848 case GL_LUMINANCE_ALPHA16F_EXT:
1849 if (!context->getExtensions().textureHalfFloat)
1850 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001851 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001852 return false;
1853 }
1854 break;
1855 case GL_R8_EXT:
1856 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001857 if (!context->getExtensions().textureRG)
1858 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001859 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001860 return false;
1861 }
1862 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001863 case GL_R16F_EXT:
1864 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001865 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1866 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001867 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001868 return false;
1869 }
1870 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001871 case GL_R32F_EXT:
1872 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001873 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001874 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001875 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001876 return false;
1877 }
1878 break;
1879 case GL_DEPTH_COMPONENT16:
1880 case GL_DEPTH_COMPONENT32_OES:
1881 case GL_DEPTH24_STENCIL8_OES:
1882 if (!context->getExtensions().depthTextures)
1883 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001884 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001885 return false;
1886 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001887 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001888 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001889 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001890 return false;
1891 }
1892 // ANGLE_depth_texture only supports 1-level textures
1893 if (levels != 1)
1894 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001895 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001896 return false;
1897 }
1898 break;
1899 default:
1900 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001901 }
1902
Geoff Lang691e58c2014-12-19 17:03:25 -05001903 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001904 if (!texture || texture->id() == 0)
1905 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001906 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001907 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001908 }
1909
Geoff Lang69cce582015-09-17 13:20:36 -04001910 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001911 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001912 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001913 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001914 }
1915
1916 return true;
1917}
1918
He Yunchaoced53ae2016-11-29 15:00:51 +08001919bool ValidateDiscardFramebufferEXT(Context *context,
1920 GLenum target,
1921 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001922 const GLenum *attachments)
1923{
Jamie Madillc29968b2016-01-20 11:17:23 -05001924 if (!context->getExtensions().discardFramebuffer)
1925 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001926 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001927 return false;
1928 }
1929
Austin Kinross08332632015-05-05 13:35:47 -07001930 bool defaultFramebuffer = false;
1931
1932 switch (target)
1933 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001934 case GL_FRAMEBUFFER:
1935 defaultFramebuffer =
1936 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1937 break;
1938 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001939 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001940 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001941 }
1942
He Yunchaoced53ae2016-11-29 15:00:51 +08001943 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1944 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001945}
1946
Austin Kinrossbc781f32015-10-26 09:27:38 -07001947bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1948{
1949 if (!context->getExtensions().vertexArrayObject)
1950 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001951 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001952 return false;
1953 }
1954
1955 return ValidateBindVertexArrayBase(context, array);
1956}
1957
Jamie Madilld7576732017-08-26 18:49:50 -04001958bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001959{
1960 if (!context->getExtensions().vertexArrayObject)
1961 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001962 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001963 return false;
1964 }
1965
Olli Etuaho41997e72016-03-10 13:38:39 +02001966 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001967}
1968
Jamie Madilld7576732017-08-26 18:49:50 -04001969bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001970{
1971 if (!context->getExtensions().vertexArrayObject)
1972 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001973 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001974 return false;
1975 }
1976
Olli Etuaho41997e72016-03-10 13:38:39 +02001977 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001978}
1979
Jamie Madilld7576732017-08-26 18:49:50 -04001980bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001981{
1982 if (!context->getExtensions().vertexArrayObject)
1983 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001984 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001985 return false;
1986 }
1987
1988 return true;
1989}
Geoff Langc5629752015-12-07 16:29:04 -05001990
1991bool ValidateProgramBinaryOES(Context *context,
1992 GLuint program,
1993 GLenum binaryFormat,
1994 const void *binary,
1995 GLint length)
1996{
1997 if (!context->getExtensions().getProgramBinary)
1998 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001999 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002000 return false;
2001 }
2002
2003 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2004}
2005
2006bool ValidateGetProgramBinaryOES(Context *context,
2007 GLuint program,
2008 GLsizei bufSize,
2009 GLsizei *length,
2010 GLenum *binaryFormat,
2011 void *binary)
2012{
2013 if (!context->getExtensions().getProgramBinary)
2014 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002015 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002016 return false;
2017 }
2018
2019 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2020}
Geoff Lange102fee2015-12-10 11:23:30 -05002021
Geoff Lang70d0f492015-12-10 17:45:46 -05002022static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2023{
2024 switch (source)
2025 {
2026 case GL_DEBUG_SOURCE_API:
2027 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2028 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2029 case GL_DEBUG_SOURCE_OTHER:
2030 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2031 return !mustBeThirdPartyOrApplication;
2032
2033 case GL_DEBUG_SOURCE_THIRD_PARTY:
2034 case GL_DEBUG_SOURCE_APPLICATION:
2035 return true;
2036
2037 default:
2038 return false;
2039 }
2040}
2041
2042static bool ValidDebugType(GLenum type)
2043{
2044 switch (type)
2045 {
2046 case GL_DEBUG_TYPE_ERROR:
2047 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2048 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2049 case GL_DEBUG_TYPE_PERFORMANCE:
2050 case GL_DEBUG_TYPE_PORTABILITY:
2051 case GL_DEBUG_TYPE_OTHER:
2052 case GL_DEBUG_TYPE_MARKER:
2053 case GL_DEBUG_TYPE_PUSH_GROUP:
2054 case GL_DEBUG_TYPE_POP_GROUP:
2055 return true;
2056
2057 default:
2058 return false;
2059 }
2060}
2061
2062static bool ValidDebugSeverity(GLenum severity)
2063{
2064 switch (severity)
2065 {
2066 case GL_DEBUG_SEVERITY_HIGH:
2067 case GL_DEBUG_SEVERITY_MEDIUM:
2068 case GL_DEBUG_SEVERITY_LOW:
2069 case GL_DEBUG_SEVERITY_NOTIFICATION:
2070 return true;
2071
2072 default:
2073 return false;
2074 }
2075}
2076
Geoff Lange102fee2015-12-10 11:23:30 -05002077bool ValidateDebugMessageControlKHR(Context *context,
2078 GLenum source,
2079 GLenum type,
2080 GLenum severity,
2081 GLsizei count,
2082 const GLuint *ids,
2083 GLboolean enabled)
2084{
2085 if (!context->getExtensions().debug)
2086 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002087 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002088 return false;
2089 }
2090
Geoff Lang70d0f492015-12-10 17:45:46 -05002091 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2092 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002093 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002094 return false;
2095 }
2096
2097 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2098 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002099 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002100 return false;
2101 }
2102
2103 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2104 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002105 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002106 return false;
2107 }
2108
2109 if (count > 0)
2110 {
2111 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2112 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002113 context->handleError(
2114 InvalidOperation()
2115 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002116 return false;
2117 }
2118
2119 if (severity != GL_DONT_CARE)
2120 {
Jamie Madill437fa652016-05-03 15:13:24 -04002121 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002122 InvalidOperation()
2123 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002124 return false;
2125 }
2126 }
2127
Geoff Lange102fee2015-12-10 11:23:30 -05002128 return true;
2129}
2130
2131bool ValidateDebugMessageInsertKHR(Context *context,
2132 GLenum source,
2133 GLenum type,
2134 GLuint id,
2135 GLenum severity,
2136 GLsizei length,
2137 const GLchar *buf)
2138{
2139 if (!context->getExtensions().debug)
2140 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002141 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002142 return false;
2143 }
2144
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002145 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002146 {
2147 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2148 // not generate an error.
2149 return false;
2150 }
2151
2152 if (!ValidDebugSeverity(severity))
2153 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002154 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002155 return false;
2156 }
2157
2158 if (!ValidDebugType(type))
2159 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002160 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002161 return false;
2162 }
2163
2164 if (!ValidDebugSource(source, true))
2165 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002166 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002167 return false;
2168 }
2169
2170 size_t messageLength = (length < 0) ? strlen(buf) : length;
2171 if (messageLength > context->getExtensions().maxDebugMessageLength)
2172 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002173 context->handleError(InvalidValue()
2174 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002175 return false;
2176 }
2177
Geoff Lange102fee2015-12-10 11:23:30 -05002178 return true;
2179}
2180
2181bool ValidateDebugMessageCallbackKHR(Context *context,
2182 GLDEBUGPROCKHR callback,
2183 const void *userParam)
2184{
2185 if (!context->getExtensions().debug)
2186 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002187 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002188 return false;
2189 }
2190
Geoff Lange102fee2015-12-10 11:23:30 -05002191 return true;
2192}
2193
2194bool ValidateGetDebugMessageLogKHR(Context *context,
2195 GLuint count,
2196 GLsizei bufSize,
2197 GLenum *sources,
2198 GLenum *types,
2199 GLuint *ids,
2200 GLenum *severities,
2201 GLsizei *lengths,
2202 GLchar *messageLog)
2203{
2204 if (!context->getExtensions().debug)
2205 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002206 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002207 return false;
2208 }
2209
Geoff Lang70d0f492015-12-10 17:45:46 -05002210 if (bufSize < 0 && messageLog != nullptr)
2211 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002212 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002213 return false;
2214 }
2215
Geoff Lange102fee2015-12-10 11:23:30 -05002216 return true;
2217}
2218
2219bool ValidatePushDebugGroupKHR(Context *context,
2220 GLenum source,
2221 GLuint id,
2222 GLsizei length,
2223 const GLchar *message)
2224{
2225 if (!context->getExtensions().debug)
2226 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002227 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002228 return false;
2229 }
2230
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 if (!ValidDebugSource(source, true))
2232 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002233 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002234 return false;
2235 }
2236
2237 size_t messageLength = (length < 0) ? strlen(message) : length;
2238 if (messageLength > context->getExtensions().maxDebugMessageLength)
2239 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002240 context->handleError(InvalidValue()
2241 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002242 return false;
2243 }
2244
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002245 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002246 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2247 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002248 context
2249 ->handleError(StackOverflow()
2250 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002251 return false;
2252 }
2253
Geoff Lange102fee2015-12-10 11:23:30 -05002254 return true;
2255}
2256
2257bool ValidatePopDebugGroupKHR(Context *context)
2258{
2259 if (!context->getExtensions().debug)
2260 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002261 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002262 return false;
2263 }
2264
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002265 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002266 if (currentStackSize <= 1)
2267 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002268 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002269 return false;
2270 }
2271
2272 return true;
2273}
2274
2275static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2276{
2277 switch (identifier)
2278 {
2279 case GL_BUFFER:
2280 if (context->getBuffer(name) == nullptr)
2281 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002282 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002283 return false;
2284 }
2285 return true;
2286
2287 case GL_SHADER:
2288 if (context->getShader(name) == nullptr)
2289 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002290 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002291 return false;
2292 }
2293 return true;
2294
2295 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002296 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002297 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002298 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002299 return false;
2300 }
2301 return true;
2302
2303 case GL_VERTEX_ARRAY:
2304 if (context->getVertexArray(name) == nullptr)
2305 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002306 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002307 return false;
2308 }
2309 return true;
2310
2311 case GL_QUERY:
2312 if (context->getQuery(name) == nullptr)
2313 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002314 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002315 return false;
2316 }
2317 return true;
2318
2319 case GL_TRANSFORM_FEEDBACK:
2320 if (context->getTransformFeedback(name) == nullptr)
2321 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002322 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002323 return false;
2324 }
2325 return true;
2326
2327 case GL_SAMPLER:
2328 if (context->getSampler(name) == nullptr)
2329 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002330 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002331 return false;
2332 }
2333 return true;
2334
2335 case GL_TEXTURE:
2336 if (context->getTexture(name) == nullptr)
2337 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002338 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002339 return false;
2340 }
2341 return true;
2342
2343 case GL_RENDERBUFFER:
2344 if (context->getRenderbuffer(name) == nullptr)
2345 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002346 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002347 return false;
2348 }
2349 return true;
2350
2351 case GL_FRAMEBUFFER:
2352 if (context->getFramebuffer(name) == nullptr)
2353 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002354 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002355 return false;
2356 }
2357 return true;
2358
2359 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002360 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002361 return false;
2362 }
Geoff Lange102fee2015-12-10 11:23:30 -05002363}
2364
Martin Radev9d901792016-07-15 15:58:58 +03002365static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2366{
2367 size_t labelLength = 0;
2368
2369 if (length < 0)
2370 {
2371 if (label != nullptr)
2372 {
2373 labelLength = strlen(label);
2374 }
2375 }
2376 else
2377 {
2378 labelLength = static_cast<size_t>(length);
2379 }
2380
2381 if (labelLength > context->getExtensions().maxLabelLength)
2382 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002383 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002384 return false;
2385 }
2386
2387 return true;
2388}
2389
Geoff Lange102fee2015-12-10 11:23:30 -05002390bool ValidateObjectLabelKHR(Context *context,
2391 GLenum identifier,
2392 GLuint name,
2393 GLsizei length,
2394 const GLchar *label)
2395{
2396 if (!context->getExtensions().debug)
2397 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002398 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002399 return false;
2400 }
2401
Geoff Lang70d0f492015-12-10 17:45:46 -05002402 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2403 {
2404 return false;
2405 }
2406
Martin Radev9d901792016-07-15 15:58:58 +03002407 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002408 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002409 return false;
2410 }
2411
Geoff Lange102fee2015-12-10 11:23:30 -05002412 return true;
2413}
2414
2415bool ValidateGetObjectLabelKHR(Context *context,
2416 GLenum identifier,
2417 GLuint name,
2418 GLsizei bufSize,
2419 GLsizei *length,
2420 GLchar *label)
2421{
2422 if (!context->getExtensions().debug)
2423 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002424 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002425 return false;
2426 }
2427
Geoff Lang70d0f492015-12-10 17:45:46 -05002428 if (bufSize < 0)
2429 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002430 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002431 return false;
2432 }
2433
2434 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2435 {
2436 return false;
2437 }
2438
Martin Radev9d901792016-07-15 15:58:58 +03002439 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002440}
2441
2442static bool ValidateObjectPtrName(Context *context, const void *ptr)
2443{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002444 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002446 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002447 return false;
2448 }
2449
Geoff Lange102fee2015-12-10 11:23:30 -05002450 return true;
2451}
2452
2453bool ValidateObjectPtrLabelKHR(Context *context,
2454 const void *ptr,
2455 GLsizei length,
2456 const GLchar *label)
2457{
2458 if (!context->getExtensions().debug)
2459 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002460 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002461 return false;
2462 }
2463
Geoff Lang70d0f492015-12-10 17:45:46 -05002464 if (!ValidateObjectPtrName(context, ptr))
2465 {
2466 return false;
2467 }
2468
Martin Radev9d901792016-07-15 15:58:58 +03002469 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002470 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002471 return false;
2472 }
2473
Geoff Lange102fee2015-12-10 11:23:30 -05002474 return true;
2475}
2476
2477bool ValidateGetObjectPtrLabelKHR(Context *context,
2478 const void *ptr,
2479 GLsizei bufSize,
2480 GLsizei *length,
2481 GLchar *label)
2482{
2483 if (!context->getExtensions().debug)
2484 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002485 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002486 return false;
2487 }
2488
Geoff Lang70d0f492015-12-10 17:45:46 -05002489 if (bufSize < 0)
2490 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002491 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002492 return false;
2493 }
2494
2495 if (!ValidateObjectPtrName(context, ptr))
2496 {
2497 return false;
2498 }
2499
Martin Radev9d901792016-07-15 15:58:58 +03002500 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002501}
2502
2503bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2504{
2505 if (!context->getExtensions().debug)
2506 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002508 return false;
2509 }
2510
Geoff Lang70d0f492015-12-10 17:45:46 -05002511 // TODO: represent this in Context::getQueryParameterInfo.
2512 switch (pname)
2513 {
2514 case GL_DEBUG_CALLBACK_FUNCTION:
2515 case GL_DEBUG_CALLBACK_USER_PARAM:
2516 break;
2517
2518 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002519 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002520 return false;
2521 }
2522
Geoff Lange102fee2015-12-10 11:23:30 -05002523 return true;
2524}
Jamie Madillc29968b2016-01-20 11:17:23 -05002525
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002526bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2527 GLenum pname,
2528 GLsizei bufSize,
2529 GLsizei *length,
2530 void **params)
2531{
2532 UNIMPLEMENTED();
2533 return false;
2534}
2535
Jamie Madillc29968b2016-01-20 11:17:23 -05002536bool ValidateBlitFramebufferANGLE(Context *context,
2537 GLint srcX0,
2538 GLint srcY0,
2539 GLint srcX1,
2540 GLint srcY1,
2541 GLint dstX0,
2542 GLint dstY0,
2543 GLint dstX1,
2544 GLint dstY1,
2545 GLbitfield mask,
2546 GLenum filter)
2547{
2548 if (!context->getExtensions().framebufferBlit)
2549 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002550 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002551 return false;
2552 }
2553
2554 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2555 {
2556 // TODO(jmadill): Determine if this should be available on other implementations.
Olli Etuahof0e3c192018-08-15 13:37:21 +03002557 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002558 return false;
2559 }
2560
2561 if (filter == GL_LINEAR)
2562 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002563 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002564 return false;
2565 }
2566
Jamie Madill51f40ec2016-06-15 14:06:00 -04002567 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2568 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002569
2570 if (mask & GL_COLOR_BUFFER_BIT)
2571 {
2572 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2573 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2574
2575 if (readColorAttachment && drawColorAttachment)
2576 {
2577 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002578 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002579 readColorAttachment->type() != GL_RENDERBUFFER &&
2580 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2581 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002582 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2583 BlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002584 return false;
2585 }
2586
Geoff Langa15472a2015-08-11 11:48:03 -04002587 for (size_t drawbufferIdx = 0;
2588 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002589 {
Geoff Langa15472a2015-08-11 11:48:03 -04002590 const FramebufferAttachment *attachment =
2591 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2592 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002593 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002594 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002595 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002596 attachment->type() != GL_RENDERBUFFER &&
2597 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2598 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002599 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2600 BlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002601 return false;
2602 }
2603
2604 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002605 if (!Format::EquivalentForBlit(attachment->getFormat(),
2606 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002607 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002608 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2609 BlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002610 return false;
2611 }
2612 }
2613 }
2614
Jamie Madill427064d2018-04-13 16:20:34 -04002615 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002616 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002617 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2618 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2619 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002620 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2621 BlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002622 return false;
2623 }
2624 }
2625 }
2626
2627 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2628 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2629 for (size_t i = 0; i < 2; i++)
2630 {
2631 if (mask & masks[i])
2632 {
2633 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002634 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002635 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002636 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002637
2638 if (readBuffer && drawBuffer)
2639 {
2640 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2641 dstX0, dstY0, dstX1, dstY1))
2642 {
2643 // only whole-buffer copies are permitted
Olli Etuahof0e3c192018-08-15 13:37:21 +03002644 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2645 BlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002646 return false;
2647 }
2648
2649 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2650 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002651 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2652 BlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002653 return false;
2654 }
2655 }
2656 }
2657 }
2658
2659 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2660 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002661}
Jamie Madillc29968b2016-01-20 11:17:23 -05002662
Jamie Madill5b772312018-03-08 20:28:32 -05002663bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002664{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002665 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002666 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002667
Jamie Madill427064d2018-04-13 16:20:34 -04002668 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002669 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002670 return false;
2671 }
2672
2673 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2674 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002675 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002676 return false;
2677 }
2678
Olli Etuaho94c91a92018-07-19 15:10:24 +03002679 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002680 {
2681 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2682 GL_SIGNED_NORMALIZED};
2683
Corentin Wallez59c41592017-07-11 13:19:54 -04002684 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002685 drawBufferIdx++)
2686 {
2687 if (!ValidateWebGLFramebufferAttachmentClearType(
2688 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2689 {
2690 return false;
2691 }
2692 }
2693 }
2694
Olli Etuaho94c91a92018-07-19 15:10:24 +03002695 if (extensions.multiview && extensions.disjointTimerQuery)
2696 {
2697 const State &state = context->getGLState();
2698 Framebuffer *framebuffer = state.getDrawFramebuffer();
2699 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2700 {
2701 context->handleError(InvalidOperation() << "There is an active query for target "
2702 "GL_TIME_ELAPSED_EXT when the number of "
2703 "views in the active draw framebuffer is "
2704 "greater than 1.");
2705 return false;
2706 }
2707 }
2708
Jamie Madillc29968b2016-01-20 11:17:23 -05002709 return true;
2710}
2711
Jamie Madill5b772312018-03-08 20:28:32 -05002712bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002713{
2714 if (!context->getExtensions().drawBuffers)
2715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002716 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002717 return false;
2718 }
2719
2720 return ValidateDrawBuffersBase(context, n, bufs);
2721}
2722
Jamie Madill73a84962016-02-12 09:27:23 -05002723bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002724 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002725 GLint level,
2726 GLint internalformat,
2727 GLsizei width,
2728 GLsizei height,
2729 GLint border,
2730 GLenum format,
2731 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002732 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002733{
Martin Radev1be913c2016-07-11 17:59:16 +03002734 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002735 {
2736 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002737 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002738 }
2739
Martin Radev1be913c2016-07-11 17:59:16 +03002740 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002741 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002742 0, 0, width, height, 1, border, format, type, -1,
2743 pixels);
2744}
2745
Brandon Jones416aaf92018-04-10 08:10:16 -07002746bool ValidateTexImage2DRobustANGLE(Context *context,
2747 TextureTarget target,
2748 GLint level,
2749 GLint internalformat,
2750 GLsizei width,
2751 GLsizei height,
2752 GLint border,
2753 GLenum format,
2754 GLenum type,
2755 GLsizei bufSize,
2756 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002757{
2758 if (!ValidateRobustEntryPoint(context, bufSize))
2759 {
2760 return false;
2761 }
2762
2763 if (context->getClientMajorVersion() < 3)
2764 {
2765 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2766 0, 0, width, height, border, format, type, bufSize,
2767 pixels);
2768 }
2769
2770 ASSERT(context->getClientMajorVersion() >= 3);
2771 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2772 0, 0, width, height, 1, border, format, type, bufSize,
2773 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002774}
2775
2776bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002777 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002778 GLint level,
2779 GLint xoffset,
2780 GLint yoffset,
2781 GLsizei width,
2782 GLsizei height,
2783 GLenum format,
2784 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002785 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002786{
2787
Martin Radev1be913c2016-07-11 17:59:16 +03002788 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002789 {
2790 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002791 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002792 }
2793
Martin Radev1be913c2016-07-11 17:59:16 +03002794 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002795 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002796 yoffset, 0, width, height, 1, 0, format, type, -1,
2797 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002798}
2799
Geoff Langc52f6f12016-10-14 10:18:00 -04002800bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002801 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002802 GLint level,
2803 GLint xoffset,
2804 GLint yoffset,
2805 GLsizei width,
2806 GLsizei height,
2807 GLenum format,
2808 GLenum type,
2809 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002810 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002811{
2812 if (!ValidateRobustEntryPoint(context, bufSize))
2813 {
2814 return false;
2815 }
2816
2817 if (context->getClientMajorVersion() < 3)
2818 {
2819 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2820 yoffset, width, height, 0, format, type, bufSize,
2821 pixels);
2822 }
2823
2824 ASSERT(context->getClientMajorVersion() >= 3);
2825 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2826 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2827 pixels);
2828}
2829
Jamie Madill73a84962016-02-12 09:27:23 -05002830bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002831 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002832 GLint level,
2833 GLenum internalformat,
2834 GLsizei width,
2835 GLsizei height,
2836 GLint border,
2837 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002838 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002839{
Martin Radev1be913c2016-07-11 17:59:16 +03002840 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002841 {
2842 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002843 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002844 {
2845 return false;
2846 }
2847 }
2848 else
2849 {
Martin Radev1be913c2016-07-11 17:59:16 +03002850 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002851 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002852 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002853 data))
2854 {
2855 return false;
2856 }
2857 }
2858
Geoff Langca271392017-04-05 12:30:00 -04002859 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002860
2861 GLuint blockSize = 0;
2862 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002863 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002864 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002865 return false;
2866 }
2867
Jamie Madillca2ff382018-07-11 09:01:17 -04002868 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002869 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002870 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002871 return false;
2872 }
2873
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002874 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002875 {
2876 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2877 return false;
2878 }
2879
Jamie Madill73a84962016-02-12 09:27:23 -05002880 return true;
2881}
2882
Corentin Wallezb2931602017-04-11 15:58:57 -04002883bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002884 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002885 GLint level,
2886 GLenum internalformat,
2887 GLsizei width,
2888 GLsizei height,
2889 GLint border,
2890 GLsizei imageSize,
2891 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002892 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002893{
2894 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2895 {
2896 return false;
2897 }
2898
2899 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2900 border, imageSize, data);
2901}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002902
Corentin Wallezb2931602017-04-11 15:58:57 -04002903bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002904 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002905 GLint level,
2906 GLint xoffset,
2907 GLint yoffset,
2908 GLsizei width,
2909 GLsizei height,
2910 GLenum format,
2911 GLsizei imageSize,
2912 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002913 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002914{
2915 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2916 {
2917 return false;
2918 }
2919
2920 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2921 format, imageSize, data);
2922}
2923
Jamie Madill73a84962016-02-12 09:27:23 -05002924bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002925 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002926 GLint level,
2927 GLint xoffset,
2928 GLint yoffset,
2929 GLsizei width,
2930 GLsizei height,
2931 GLenum format,
2932 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002933 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002934{
Martin Radev1be913c2016-07-11 17:59:16 +03002935 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002936 {
2937 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002938 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002939 {
2940 return false;
2941 }
2942 }
2943 else
2944 {
Martin Radev1be913c2016-07-11 17:59:16 +03002945 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002946 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002947 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002948 data))
2949 {
2950 return false;
2951 }
2952 }
2953
Geoff Langca271392017-04-05 12:30:00 -04002954 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002955 GLuint blockSize = 0;
2956 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002957 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002958 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002959 return false;
2960 }
2961
Jamie Madillca2ff382018-07-11 09:01:17 -04002962 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002963 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002964 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002965 return false;
2966 }
2967
2968 return true;
2969}
2970
Corentin Wallez336129f2017-10-17 15:55:40 -04002971bool ValidateGetBufferPointervOES(Context *context,
2972 BufferBinding target,
2973 GLenum pname,
2974 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002975{
Geoff Lang496c02d2016-10-20 11:38:11 -07002976 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002977}
2978
Corentin Wallez336129f2017-10-17 15:55:40 -04002979bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002980{
2981 if (!context->getExtensions().mapBuffer)
2982 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002983 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002984 return false;
2985 }
2986
Corentin Walleze4477002017-12-01 14:39:58 -05002987 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002988 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002989 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002990 return false;
2991 }
2992
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002993 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002994
2995 if (buffer == nullptr)
2996 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002997 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002998 return false;
2999 }
3000
3001 if (access != GL_WRITE_ONLY_OES)
3002 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003003 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003004 return false;
3005 }
3006
3007 if (buffer->isMapped())
3008 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003009 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003010 return false;
3011 }
3012
Geoff Lang79f71042017-08-14 16:43:43 -04003013 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003014}
3015
Corentin Wallez336129f2017-10-17 15:55:40 -04003016bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003017{
3018 if (!context->getExtensions().mapBuffer)
3019 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003020 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003021 return false;
3022 }
3023
3024 return ValidateUnmapBufferBase(context, target);
3025}
3026
3027bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003028 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003029 GLintptr offset,
3030 GLsizeiptr length,
3031 GLbitfield access)
3032{
3033 if (!context->getExtensions().mapBufferRange)
3034 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003035 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003036 return false;
3037 }
3038
3039 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3040}
3041
Corentin Wallez336129f2017-10-17 15:55:40 -04003042bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003043{
3044 Buffer *buffer = context->getGLState().getTargetBuffer(target);
3045 ASSERT(buffer != nullptr);
3046
3047 // Check if this buffer is currently being used as a transform feedback output buffer
3048 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3049 if (transformFeedback != nullptr && transformFeedback->isActive())
3050 {
3051 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3052 {
3053 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3054 if (transformFeedbackBuffer.get() == buffer)
3055 {
3056 context->handleError(InvalidOperation()
3057 << "Buffer is currently bound for transform feedback.");
3058 return false;
3059 }
3060 }
3061 }
3062
James Darpiniane8a93c62018-01-04 18:02:24 -08003063 if (context->getExtensions().webglCompatibility &&
3064 buffer->isBoundForTransformFeedbackAndOtherUse())
3065 {
3066 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
3067 return false;
3068 }
3069
Geoff Lang79f71042017-08-14 16:43:43 -04003070 return true;
3071}
3072
Olli Etuaho4f667482016-03-30 15:56:35 +03003073bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003074 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003075 GLintptr offset,
3076 GLsizeiptr length)
3077{
3078 if (!context->getExtensions().mapBufferRange)
3079 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003080 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003081 return false;
3082 }
3083
3084 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3085}
3086
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003087bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05003088{
Jamie Madillac66f982018-10-09 18:30:01 -04003089 if (!context->getStateCache().isValidBindTextureType(target))
Ian Ewell54f87462016-03-10 13:47:21 -05003090 {
Jamie Madillac66f982018-10-09 18:30:01 -04003091 RecordBindTextureTypeError(context, target);
3092 return false;
Ian Ewell54f87462016-03-10 13:47:21 -05003093 }
3094
Jamie Madill0fdb9562018-09-17 17:18:43 -04003095 if (texture == 0)
3096 {
3097 return true;
3098 }
3099
3100 Texture *textureObject = context->getTexture(texture);
3101 if (textureObject && textureObject->getType() != target)
3102 {
3103 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
3104 return false;
3105 }
3106
3107 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3108 !context->isTextureGenerated(texture))
3109 {
3110 context->handleError(InvalidOperation() << "Texture was not generated");
3111 return false;
3112 }
3113
Ian Ewell54f87462016-03-10 13:47:21 -05003114 return true;
3115}
3116
Geoff Langd8605522016-04-13 10:19:12 -04003117bool ValidateBindUniformLocationCHROMIUM(Context *context,
3118 GLuint program,
3119 GLint location,
3120 const GLchar *name)
3121{
3122 if (!context->getExtensions().bindUniformLocation)
3123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003124 context->handleError(InvalidOperation()
3125 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003126 return false;
3127 }
3128
3129 Program *programObject = GetValidProgram(context, program);
3130 if (!programObject)
3131 {
3132 return false;
3133 }
3134
3135 if (location < 0)
3136 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003137 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003138 return false;
3139 }
3140
3141 const Caps &caps = context->getCaps();
3142 if (static_cast<size_t>(location) >=
3143 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3144 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003145 context->handleError(InvalidValue() << "Location must be less than "
3146 "(MAX_VERTEX_UNIFORM_VECTORS + "
3147 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003148 return false;
3149 }
3150
Geoff Langfc32e8b2017-05-31 14:16:59 -04003151 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3152 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003153 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003154 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003155 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003156 return false;
3157 }
3158
Geoff Langd8605522016-04-13 10:19:12 -04003159 if (strncmp(name, "gl_", 3) == 0)
3160 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003161 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003162 return false;
3163 }
3164
3165 return true;
3166}
3167
Jamie Madille2e406c2016-06-02 13:04:10 -04003168bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003169{
3170 if (!context->getExtensions().framebufferMixedSamples)
3171 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003172 context->handleError(InvalidOperation()
3173 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003174 return false;
3175 }
3176 switch (components)
3177 {
3178 case GL_RGB:
3179 case GL_RGBA:
3180 case GL_ALPHA:
3181 case GL_NONE:
3182 break;
3183 default:
3184 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003185 InvalidEnum()
3186 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003187 return false;
3188 }
3189
3190 return true;
3191}
3192
Sami Väisänene45e53b2016-05-25 10:36:04 +03003193// CHROMIUM_path_rendering
3194
Jamie Madill007530e2017-12-28 14:27:04 -05003195bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003196{
Jamie Madill007530e2017-12-28 14:27:04 -05003197 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003198 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003199 return false;
3200 }
Jamie Madill007530e2017-12-28 14:27:04 -05003201
Sami Väisänene45e53b2016-05-25 10:36:04 +03003202 if (matrix == nullptr)
3203 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003204 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003205 return false;
3206 }
Jamie Madill007530e2017-12-28 14:27:04 -05003207
Sami Väisänene45e53b2016-05-25 10:36:04 +03003208 return true;
3209}
3210
Jamie Madill007530e2017-12-28 14:27:04 -05003211bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003212{
Jamie Madill007530e2017-12-28 14:27:04 -05003213 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003214}
3215
Jamie Madill007530e2017-12-28 14:27:04 -05003216bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003217{
3218 if (!context->getExtensions().pathRendering)
3219 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003220 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003221 return false;
3222 }
3223
3224 // range = 0 is undefined in NV_path_rendering.
3225 // we add stricter semantic check here and require a non zero positive range.
3226 if (range <= 0)
3227 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003228 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003229 return false;
3230 }
3231
3232 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3233 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003234 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003235 return false;
3236 }
3237
3238 return true;
3239}
3240
Jamie Madill007530e2017-12-28 14:27:04 -05003241bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003242{
3243 if (!context->getExtensions().pathRendering)
3244 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003245 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003246 return false;
3247 }
3248
3249 // range = 0 is undefined in NV_path_rendering.
3250 // we add stricter semantic check here and require a non zero positive range.
3251 if (range <= 0)
3252 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003253 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003254 return false;
3255 }
3256
3257 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3258 checkedRange += range;
3259
3260 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3261 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003262 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003263 return false;
3264 }
3265 return true;
3266}
3267
Jamie Madill007530e2017-12-28 14:27:04 -05003268bool ValidatePathCommandsCHROMIUM(Context *context,
3269 GLuint path,
3270 GLsizei numCommands,
3271 const GLubyte *commands,
3272 GLsizei numCoords,
3273 GLenum coordType,
3274 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003275{
3276 if (!context->getExtensions().pathRendering)
3277 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003278 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003279 return false;
3280 }
Brandon Jones59770802018-04-02 13:18:42 -07003281 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003282 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003283 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003284 return false;
3285 }
3286
3287 if (numCommands < 0)
3288 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003289 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003290 return false;
3291 }
3292 else if (numCommands > 0)
3293 {
3294 if (!commands)
3295 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003296 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003297 return false;
3298 }
3299 }
3300
3301 if (numCoords < 0)
3302 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003303 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003304 return false;
3305 }
3306 else if (numCoords > 0)
3307 {
3308 if (!coords)
3309 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003310 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003311 return false;
3312 }
3313 }
3314
3315 std::uint32_t coordTypeSize = 0;
3316 switch (coordType)
3317 {
3318 case GL_BYTE:
3319 coordTypeSize = sizeof(GLbyte);
3320 break;
3321
3322 case GL_UNSIGNED_BYTE:
3323 coordTypeSize = sizeof(GLubyte);
3324 break;
3325
3326 case GL_SHORT:
3327 coordTypeSize = sizeof(GLshort);
3328 break;
3329
3330 case GL_UNSIGNED_SHORT:
3331 coordTypeSize = sizeof(GLushort);
3332 break;
3333
3334 case GL_FLOAT:
3335 coordTypeSize = sizeof(GLfloat);
3336 break;
3337
3338 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003339 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003340 return false;
3341 }
3342
3343 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3344 checkedSize += (coordTypeSize * numCoords);
3345 if (!checkedSize.IsValid())
3346 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003347 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003348 return false;
3349 }
3350
3351 // early return skips command data validation when it doesn't exist.
3352 if (!commands)
3353 return true;
3354
3355 GLsizei expectedNumCoords = 0;
3356 for (GLsizei i = 0; i < numCommands; ++i)
3357 {
3358 switch (commands[i])
3359 {
3360 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3361 break;
3362 case GL_MOVE_TO_CHROMIUM:
3363 case GL_LINE_TO_CHROMIUM:
3364 expectedNumCoords += 2;
3365 break;
3366 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3367 expectedNumCoords += 4;
3368 break;
3369 case GL_CUBIC_CURVE_TO_CHROMIUM:
3370 expectedNumCoords += 6;
3371 break;
3372 case GL_CONIC_CURVE_TO_CHROMIUM:
3373 expectedNumCoords += 5;
3374 break;
3375 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003376 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003377 return false;
3378 }
3379 }
3380 if (expectedNumCoords != numCoords)
3381 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003382 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003383 return false;
3384 }
3385
3386 return true;
3387}
3388
Jamie Madill007530e2017-12-28 14:27:04 -05003389bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003390{
3391 if (!context->getExtensions().pathRendering)
3392 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003393 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003394 return false;
3395 }
Brandon Jones59770802018-04-02 13:18:42 -07003396 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003397 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003398 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003399 return false;
3400 }
3401
3402 switch (pname)
3403 {
3404 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3405 if (value < 0.0f)
3406 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003407 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003408 return false;
3409 }
3410 break;
3411 case GL_PATH_END_CAPS_CHROMIUM:
3412 switch (static_cast<GLenum>(value))
3413 {
3414 case GL_FLAT_CHROMIUM:
3415 case GL_SQUARE_CHROMIUM:
3416 case GL_ROUND_CHROMIUM:
3417 break;
3418 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003419 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003420 return false;
3421 }
3422 break;
3423 case GL_PATH_JOIN_STYLE_CHROMIUM:
3424 switch (static_cast<GLenum>(value))
3425 {
3426 case GL_MITER_REVERT_CHROMIUM:
3427 case GL_BEVEL_CHROMIUM:
3428 case GL_ROUND_CHROMIUM:
3429 break;
3430 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003431 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003432 return false;
3433 }
Nico Weber41b072b2018-02-09 10:01:32 -05003434 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003435 case GL_PATH_MITER_LIMIT_CHROMIUM:
3436 if (value < 0.0f)
3437 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003438 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003439 return false;
3440 }
3441 break;
3442
3443 case GL_PATH_STROKE_BOUND_CHROMIUM:
3444 // no errors, only clamping.
3445 break;
3446
3447 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003448 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003449 return false;
3450 }
3451 return true;
3452}
3453
Jamie Madill007530e2017-12-28 14:27:04 -05003454bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3455{
3456 // TODO(jmadill): Use proper clamping cast.
3457 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3458}
3459
3460bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003461{
3462 if (!context->getExtensions().pathRendering)
3463 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003464 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003465 return false;
3466 }
3467
Brandon Jones59770802018-04-02 13:18:42 -07003468 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003469 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003470 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471 return false;
3472 }
3473 if (!value)
3474 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003475 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003476 return false;
3477 }
3478
3479 switch (pname)
3480 {
3481 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3482 case GL_PATH_END_CAPS_CHROMIUM:
3483 case GL_PATH_JOIN_STYLE_CHROMIUM:
3484 case GL_PATH_MITER_LIMIT_CHROMIUM:
3485 case GL_PATH_STROKE_BOUND_CHROMIUM:
3486 break;
3487
3488 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003489 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003490 return false;
3491 }
3492
3493 return true;
3494}
3495
Jamie Madill007530e2017-12-28 14:27:04 -05003496bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3497{
3498 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3499 reinterpret_cast<GLfloat *>(value));
3500}
3501
3502bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003503{
3504 if (!context->getExtensions().pathRendering)
3505 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003506 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003507 return false;
3508 }
3509
3510 switch (func)
3511 {
3512 case GL_NEVER:
3513 case GL_ALWAYS:
3514 case GL_LESS:
3515 case GL_LEQUAL:
3516 case GL_EQUAL:
3517 case GL_GEQUAL:
3518 case GL_GREATER:
3519 case GL_NOTEQUAL:
3520 break;
3521 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003522 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003523 return false;
3524 }
3525
3526 return true;
3527}
3528
3529// Note that the spec specifies that for the path drawing commands
3530// if the path object is not an existing path object the command
3531// does nothing and no error is generated.
3532// However if the path object exists but has not been specified any
3533// commands then an error is generated.
3534
Jamie Madill007530e2017-12-28 14:27:04 -05003535bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003536{
3537 if (!context->getExtensions().pathRendering)
3538 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003539 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003540 return false;
3541 }
Brandon Jones59770802018-04-02 13:18:42 -07003542 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003543 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003544 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003545 return false;
3546 }
3547
3548 switch (fillMode)
3549 {
3550 case GL_COUNT_UP_CHROMIUM:
3551 case GL_COUNT_DOWN_CHROMIUM:
3552 break;
3553 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003554 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003555 return false;
3556 }
3557
3558 if (!isPow2(mask + 1))
3559 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003560 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003561 return false;
3562 }
3563
3564 return true;
3565}
3566
Jamie Madill007530e2017-12-28 14:27:04 -05003567bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003568{
3569 if (!context->getExtensions().pathRendering)
3570 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003571 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003572 return false;
3573 }
Brandon Jones59770802018-04-02 13:18:42 -07003574 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003575 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003576 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003577 return false;
3578 }
3579
3580 return true;
3581}
3582
Brandon Jonesd1049182018-03-28 10:02:20 -07003583bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3584{
3585 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3586}
3587
3588bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3589{
3590 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3591}
3592
Jamie Madill007530e2017-12-28 14:27:04 -05003593bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003594{
3595 if (!context->getExtensions().pathRendering)
3596 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003597 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003598 return false;
3599 }
Brandon Jones59770802018-04-02 13:18:42 -07003600 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003601 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003602 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003603 return false;
3604 }
3605
3606 switch (coverMode)
3607 {
3608 case GL_CONVEX_HULL_CHROMIUM:
3609 case GL_BOUNDING_BOX_CHROMIUM:
3610 break;
3611 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003612 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003613 return false;
3614 }
3615 return true;
3616}
3617
Jamie Madill007530e2017-12-28 14:27:04 -05003618bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3619 GLuint path,
3620 GLenum fillMode,
3621 GLuint mask,
3622 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003623{
Jamie Madill007530e2017-12-28 14:27:04 -05003624 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3625 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003626}
3627
Jamie Madill007530e2017-12-28 14:27:04 -05003628bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3629 GLuint path,
3630 GLint reference,
3631 GLuint mask,
3632 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003633{
Jamie Madill007530e2017-12-28 14:27:04 -05003634 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3635 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003636}
3637
Brandon Jonesd1049182018-03-28 10:02:20 -07003638bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003639{
3640 if (!context->getExtensions().pathRendering)
3641 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003642 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003643 return false;
3644 }
3645 return true;
3646}
3647
Jamie Madill007530e2017-12-28 14:27:04 -05003648bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3649 GLsizei numPaths,
3650 GLenum pathNameType,
3651 const void *paths,
3652 GLuint pathBase,
3653 GLenum coverMode,
3654 GLenum transformType,
3655 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003656{
3657 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3658 transformType, transformValues))
3659 return false;
3660
3661 switch (coverMode)
3662 {
3663 case GL_CONVEX_HULL_CHROMIUM:
3664 case GL_BOUNDING_BOX_CHROMIUM:
3665 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3666 break;
3667 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003668 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003669 return false;
3670 }
3671
3672 return true;
3673}
3674
Jamie Madill007530e2017-12-28 14:27:04 -05003675bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3676 GLsizei numPaths,
3677 GLenum pathNameType,
3678 const void *paths,
3679 GLuint pathBase,
3680 GLenum coverMode,
3681 GLenum transformType,
3682 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003683{
3684 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3685 transformType, transformValues))
3686 return false;
3687
3688 switch (coverMode)
3689 {
3690 case GL_CONVEX_HULL_CHROMIUM:
3691 case GL_BOUNDING_BOX_CHROMIUM:
3692 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3693 break;
3694 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003695 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003696 return false;
3697 }
3698
3699 return true;
3700}
3701
Jamie Madill007530e2017-12-28 14:27:04 -05003702bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3703 GLsizei numPaths,
3704 GLenum pathNameType,
3705 const void *paths,
3706 GLuint pathBase,
3707 GLenum fillMode,
3708 GLuint mask,
3709 GLenum transformType,
3710 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003711{
3712
3713 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3714 transformType, transformValues))
3715 return false;
3716
3717 switch (fillMode)
3718 {
3719 case GL_COUNT_UP_CHROMIUM:
3720 case GL_COUNT_DOWN_CHROMIUM:
3721 break;
3722 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003723 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003724 return false;
3725 }
3726 if (!isPow2(mask + 1))
3727 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003728 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003729 return false;
3730 }
3731 return true;
3732}
3733
Jamie Madill007530e2017-12-28 14:27:04 -05003734bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3735 GLsizei numPaths,
3736 GLenum pathNameType,
3737 const void *paths,
3738 GLuint pathBase,
3739 GLint reference,
3740 GLuint mask,
3741 GLenum transformType,
3742 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003743{
3744 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3745 transformType, transformValues))
3746 return false;
3747
3748 // no more validation here.
3749
3750 return true;
3751}
3752
Jamie Madill007530e2017-12-28 14:27:04 -05003753bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3754 GLsizei numPaths,
3755 GLenum pathNameType,
3756 const void *paths,
3757 GLuint pathBase,
3758 GLenum fillMode,
3759 GLuint mask,
3760 GLenum coverMode,
3761 GLenum transformType,
3762 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003763{
3764 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3765 transformType, transformValues))
3766 return false;
3767
3768 switch (coverMode)
3769 {
3770 case GL_CONVEX_HULL_CHROMIUM:
3771 case GL_BOUNDING_BOX_CHROMIUM:
3772 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3773 break;
3774 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003775 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003776 return false;
3777 }
3778
3779 switch (fillMode)
3780 {
3781 case GL_COUNT_UP_CHROMIUM:
3782 case GL_COUNT_DOWN_CHROMIUM:
3783 break;
3784 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003785 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003786 return false;
3787 }
3788 if (!isPow2(mask + 1))
3789 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003790 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003791 return false;
3792 }
3793
3794 return true;
3795}
3796
Jamie Madill007530e2017-12-28 14:27:04 -05003797bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3798 GLsizei numPaths,
3799 GLenum pathNameType,
3800 const void *paths,
3801 GLuint pathBase,
3802 GLint reference,
3803 GLuint mask,
3804 GLenum coverMode,
3805 GLenum transformType,
3806 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003807{
3808 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3809 transformType, transformValues))
3810 return false;
3811
3812 switch (coverMode)
3813 {
3814 case GL_CONVEX_HULL_CHROMIUM:
3815 case GL_BOUNDING_BOX_CHROMIUM:
3816 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3817 break;
3818 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003819 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003820 return false;
3821 }
3822
3823 return true;
3824}
3825
Jamie Madill007530e2017-12-28 14:27:04 -05003826bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3827 GLuint program,
3828 GLint location,
3829 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003830{
3831 if (!context->getExtensions().pathRendering)
3832 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003833 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003834 return false;
3835 }
3836
3837 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3838 if (location >= MaxLocation)
3839 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003840 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003841 return false;
3842 }
3843
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003844 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003845 if (!programObject)
3846 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003847 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003848 return false;
3849 }
3850
3851 if (!name)
3852 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003853 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003854 return false;
3855 }
3856
3857 if (angle::BeginsWith(name, "gl_"))
3858 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003859 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003860 return false;
3861 }
3862
3863 return true;
3864}
3865
Jamie Madill007530e2017-12-28 14:27:04 -05003866bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3867 GLuint program,
3868 GLint location,
3869 GLenum genMode,
3870 GLint components,
3871 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003872{
3873 if (!context->getExtensions().pathRendering)
3874 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003875 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003876 return false;
3877 }
3878
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003879 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003880 if (!programObject || programObject->isFlaggedForDeletion())
3881 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003882 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003883 return false;
3884 }
3885
3886 if (!programObject->isLinked())
3887 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003888 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003889 return false;
3890 }
3891
3892 switch (genMode)
3893 {
3894 case GL_NONE:
3895 if (components != 0)
3896 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003897 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003898 return false;
3899 }
3900 break;
3901
3902 case GL_OBJECT_LINEAR_CHROMIUM:
3903 case GL_EYE_LINEAR_CHROMIUM:
3904 case GL_CONSTANT_CHROMIUM:
3905 if (components < 1 || components > 4)
3906 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003907 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003908 return false;
3909 }
3910 if (!coeffs)
3911 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003912 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003913 return false;
3914 }
3915 break;
3916
3917 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003918 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003919 return false;
3920 }
3921
3922 // If the location is -1 then the command is silently ignored
3923 // and no further validation is needed.
3924 if (location == -1)
3925 return true;
3926
jchen103fd614d2018-08-13 12:21:58 +08003927 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003928
3929 if (!binding.valid)
3930 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003931 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003932 return false;
3933 }
3934
3935 if (binding.type != GL_NONE)
3936 {
3937 GLint expectedComponents = 0;
3938 switch (binding.type)
3939 {
3940 case GL_FLOAT:
3941 expectedComponents = 1;
3942 break;
3943 case GL_FLOAT_VEC2:
3944 expectedComponents = 2;
3945 break;
3946 case GL_FLOAT_VEC3:
3947 expectedComponents = 3;
3948 break;
3949 case GL_FLOAT_VEC4:
3950 expectedComponents = 4;
3951 break;
3952 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003953 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003954 InvalidOperation()
3955 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003956 return false;
3957 }
3958 if (expectedComponents != components && genMode != GL_NONE)
3959 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003960 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003961 return false;
3962 }
3963 }
3964 return true;
3965}
3966
Geoff Lang97073d12016-04-20 10:42:34 -07003967bool ValidateCopyTextureCHROMIUM(Context *context,
3968 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003969 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003970 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003971 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003972 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003973 GLint internalFormat,
3974 GLenum destType,
3975 GLboolean unpackFlipY,
3976 GLboolean unpackPremultiplyAlpha,
3977 GLboolean unpackUnmultiplyAlpha)
3978{
3979 if (!context->getExtensions().copyTexture)
3980 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003981 context->handleError(InvalidOperation()
3982 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003983 return false;
3984 }
3985
Geoff Lang4f0e0032017-05-01 16:04:35 -04003986 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003987 if (source == nullptr)
3988 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003989 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003990 return false;
3991 }
3992
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003993 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003994 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07003995 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003996 return false;
3997 }
3998
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003999 TextureType sourceType = source->getType();
4000 ASSERT(sourceType != TextureType::CubeMap);
4001 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004002
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004003 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004004 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004005 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004006 return false;
4007 }
4008
Geoff Lang4f0e0032017-05-01 16:04:35 -04004009 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4010 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4011 if (sourceWidth == 0 || sourceHeight == 0)
4012 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004013 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004014 return false;
4015 }
4016
4017 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4018 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004019 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004020 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004021 return false;
4022 }
4023
Geoff Lang63458a32017-10-30 15:16:53 -04004024 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4025 {
4026 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4027 return false;
4028 }
4029
Geoff Lang4f0e0032017-05-01 16:04:35 -04004030 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004031 if (dest == nullptr)
4032 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004033 context->handleError(InvalidValue()
4034 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004035 return false;
4036 }
4037
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004038 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004039 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004040 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004041 return false;
4042 }
4043
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004044 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004045 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004046 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004047 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004048 return false;
4049 }
4050
Geoff Lang97073d12016-04-20 10:42:34 -07004051 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4052 {
Geoff Lang97073d12016-04-20 10:42:34 -07004053 return false;
4054 }
4055
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004056 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004058 context->handleError(
4059 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004060 return false;
4061 }
4062
Geoff Lang97073d12016-04-20 10:42:34 -07004063 if (dest->getImmutableFormat())
4064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004065 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07004066 return false;
4067 }
4068
4069 return true;
4070}
4071
4072bool ValidateCopySubTextureCHROMIUM(Context *context,
4073 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004074 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004075 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004076 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004077 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004078 GLint xoffset,
4079 GLint yoffset,
4080 GLint x,
4081 GLint y,
4082 GLsizei width,
4083 GLsizei height,
4084 GLboolean unpackFlipY,
4085 GLboolean unpackPremultiplyAlpha,
4086 GLboolean unpackUnmultiplyAlpha)
4087{
4088 if (!context->getExtensions().copyTexture)
4089 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004090 context->handleError(InvalidOperation()
4091 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004092 return false;
4093 }
4094
Geoff Lang4f0e0032017-05-01 16:04:35 -04004095 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004096 if (source == nullptr)
4097 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004098 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004099 return false;
4100 }
4101
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004102 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004103 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004104 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004105 return false;
4106 }
4107
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004108 TextureType sourceType = source->getType();
4109 ASSERT(sourceType != TextureType::CubeMap);
4110 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004111
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004112 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004113 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004114 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004115 return false;
4116 }
4117
4118 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4119 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004120 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004121 context->handleError(InvalidValue()
4122 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004123 return false;
4124 }
4125
4126 if (x < 0 || y < 0)
4127 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004128 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004129 return false;
4130 }
4131
4132 if (width < 0 || height < 0)
4133 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004134 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004135 return false;
4136 }
4137
Geoff Lang4f0e0032017-05-01 16:04:35 -04004138 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4139 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004140 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004141 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004142 return false;
4143 }
4144
Geoff Lang4f0e0032017-05-01 16:04:35 -04004145 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4146 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004147 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004148 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004149 return false;
4150 }
4151
Geoff Lang63458a32017-10-30 15:16:53 -04004152 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4153 {
4154 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4155 return false;
4156 }
4157
Geoff Lang4f0e0032017-05-01 16:04:35 -04004158 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004159 if (dest == nullptr)
4160 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004161 context->handleError(InvalidValue()
4162 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004163 return false;
4164 }
4165
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004166 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004168 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004169 return false;
4170 }
4171
Brandon Jones28783792018-03-05 09:37:32 -08004172 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4173 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004175 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004176 return false;
4177 }
4178
Geoff Lang4f0e0032017-05-01 16:04:35 -04004179 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4180 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004181 context
4182 ->handleError(InvalidOperation()
4183 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004184 return false;
4185 }
4186
4187 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4188 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004190 context->handleError(InvalidOperation()
4191 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004192 return false;
4193 }
4194
4195 if (xoffset < 0 || yoffset < 0)
4196 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004197 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004198 return false;
4199 }
4200
Geoff Lang4f0e0032017-05-01 16:04:35 -04004201 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4202 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004203 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004204 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004205 return false;
4206 }
4207
4208 return true;
4209}
4210
Geoff Lang47110bf2016-04-20 11:13:22 -07004211bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4212{
4213 if (!context->getExtensions().copyCompressedTexture)
4214 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004215 context->handleError(InvalidOperation()
4216 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004217 return false;
4218 }
4219
4220 const gl::Texture *source = context->getTexture(sourceId);
4221 if (source == nullptr)
4222 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004223 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004224 return false;
4225 }
4226
Corentin Wallez99d492c2018-02-27 15:17:10 -05004227 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004228 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004229 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004230 return false;
4231 }
4232
Corentin Wallez99d492c2018-02-27 15:17:10 -05004233 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4234 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004235 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004236 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004237 return false;
4238 }
4239
Corentin Wallez99d492c2018-02-27 15:17:10 -05004240 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004241 if (!sourceFormat.info->compressed)
4242 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004243 context->handleError(InvalidOperation()
4244 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004245 return false;
4246 }
4247
4248 const gl::Texture *dest = context->getTexture(destId);
4249 if (dest == nullptr)
4250 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004251 context->handleError(InvalidValue()
4252 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004253 return false;
4254 }
4255
Corentin Wallez99d492c2018-02-27 15:17:10 -05004256 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004257 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004258 context->handleError(InvalidValue()
4259 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004260 return false;
4261 }
4262
4263 if (dest->getImmutableFormat())
4264 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004265 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004266 return false;
4267 }
4268
4269 return true;
4270}
4271
Jiawei Shao385b3e02018-03-21 09:43:28 +08004272bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004273{
4274 switch (type)
4275 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004276 case ShaderType::Vertex:
4277 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004278 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004279
Jiawei Shao385b3e02018-03-21 09:43:28 +08004280 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004281 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004282 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004283 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004284 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004285 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004286 break;
4287
Jiawei Shao385b3e02018-03-21 09:43:28 +08004288 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004289 if (!context->getExtensions().geometryShader)
4290 {
4291 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4292 return false;
4293 }
4294 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004295 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004296 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004297 return false;
4298 }
Jamie Madill29639852016-09-02 15:00:09 -04004299
4300 return true;
4301}
4302
Jamie Madill5b772312018-03-08 20:28:32 -05004303bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004304 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004305 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004306 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004307 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004308{
4309 if (size < 0)
4310 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004311 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004312 return false;
4313 }
4314
4315 switch (usage)
4316 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004317 case BufferUsage::StreamDraw:
4318 case BufferUsage::StaticDraw:
4319 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004320 break;
4321
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004322 case BufferUsage::StreamRead:
4323 case BufferUsage::StaticRead:
4324 case BufferUsage::DynamicRead:
4325 case BufferUsage::StreamCopy:
4326 case BufferUsage::StaticCopy:
4327 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004328 if (context->getClientMajorVersion() < 3)
4329 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004330 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004331 return false;
4332 }
4333 break;
4334
4335 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004336 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004337 return false;
4338 }
4339
Corentin Walleze4477002017-12-01 14:39:58 -05004340 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004341 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004342 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004343 return false;
4344 }
4345
4346 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4347
4348 if (!buffer)
4349 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004351 return false;
4352 }
4353
James Darpiniane8a93c62018-01-04 18:02:24 -08004354 if (context->getExtensions().webglCompatibility &&
4355 buffer->isBoundForTransformFeedbackAndOtherUse())
4356 {
4357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4358 return false;
4359 }
4360
Jamie Madill29639852016-09-02 15:00:09 -04004361 return true;
4362}
4363
Jamie Madill5b772312018-03-08 20:28:32 -05004364bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004365 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004366 GLintptr offset,
4367 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004368 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004369{
Brandon Jones6cad5662017-06-14 13:25:13 -07004370 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004371 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004372 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4373 return false;
4374 }
4375
4376 if (offset < 0)
4377 {
4378 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004379 return false;
4380 }
4381
Corentin Walleze4477002017-12-01 14:39:58 -05004382 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004383 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004384 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004385 return false;
4386 }
4387
4388 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4389
4390 if (!buffer)
4391 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004392 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004393 return false;
4394 }
4395
4396 if (buffer->isMapped())
4397 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004398 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004399 return false;
4400 }
4401
James Darpiniane8a93c62018-01-04 18:02:24 -08004402 if (context->getExtensions().webglCompatibility &&
4403 buffer->isBoundForTransformFeedbackAndOtherUse())
4404 {
4405 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4406 return false;
4407 }
4408
Jamie Madill29639852016-09-02 15:00:09 -04004409 // Check for possible overflow of size + offset
4410 angle::CheckedNumeric<size_t> checkedSize(size);
4411 checkedSize += offset;
4412 if (!checkedSize.IsValid())
4413 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004414 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004415 return false;
4416 }
4417
4418 if (size + offset > buffer->getSize())
4419 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004420 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004421 return false;
4422 }
4423
Martin Radev4c4c8e72016-08-04 12:25:34 +03004424 return true;
4425}
4426
Geoff Lang111a99e2017-10-17 10:58:41 -04004427bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004428{
Geoff Langc339c4e2016-11-29 10:37:36 -05004429 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004430 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004431 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004432 return false;
4433 }
4434
Geoff Lang111a99e2017-10-17 10:58:41 -04004435 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004436 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004437 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004438 return false;
4439 }
4440
4441 return true;
4442}
4443
Jamie Madill5b772312018-03-08 20:28:32 -05004444bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004445{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004446 if (context->getClientMajorVersion() < 2)
4447 {
4448 return ValidateMultitextureUnit(context, texture);
4449 }
4450
Jamie Madillef300b12016-10-07 15:12:09 -04004451 if (texture < GL_TEXTURE0 ||
4452 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4453 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004454 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004455 return false;
4456 }
4457
4458 return true;
4459}
4460
Jamie Madill5b772312018-03-08 20:28:32 -05004461bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004462{
4463 Program *programObject = GetValidProgram(context, program);
4464 if (!programObject)
4465 {
4466 return false;
4467 }
4468
4469 Shader *shaderObject = GetValidShader(context, shader);
4470 if (!shaderObject)
4471 {
4472 return false;
4473 }
4474
Jiawei Shao385b3e02018-03-21 09:43:28 +08004475 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004476 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004477 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4478 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004479 }
4480
4481 return true;
4482}
4483
Jamie Madill5b772312018-03-08 20:28:32 -05004484bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004485{
4486 if (index >= MAX_VERTEX_ATTRIBS)
4487 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004488 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004489 return false;
4490 }
4491
4492 if (strncmp(name, "gl_", 3) == 0)
4493 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004494 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004495 return false;
4496 }
4497
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004498 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004499 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004500 const size_t length = strlen(name);
4501
4502 if (!IsValidESSLString(name, length))
4503 {
4504 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4505 // for shader-related entry points
4506 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4507 return false;
4508 }
4509
4510 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4511 {
4512 return false;
4513 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004514 }
4515
Jamie Madill01a80ee2016-11-07 12:06:18 -05004516 return GetValidProgram(context, program) != nullptr;
4517}
4518
Jamie Madill5b772312018-03-08 20:28:32 -05004519bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004520{
Geoff Lange8afa902017-09-27 15:00:43 -04004521 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004522 {
Jamie Madilla139f012018-10-10 16:13:03 -04004523 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004524 return false;
4525 }
4526
4527 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4528 !context->isFramebufferGenerated(framebuffer))
4529 {
Jamie Madilla139f012018-10-10 16:13:03 -04004530 context->validationError(GL_INVALID_OPERATION, kErrorObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004531 return false;
4532 }
4533
4534 return true;
4535}
4536
Jamie Madill5b772312018-03-08 20:28:32 -05004537bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004538{
4539 if (target != GL_RENDERBUFFER)
4540 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004541 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004542 return false;
4543 }
4544
4545 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4546 !context->isRenderbufferGenerated(renderbuffer))
4547 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004548 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004549 return false;
4550 }
4551
4552 return true;
4553}
4554
Jamie Madill5b772312018-03-08 20:28:32 -05004555static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004556{
4557 switch (mode)
4558 {
4559 case GL_FUNC_ADD:
4560 case GL_FUNC_SUBTRACT:
4561 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004562 return true;
4563
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004564 case GL_MIN:
4565 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004566 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004567
4568 default:
4569 return false;
4570 }
4571}
4572
Jamie Madill5b772312018-03-08 20:28:32 -05004573bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004574{
4575 return true;
4576}
4577
Jamie Madill5b772312018-03-08 20:28:32 -05004578bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004579{
Geoff Lang50cac572017-09-26 17:37:43 -04004580 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004581 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004582 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004583 return false;
4584 }
4585
4586 return true;
4587}
4588
Jamie Madill5b772312018-03-08 20:28:32 -05004589bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004590{
Geoff Lang50cac572017-09-26 17:37:43 -04004591 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004592 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004593 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004594 return false;
4595 }
4596
Geoff Lang50cac572017-09-26 17:37:43 -04004597 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004598 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004599 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004600 return false;
4601 }
4602
4603 return true;
4604}
4605
Jamie Madill5b772312018-03-08 20:28:32 -05004606bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004607{
4608 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4609}
4610
Jamie Madill5b772312018-03-08 20:28:32 -05004611bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004612 GLenum srcRGB,
4613 GLenum dstRGB,
4614 GLenum srcAlpha,
4615 GLenum dstAlpha)
4616{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004617 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004618 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004619 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004620 return false;
4621 }
4622
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004623 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004624 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004625 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004626 return false;
4627 }
4628
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004629 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004630 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004631 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004632 return false;
4633 }
4634
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004635 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004636 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004637 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004638 return false;
4639 }
4640
Frank Henigman146e8a12017-03-02 23:22:37 -05004641 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4642 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004643 {
4644 bool constantColorUsed =
4645 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4646 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4647
4648 bool constantAlphaUsed =
4649 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4650 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4651
4652 if (constantColorUsed && constantAlphaUsed)
4653 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004654 const char *msg;
4655 if (context->getExtensions().webglCompatibility)
4656 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004657 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004658 }
4659 else
4660 {
4661 msg =
4662 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4663 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4664 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004665 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004666 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004667 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004668 return false;
4669 }
4670 }
4671
4672 return true;
4673}
4674
Geoff Langc339c4e2016-11-29 10:37:36 -05004675bool ValidateGetString(Context *context, GLenum name)
4676{
4677 switch (name)
4678 {
4679 case GL_VENDOR:
4680 case GL_RENDERER:
4681 case GL_VERSION:
4682 case GL_SHADING_LANGUAGE_VERSION:
4683 case GL_EXTENSIONS:
4684 break;
4685
4686 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4687 if (!context->getExtensions().requestExtension)
4688 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004689 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004690 return false;
4691 }
4692 break;
4693
4694 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004695 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004696 return false;
4697 }
4698
4699 return true;
4700}
4701
Jamie Madill5b772312018-03-08 20:28:32 -05004702bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004703{
4704 if (width <= 0.0f || isNaN(width))
4705 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004706 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004707 return false;
4708 }
4709
4710 return true;
4711}
4712
Jamie Madill5b772312018-03-08 20:28:32 -05004713bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004714 GLuint index,
4715 GLint size,
4716 GLenum type,
4717 GLboolean normalized,
4718 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004719 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004720{
Shao80957d92017-02-20 21:25:59 +08004721 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004722 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004723 return false;
4724 }
4725
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004726 if (stride < 0)
4727 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004728 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004729 return false;
4730 }
4731
Shao80957d92017-02-20 21:25:59 +08004732 const Caps &caps = context->getCaps();
4733 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004734 {
Shao80957d92017-02-20 21:25:59 +08004735 if (stride > caps.maxVertexAttribStride)
4736 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004737 context->handleError(InvalidValue()
4738 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004739 return false;
4740 }
4741
4742 if (index >= caps.maxVertexAttribBindings)
4743 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004744 context->handleError(InvalidValue()
4745 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004746 return false;
4747 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004748 }
4749
4750 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4751 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4752 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4753 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004754 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4755 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004756 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4757 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004759 context
4760 ->handleError(InvalidOperation()
4761 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004762 return false;
4763 }
4764
4765 if (context->getExtensions().webglCompatibility)
4766 {
4767 // WebGL 1.0 [Section 6.14] Fixed point support
4768 // The WebGL API does not support the GL_FIXED data type.
4769 if (type == GL_FIXED)
4770 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004771 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004772 return false;
4773 }
4774
Geoff Lang2d62ab72017-03-23 16:54:40 -04004775 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004776 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004777 return false;
4778 }
4779 }
4780
4781 return true;
4782}
4783
Jamie Madill5b772312018-03-08 20:28:32 -05004784bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004785{
4786 if (context->getExtensions().webglCompatibility && zNear > zFar)
4787 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004788 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004789 return false;
4790 }
4791
4792 return true;
4793}
4794
Jamie Madill5b772312018-03-08 20:28:32 -05004795bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004796 GLenum target,
4797 GLenum internalformat,
4798 GLsizei width,
4799 GLsizei height)
4800{
4801 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4802 height);
4803}
4804
Jamie Madill5b772312018-03-08 20:28:32 -05004805bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004806 GLenum target,
4807 GLsizei samples,
4808 GLenum internalformat,
4809 GLsizei width,
4810 GLsizei height)
4811{
4812 if (!context->getExtensions().framebufferMultisample)
4813 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004814 context->handleError(InvalidOperation()
4815 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004816 return false;
4817 }
4818
4819 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4820 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4821 // generated.
4822 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4823 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004824 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004825 return false;
4826 }
4827
4828 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4829 // the specified storage. This is different than ES 3.0 in which a sample number higher
4830 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4831 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4832 if (context->getClientMajorVersion() >= 3)
4833 {
4834 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4835 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4836 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004837 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004838 return false;
4839 }
4840 }
4841
4842 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4843 width, height);
4844}
4845
Jamie Madill5b772312018-03-08 20:28:32 -05004846bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004847{
Geoff Lange8afa902017-09-27 15:00:43 -04004848 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004849 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004850 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004851 return false;
4852 }
4853
4854 return true;
4855}
4856
Jamie Madill5b772312018-03-08 20:28:32 -05004857bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004858{
4859 return true;
4860}
4861
Jamie Madill5b772312018-03-08 20:28:32 -05004862bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004863{
4864 return true;
4865}
4866
Jamie Madill5b772312018-03-08 20:28:32 -05004867bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004868{
4869 return true;
4870}
4871
Jamie Madill5b772312018-03-08 20:28:32 -05004872bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004873 GLboolean red,
4874 GLboolean green,
4875 GLboolean blue,
4876 GLboolean alpha)
4877{
4878 return true;
4879}
4880
Jamie Madill5b772312018-03-08 20:28:32 -05004881bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004882{
4883 return true;
4884}
4885
Jamie Madill5b772312018-03-08 20:28:32 -05004886bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004887{
4888 return true;
4889}
4890
Jamie Madill5b772312018-03-08 20:28:32 -05004891bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004892{
4893 switch (mode)
4894 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004895 case CullFaceMode::Front:
4896 case CullFaceMode::Back:
4897 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004898 break;
4899
4900 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004901 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004902 return false;
4903 }
4904
4905 return true;
4906}
4907
Jamie Madill5b772312018-03-08 20:28:32 -05004908bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004909{
4910 if (program == 0)
4911 {
4912 return false;
4913 }
4914
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004915 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004916 {
4917 if (context->getShader(program))
4918 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004919 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004920 return false;
4921 }
4922 else
4923 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004924 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004925 return false;
4926 }
4927 }
4928
4929 return true;
4930}
4931
Jamie Madill5b772312018-03-08 20:28:32 -05004932bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004933{
4934 if (shader == 0)
4935 {
4936 return false;
4937 }
4938
4939 if (!context->getShader(shader))
4940 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004941 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004942 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004943 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004944 return false;
4945 }
4946 else
4947 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004948 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004949 return false;
4950 }
4951 }
4952
4953 return true;
4954}
4955
Jamie Madill5b772312018-03-08 20:28:32 -05004956bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004957{
4958 switch (func)
4959 {
4960 case GL_NEVER:
4961 case GL_ALWAYS:
4962 case GL_LESS:
4963 case GL_LEQUAL:
4964 case GL_EQUAL:
4965 case GL_GREATER:
4966 case GL_GEQUAL:
4967 case GL_NOTEQUAL:
4968 break;
4969
4970 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004971 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004972 return false;
4973 }
4974
4975 return true;
4976}
4977
Jamie Madill5b772312018-03-08 20:28:32 -05004978bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004979{
4980 return true;
4981}
4982
Jamie Madill5b772312018-03-08 20:28:32 -05004983bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004984{
4985 Program *programObject = GetValidProgram(context, program);
4986 if (!programObject)
4987 {
4988 return false;
4989 }
4990
4991 Shader *shaderObject = GetValidShader(context, shader);
4992 if (!shaderObject)
4993 {
4994 return false;
4995 }
4996
Jiawei Shao385b3e02018-03-21 09:43:28 +08004997 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004998 if (attachedShader != shaderObject)
4999 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005000 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005001 return false;
5002 }
5003
5004 return true;
5005}
5006
Jamie Madill5b772312018-03-08 20:28:32 -05005007bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005008{
5009 if (index >= MAX_VERTEX_ATTRIBS)
5010 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005011 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005012 return false;
5013 }
5014
5015 return true;
5016}
5017
Jamie Madill5b772312018-03-08 20:28:32 -05005018bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005019{
5020 if (index >= MAX_VERTEX_ATTRIBS)
5021 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005022 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005023 return false;
5024 }
5025
5026 return true;
5027}
5028
Jamie Madill5b772312018-03-08 20:28:32 -05005029bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005030{
5031 return true;
5032}
5033
Jamie Madill5b772312018-03-08 20:28:32 -05005034bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005035{
5036 return true;
5037}
5038
Jamie Madill5b772312018-03-08 20:28:32 -05005039bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005040{
5041 switch (mode)
5042 {
5043 case GL_CW:
5044 case GL_CCW:
5045 break;
5046 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005047 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005048 return false;
5049 }
5050
5051 return true;
5052}
5053
Jamie Madill5b772312018-03-08 20:28:32 -05005054bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005055 GLuint program,
5056 GLuint index,
5057 GLsizei bufsize,
5058 GLsizei *length,
5059 GLint *size,
5060 GLenum *type,
5061 GLchar *name)
5062{
5063 if (bufsize < 0)
5064 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005065 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005066 return false;
5067 }
5068
5069 Program *programObject = GetValidProgram(context, program);
5070
5071 if (!programObject)
5072 {
5073 return false;
5074 }
5075
5076 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5077 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005078 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005079 return false;
5080 }
5081
5082 return true;
5083}
5084
Jamie Madill5b772312018-03-08 20:28:32 -05005085bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005086 GLuint program,
5087 GLuint index,
5088 GLsizei bufsize,
5089 GLsizei *length,
5090 GLint *size,
5091 GLenum *type,
5092 GLchar *name)
5093{
5094 if (bufsize < 0)
5095 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005096 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005097 return false;
5098 }
5099
5100 Program *programObject = GetValidProgram(context, program);
5101
5102 if (!programObject)
5103 {
5104 return false;
5105 }
5106
5107 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5108 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005109 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110 return false;
5111 }
5112
5113 return true;
5114}
5115
Jamie Madill5b772312018-03-08 20:28:32 -05005116bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005117 GLuint program,
5118 GLsizei maxcount,
5119 GLsizei *count,
5120 GLuint *shaders)
5121{
5122 if (maxcount < 0)
5123 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005124 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005125 return false;
5126 }
5127
5128 Program *programObject = GetValidProgram(context, program);
5129
5130 if (!programObject)
5131 {
5132 return false;
5133 }
5134
5135 return true;
5136}
5137
Jamie Madill5b772312018-03-08 20:28:32 -05005138bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005139{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005140 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5141 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005142 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005144 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005145 return false;
5146 }
5147
Jamie Madillc1d770e2017-04-13 17:31:24 -04005148 Program *programObject = GetValidProgram(context, program);
5149
5150 if (!programObject)
5151 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005152 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005153 return false;
5154 }
5155
5156 if (!programObject->isLinked())
5157 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005158 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005159 return false;
5160 }
5161
5162 return true;
5163}
5164
Jamie Madill5b772312018-03-08 20:28:32 -05005165bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005166{
5167 GLenum nativeType;
5168 unsigned int numParams = 0;
5169 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5170}
5171
Jamie Madill5b772312018-03-08 20:28:32 -05005172bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005173{
5174 return true;
5175}
5176
Jamie Madill5b772312018-03-08 20:28:32 -05005177bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005178{
5179 GLenum nativeType;
5180 unsigned int numParams = 0;
5181 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5182}
5183
Jamie Madill5b772312018-03-08 20:28:32 -05005184bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005185{
5186 GLenum nativeType;
5187 unsigned int numParams = 0;
5188 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5189}
5190
Jamie Madill5b772312018-03-08 20:28:32 -05005191bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005192 GLuint program,
5193 GLsizei bufsize,
5194 GLsizei *length,
5195 GLchar *infolog)
5196{
5197 if (bufsize < 0)
5198 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005199 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005200 return false;
5201 }
5202
5203 Program *programObject = GetValidProgram(context, program);
5204 if (!programObject)
5205 {
5206 return false;
5207 }
5208
5209 return true;
5210}
5211
Jamie Madill5b772312018-03-08 20:28:32 -05005212bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 GLuint shader,
5214 GLsizei bufsize,
5215 GLsizei *length,
5216 GLchar *infolog)
5217{
5218 if (bufsize < 0)
5219 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005220 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005221 return false;
5222 }
5223
5224 Shader *shaderObject = GetValidShader(context, shader);
5225 if (!shaderObject)
5226 {
5227 return false;
5228 }
5229
5230 return true;
5231}
5232
Jamie Madill5b772312018-03-08 20:28:32 -05005233bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005234 GLenum shadertype,
5235 GLenum precisiontype,
5236 GLint *range,
5237 GLint *precision)
5238{
5239 switch (shadertype)
5240 {
5241 case GL_VERTEX_SHADER:
5242 case GL_FRAGMENT_SHADER:
5243 break;
5244 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005245 context->handleError(InvalidOperation()
5246 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005247 return false;
5248 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005249 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005250 return false;
5251 }
5252
5253 switch (precisiontype)
5254 {
5255 case GL_LOW_FLOAT:
5256 case GL_MEDIUM_FLOAT:
5257 case GL_HIGH_FLOAT:
5258 case GL_LOW_INT:
5259 case GL_MEDIUM_INT:
5260 case GL_HIGH_INT:
5261 break;
5262
5263 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005264 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005265 return false;
5266 }
5267
5268 return true;
5269}
5270
Jamie Madill5b772312018-03-08 20:28:32 -05005271bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005272 GLuint shader,
5273 GLsizei bufsize,
5274 GLsizei *length,
5275 GLchar *source)
5276{
5277 if (bufsize < 0)
5278 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005279 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005280 return false;
5281 }
5282
5283 Shader *shaderObject = GetValidShader(context, shader);
5284 if (!shaderObject)
5285 {
5286 return false;
5287 }
5288
5289 return true;
5290}
5291
Jamie Madill5b772312018-03-08 20:28:32 -05005292bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293{
5294 if (strstr(name, "gl_") == name)
5295 {
5296 return false;
5297 }
5298
Geoff Langfc32e8b2017-05-31 14:16:59 -04005299 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5300 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005301 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005302 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005303 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005304 return false;
5305 }
5306
Jamie Madillc1d770e2017-04-13 17:31:24 -04005307 Program *programObject = GetValidProgram(context, program);
5308
5309 if (!programObject)
5310 {
5311 return false;
5312 }
5313
5314 if (!programObject->isLinked())
5315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005317 return false;
5318 }
5319
5320 return true;
5321}
5322
Jamie Madill5b772312018-03-08 20:28:32 -05005323bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005324{
5325 switch (mode)
5326 {
5327 case GL_FASTEST:
5328 case GL_NICEST:
5329 case GL_DONT_CARE:
5330 break;
5331
5332 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005333 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005334 return false;
5335 }
5336
5337 switch (target)
5338 {
5339 case GL_GENERATE_MIPMAP_HINT:
5340 break;
5341
Geoff Lange7bd2182017-06-16 16:13:13 -04005342 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5343 if (context->getClientVersion() < ES_3_0 &&
5344 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005346 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347 return false;
5348 }
5349 break;
5350
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005351 case GL_PERSPECTIVE_CORRECTION_HINT:
5352 case GL_POINT_SMOOTH_HINT:
5353 case GL_LINE_SMOOTH_HINT:
5354 case GL_FOG_HINT:
5355 if (context->getClientMajorVersion() >= 2)
5356 {
5357 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5358 return false;
5359 }
5360 break;
5361
Jamie Madillc1d770e2017-04-13 17:31:24 -04005362 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005363 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005364 return false;
5365 }
5366
5367 return true;
5368}
5369
Jamie Madill5b772312018-03-08 20:28:32 -05005370bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005371{
5372 return true;
5373}
5374
Jamie Madill5b772312018-03-08 20:28:32 -05005375bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005376{
5377 return true;
5378}
5379
Jamie Madill5b772312018-03-08 20:28:32 -05005380bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005381{
5382 return true;
5383}
5384
Jamie Madill5b772312018-03-08 20:28:32 -05005385bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005386{
5387 return true;
5388}
5389
Jamie Madill5b772312018-03-08 20:28:32 -05005390bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005391{
5392 return true;
5393}
5394
Jamie Madill5b772312018-03-08 20:28:32 -05005395bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005396{
5397 return true;
5398}
5399
Jamie Madill5b772312018-03-08 20:28:32 -05005400bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005401{
5402 if (context->getClientMajorVersion() < 3)
5403 {
5404 switch (pname)
5405 {
5406 case GL_UNPACK_IMAGE_HEIGHT:
5407 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005408 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005409 return false;
5410
5411 case GL_UNPACK_ROW_LENGTH:
5412 case GL_UNPACK_SKIP_ROWS:
5413 case GL_UNPACK_SKIP_PIXELS:
5414 if (!context->getExtensions().unpackSubimage)
5415 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005416 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005417 return false;
5418 }
5419 break;
5420
5421 case GL_PACK_ROW_LENGTH:
5422 case GL_PACK_SKIP_ROWS:
5423 case GL_PACK_SKIP_PIXELS:
5424 if (!context->getExtensions().packSubimage)
5425 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005426 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005427 return false;
5428 }
5429 break;
5430 }
5431 }
5432
5433 if (param < 0)
5434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005435 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005436 return false;
5437 }
5438
5439 switch (pname)
5440 {
5441 case GL_UNPACK_ALIGNMENT:
5442 if (param != 1 && param != 2 && param != 4 && param != 8)
5443 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005444 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005445 return false;
5446 }
5447 break;
5448
5449 case GL_PACK_ALIGNMENT:
5450 if (param != 1 && param != 2 && param != 4 && param != 8)
5451 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005452 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005453 return false;
5454 }
5455 break;
5456
5457 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005458 if (!context->getExtensions().packReverseRowOrder)
5459 {
5460 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5461 }
5462 break;
5463
Jamie Madillc1d770e2017-04-13 17:31:24 -04005464 case GL_UNPACK_ROW_LENGTH:
5465 case GL_UNPACK_IMAGE_HEIGHT:
5466 case GL_UNPACK_SKIP_IMAGES:
5467 case GL_UNPACK_SKIP_ROWS:
5468 case GL_UNPACK_SKIP_PIXELS:
5469 case GL_PACK_ROW_LENGTH:
5470 case GL_PACK_SKIP_ROWS:
5471 case GL_PACK_SKIP_PIXELS:
5472 break;
5473
5474 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005475 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005476 return false;
5477 }
5478
5479 return true;
5480}
5481
Jamie Madill5b772312018-03-08 20:28:32 -05005482bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005483{
5484 return true;
5485}
5486
Jamie Madill5b772312018-03-08 20:28:32 -05005487bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005488{
5489 return true;
5490}
5491
Jamie Madill5b772312018-03-08 20:28:32 -05005492bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005493{
5494 return true;
5495}
5496
Jamie Madill5b772312018-03-08 20:28:32 -05005497bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005498{
5499 if (width < 0 || height < 0)
5500 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005501 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005502 return false;
5503 }
5504
5505 return true;
5506}
5507
Jamie Madill5b772312018-03-08 20:28:32 -05005508bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005509 GLsizei n,
5510 const GLuint *shaders,
5511 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005512 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005513 GLsizei length)
5514{
5515 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5516 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5517 shaderBinaryFormats.end())
5518 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005519 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005520 return false;
5521 }
5522
5523 return true;
5524}
5525
Jamie Madill5b772312018-03-08 20:28:32 -05005526bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005527 GLuint shader,
5528 GLsizei count,
5529 const GLchar *const *string,
5530 const GLint *length)
5531{
5532 if (count < 0)
5533 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005534 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005535 return false;
5536 }
5537
Geoff Langfc32e8b2017-05-31 14:16:59 -04005538 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5539 // shader-related entry points
5540 if (context->getExtensions().webglCompatibility)
5541 {
5542 for (GLsizei i = 0; i < count; i++)
5543 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005544 size_t len =
5545 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005546
5547 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005548 if (!IsValidESSLShaderSourceString(string[i], len,
5549 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005550 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005551 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005552 return false;
5553 }
5554 }
5555 }
5556
Jamie Madillc1d770e2017-04-13 17:31:24 -04005557 Shader *shaderObject = GetValidShader(context, shader);
5558 if (!shaderObject)
5559 {
5560 return false;
5561 }
5562
5563 return true;
5564}
5565
Jamie Madill5b772312018-03-08 20:28:32 -05005566bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005567{
5568 if (!IsValidStencilFunc(func))
5569 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005570 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005571 return false;
5572 }
5573
5574 return true;
5575}
5576
Jamie Madill5b772312018-03-08 20:28:32 -05005577bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005578{
5579 if (!IsValidStencilFace(face))
5580 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005581 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005582 return false;
5583 }
5584
5585 if (!IsValidStencilFunc(func))
5586 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005587 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005588 return false;
5589 }
5590
5591 return true;
5592}
5593
Jamie Madill5b772312018-03-08 20:28:32 -05005594bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005595{
5596 return true;
5597}
5598
Jamie Madill5b772312018-03-08 20:28:32 -05005599bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005600{
5601 if (!IsValidStencilFace(face))
5602 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005603 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005604 return false;
5605 }
5606
5607 return true;
5608}
5609
Jamie Madill5b772312018-03-08 20:28:32 -05005610bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005611{
5612 if (!IsValidStencilOp(fail))
5613 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005614 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005615 return false;
5616 }
5617
5618 if (!IsValidStencilOp(zfail))
5619 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005620 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005621 return false;
5622 }
5623
5624 if (!IsValidStencilOp(zpass))
5625 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005626 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005627 return false;
5628 }
5629
5630 return true;
5631}
5632
Jamie Madill5b772312018-03-08 20:28:32 -05005633bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005634 GLenum face,
5635 GLenum fail,
5636 GLenum zfail,
5637 GLenum zpass)
5638{
5639 if (!IsValidStencilFace(face))
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 return ValidateStencilOp(context, fail, zfail, zpass);
5646}
5647
Jamie Madill5b772312018-03-08 20:28:32 -05005648bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005649{
5650 return ValidateUniform(context, GL_FLOAT, location, 1);
5651}
5652
Jamie Madill5b772312018-03-08 20:28:32 -05005653bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005654{
5655 return ValidateUniform(context, GL_FLOAT, location, count);
5656}
5657
Jamie Madill5b772312018-03-08 20:28:32 -05005658bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005659{
5660 return ValidateUniform1iv(context, location, 1, &x);
5661}
5662
Jamie Madill5b772312018-03-08 20:28:32 -05005663bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005664{
5665 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5666}
5667
Jamie Madill5b772312018-03-08 20:28:32 -05005668bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005669{
5670 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5671}
5672
Jamie Madill5b772312018-03-08 20:28:32 -05005673bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005674{
5675 return ValidateUniform(context, GL_INT_VEC2, location, count);
5676}
5677
Jamie Madill5b772312018-03-08 20:28:32 -05005678bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005679{
5680 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5681}
5682
Jamie Madill5b772312018-03-08 20:28:32 -05005683bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005684{
5685 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5686}
5687
Jamie Madill5b772312018-03-08 20:28:32 -05005688bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005689{
5690 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5691}
5692
Jamie Madill5b772312018-03-08 20:28:32 -05005693bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005694{
5695 return ValidateUniform(context, GL_INT_VEC3, location, count);
5696}
5697
Jamie Madill5b772312018-03-08 20:28:32 -05005698bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005699{
5700 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5701}
5702
Jamie Madill5b772312018-03-08 20:28:32 -05005703bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005704{
5705 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5706}
5707
Jamie Madill5b772312018-03-08 20:28:32 -05005708bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005709{
5710 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5711}
5712
Jamie Madill5b772312018-03-08 20:28:32 -05005713bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005714{
5715 return ValidateUniform(context, GL_INT_VEC4, location, count);
5716}
5717
Jamie Madill5b772312018-03-08 20:28:32 -05005718bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005719 GLint location,
5720 GLsizei count,
5721 GLboolean transpose,
5722 const GLfloat *value)
5723{
5724 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5725}
5726
Jamie Madill5b772312018-03-08 20:28:32 -05005727bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005728 GLint location,
5729 GLsizei count,
5730 GLboolean transpose,
5731 const GLfloat *value)
5732{
5733 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5734}
5735
Jamie Madill5b772312018-03-08 20:28:32 -05005736bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005737 GLint location,
5738 GLsizei count,
5739 GLboolean transpose,
5740 const GLfloat *value)
5741{
5742 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5743}
5744
Jamie Madill5b772312018-03-08 20:28:32 -05005745bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005746{
5747 Program *programObject = GetValidProgram(context, program);
5748
5749 if (!programObject)
5750 {
5751 return false;
5752 }
5753
5754 return true;
5755}
5756
Jamie Madill5b772312018-03-08 20:28:32 -05005757bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005758{
5759 return ValidateVertexAttribIndex(context, index);
5760}
5761
Jamie Madill5b772312018-03-08 20:28:32 -05005762bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005763{
5764 return ValidateVertexAttribIndex(context, index);
5765}
5766
Jamie Madill5b772312018-03-08 20:28:32 -05005767bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005768{
5769 return ValidateVertexAttribIndex(context, index);
5770}
5771
Jamie Madill5b772312018-03-08 20:28:32 -05005772bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005773{
5774 return ValidateVertexAttribIndex(context, index);
5775}
5776
Jamie Madill5b772312018-03-08 20:28:32 -05005777bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005778{
5779 return ValidateVertexAttribIndex(context, index);
5780}
5781
Jamie Madill5b772312018-03-08 20:28:32 -05005782bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005783{
5784 return ValidateVertexAttribIndex(context, index);
5785}
5786
Jamie Madill5b772312018-03-08 20:28:32 -05005787bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005788 GLuint index,
5789 GLfloat x,
5790 GLfloat y,
5791 GLfloat z,
5792 GLfloat w)
5793{
5794 return ValidateVertexAttribIndex(context, index);
5795}
5796
Jamie Madill5b772312018-03-08 20:28:32 -05005797bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005798{
5799 return ValidateVertexAttribIndex(context, index);
5800}
5801
Jamie Madill5b772312018-03-08 20:28:32 -05005802bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005803{
5804 if (width < 0 || height < 0)
5805 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005806 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005807 return false;
5808 }
5809
5810 return true;
5811}
5812
Jamie Madill5b772312018-03-08 20:28:32 -05005813bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005814 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005815 GLsizei count,
5816 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005817 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005818{
5819 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5820}
5821
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005822bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005823 GLenum target,
5824 GLenum attachment,
5825 GLenum pname,
5826 GLint *params)
5827{
5828 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5829 nullptr);
5830}
5831
Jamie Madill5b772312018-03-08 20:28:32 -05005832bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005833{
5834 return ValidateGetProgramivBase(context, program, pname, nullptr);
5835}
5836
Jamie Madill5b772312018-03-08 20:28:32 -05005837bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005838 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005839 GLint level,
5840 GLenum internalformat,
5841 GLint x,
5842 GLint y,
5843 GLsizei width,
5844 GLsizei height,
5845 GLint border)
5846{
5847 if (context->getClientMajorVersion() < 3)
5848 {
5849 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5850 0, x, y, width, height, border);
5851 }
5852
5853 ASSERT(context->getClientMajorVersion() == 3);
5854 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5855 0, x, y, width, height, border);
5856}
5857
5858bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005859 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005860 GLint level,
5861 GLint xoffset,
5862 GLint yoffset,
5863 GLint x,
5864 GLint y,
5865 GLsizei width,
5866 GLsizei height)
5867{
5868 if (context->getClientMajorVersion() < 3)
5869 {
5870 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5871 yoffset, x, y, width, height, 0);
5872 }
5873
5874 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5875 yoffset, 0, x, y, width, height, 0);
5876}
5877
5878bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5879{
5880 return ValidateGenOrDelete(context, n);
5881}
5882
5883bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5884{
5885 return ValidateGenOrDelete(context, n);
5886}
5887
5888bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5889{
5890 return ValidateGenOrDelete(context, n);
5891}
5892
5893bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5894{
5895 return ValidateGenOrDelete(context, n);
5896}
5897
5898bool ValidateDisable(Context *context, GLenum cap)
5899{
5900 if (!ValidCap(context, cap, false))
5901 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005902 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005903 return false;
5904 }
5905
5906 return true;
5907}
5908
5909bool ValidateEnable(Context *context, GLenum cap)
5910{
5911 if (!ValidCap(context, cap, false))
5912 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005913 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005914 return false;
5915 }
5916
5917 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5918 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5919 {
5920 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005921 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005922
5923 // We also output an error message to the debugger window if tracing is active, so that
5924 // developers can see the error message.
5925 ERR() << errorMessage;
5926 return false;
5927 }
5928
5929 return true;
5930}
5931
5932bool ValidateFramebufferRenderbuffer(Context *context,
5933 GLenum target,
5934 GLenum attachment,
5935 GLenum renderbuffertarget,
5936 GLuint renderbuffer)
5937{
Geoff Lange8afa902017-09-27 15:00:43 -04005938 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005939 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005940 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5941 return false;
5942 }
5943
5944 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5945 {
5946 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005947 return false;
5948 }
5949
5950 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5951 renderbuffertarget, renderbuffer);
5952}
5953
5954bool ValidateFramebufferTexture2D(Context *context,
5955 GLenum target,
5956 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005957 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005958 GLuint texture,
5959 GLint level)
5960{
5961 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5962 // extension
5963 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5964 level != 0)
5965 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005966 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005967 return false;
5968 }
5969
5970 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5971 {
5972 return false;
5973 }
5974
5975 if (texture != 0)
5976 {
5977 gl::Texture *tex = context->getTexture(texture);
5978 ASSERT(tex);
5979
5980 const gl::Caps &caps = context->getCaps();
5981
5982 switch (textarget)
5983 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005984 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005985 {
5986 if (level > gl::log2(caps.max2DTextureSize))
5987 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005988 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005989 return false;
5990 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005991 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005992 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005993 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005994 return false;
5995 }
5996 }
5997 break;
5998
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005999 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006000 {
6001 if (level != 0)
6002 {
6003 context->handleError(InvalidValue());
6004 return false;
6005 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006006 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006007 {
6008 context->handleError(InvalidOperation()
6009 << "Textarget must match the texture target type.");
6010 return false;
6011 }
6012 }
6013 break;
6014
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006015 case TextureTarget::CubeMapNegativeX:
6016 case TextureTarget::CubeMapNegativeY:
6017 case TextureTarget::CubeMapNegativeZ:
6018 case TextureTarget::CubeMapPositiveX:
6019 case TextureTarget::CubeMapPositiveY:
6020 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006021 {
6022 if (level > gl::log2(caps.maxCubeMapTextureSize))
6023 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006024 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006025 return false;
6026 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006027 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006028 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006029 context->handleError(InvalidOperation()
6030 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006031 return false;
6032 }
6033 }
6034 break;
6035
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006036 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 {
6038 if (context->getClientVersion() < ES_3_1)
6039 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006040 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006041 return false;
6042 }
6043
6044 if (level != 0)
6045 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006046 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006047 return false;
6048 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006049 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006050 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006051 context->handleError(InvalidOperation()
6052 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006053 return false;
6054 }
6055 }
6056 break;
6057
6058 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006059 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006060 return false;
6061 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006062 }
6063
6064 return true;
6065}
6066
6067bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6068{
6069 return ValidateGenOrDelete(context, n);
6070}
6071
6072bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6073{
6074 return ValidateGenOrDelete(context, n);
6075}
6076
6077bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6078{
6079 return ValidateGenOrDelete(context, n);
6080}
6081
6082bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6083{
6084 return ValidateGenOrDelete(context, n);
6085}
6086
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006087bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006088{
6089 if (!ValidTextureTarget(context, target))
6090 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006091 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006092 return false;
6093 }
6094
6095 Texture *texture = context->getTargetTexture(target);
6096
6097 if (texture == nullptr)
6098 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006099 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006100 return false;
6101 }
6102
6103 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6104
6105 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6106 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6107 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006109 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006110 return false;
6111 }
6112
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006113 TextureTarget baseTarget = (target == TextureType::CubeMap)
6114 ? TextureTarget::CubeMapPositiveX
6115 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006116 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6117 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6118 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006119 {
6120 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6121 return false;
6122 }
6123
Geoff Lang536eca12017-09-13 11:23:35 -04006124 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6125 bool formatUnsized = !format.sized;
6126 bool formatColorRenderableAndFilterable =
6127 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006128 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006129 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006130 {
Geoff Lang536eca12017-09-13 11:23:35 -04006131 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006132 return false;
6133 }
6134
Geoff Lang536eca12017-09-13 11:23:35 -04006135 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6136 // generation
6137 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6138 {
6139 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6140 return false;
6141 }
6142
Jiange2c00842018-07-13 16:50:49 +08006143 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6144 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6145 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006146 {
Geoff Lang536eca12017-09-13 11:23:35 -04006147 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006148 return false;
6149 }
6150
6151 // Non-power of 2 ES2 check
6152 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6153 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6154 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6155 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006156 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6157 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006158 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006159 return false;
6160 }
6161
6162 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006163 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006166 return false;
6167 }
6168
6169 return true;
6170}
6171
Jamie Madill5b772312018-03-08 20:28:32 -05006172bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006173 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006174 GLenum pname,
6175 GLint *params)
6176{
6177 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6178}
6179
6180bool ValidateGetRenderbufferParameteriv(Context *context,
6181 GLenum target,
6182 GLenum pname,
6183 GLint *params)
6184{
6185 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6186}
6187
6188bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6189{
6190 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6191}
6192
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006193bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006194{
6195 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6196}
6197
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006198bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006199{
6200 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6201}
6202
6203bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6204{
6205 return ValidateGetUniformBase(context, program, location);
6206}
6207
6208bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6209{
6210 return ValidateGetUniformBase(context, program, location);
6211}
6212
6213bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6214{
6215 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6216}
6217
6218bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6219{
6220 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6221}
6222
6223bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6224{
6225 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6226}
6227
6228bool ValidateIsEnabled(Context *context, GLenum cap)
6229{
6230 if (!ValidCap(context, cap, true))
6231 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006232 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006233 return false;
6234 }
6235
6236 return true;
6237}
6238
6239bool ValidateLinkProgram(Context *context, GLuint program)
6240{
6241 if (context->hasActiveTransformFeedback(program))
6242 {
6243 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006244 context->handleError(InvalidOperation() << "Cannot link program while program is "
6245 "associated with an active transform "
6246 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006247 return false;
6248 }
6249
6250 Program *programObject = GetValidProgram(context, program);
6251 if (!programObject)
6252 {
6253 return false;
6254 }
6255
6256 return true;
6257}
6258
Jamie Madill4928b7c2017-06-20 12:57:39 -04006259bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006260 GLint x,
6261 GLint y,
6262 GLsizei width,
6263 GLsizei height,
6264 GLenum format,
6265 GLenum type,
6266 void *pixels)
6267{
6268 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6269 nullptr, pixels);
6270}
6271
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006272bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006273{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006274 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006275}
6276
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006277bool ValidateTexParameterfv(Context *context,
6278 TextureType target,
6279 GLenum pname,
6280 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006281{
6282 return ValidateTexParameterBase(context, target, pname, -1, params);
6283}
6284
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006285bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006286{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006287 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006288}
6289
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006290bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006291{
6292 return ValidateTexParameterBase(context, target, pname, -1, params);
6293}
6294
6295bool ValidateUseProgram(Context *context, GLuint program)
6296{
6297 if (program != 0)
6298 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006299 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006300 if (!programObject)
6301 {
6302 // ES 3.1.0 section 7.3 page 72
6303 if (context->getShader(program))
6304 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006306 return false;
6307 }
6308 else
6309 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006310 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006311 return false;
6312 }
6313 }
6314 if (!programObject->isLinked())
6315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006316 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006317 return false;
6318 }
6319 }
6320 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6321 {
6322 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006323 context
6324 ->handleError(InvalidOperation()
6325 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006326 return false;
6327 }
6328
6329 return true;
6330}
6331
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006332bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6333{
6334 if (!context->getExtensions().fence)
6335 {
6336 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6337 return false;
6338 }
6339
6340 if (n < 0)
6341 {
6342 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6343 return false;
6344 }
6345
6346 return true;
6347}
6348
6349bool ValidateFinishFenceNV(Context *context, GLuint fence)
6350{
6351 if (!context->getExtensions().fence)
6352 {
6353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6354 return false;
6355 }
6356
6357 FenceNV *fenceObject = context->getFenceNV(fence);
6358
6359 if (fenceObject == nullptr)
6360 {
6361 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6362 return false;
6363 }
6364
6365 if (!fenceObject->isSet())
6366 {
6367 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6368 return false;
6369 }
6370
6371 return true;
6372}
6373
6374bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6375{
6376 if (!context->getExtensions().fence)
6377 {
6378 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6379 return false;
6380 }
6381
6382 if (n < 0)
6383 {
6384 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6385 return false;
6386 }
6387
6388 return true;
6389}
6390
6391bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6392{
6393 if (!context->getExtensions().fence)
6394 {
6395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6396 return false;
6397 }
6398
6399 FenceNV *fenceObject = context->getFenceNV(fence);
6400
6401 if (fenceObject == nullptr)
6402 {
6403 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6404 return false;
6405 }
6406
6407 if (!fenceObject->isSet())
6408 {
6409 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6410 return false;
6411 }
6412
6413 switch (pname)
6414 {
6415 case GL_FENCE_STATUS_NV:
6416 case GL_FENCE_CONDITION_NV:
6417 break;
6418
6419 default:
6420 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6421 return false;
6422 }
6423
6424 return true;
6425}
6426
6427bool ValidateGetGraphicsResetStatusEXT(Context *context)
6428{
6429 if (!context->getExtensions().robustness)
6430 {
6431 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6432 return false;
6433 }
6434
6435 return true;
6436}
6437
6438bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6439 GLuint shader,
6440 GLsizei bufsize,
6441 GLsizei *length,
6442 GLchar *source)
6443{
6444 if (!context->getExtensions().translatedShaderSource)
6445 {
6446 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6447 return false;
6448 }
6449
6450 if (bufsize < 0)
6451 {
6452 context->handleError(InvalidValue());
6453 return false;
6454 }
6455
6456 Shader *shaderObject = context->getShader(shader);
6457
6458 if (!shaderObject)
6459 {
6460 context->handleError(InvalidOperation());
6461 return false;
6462 }
6463
6464 return true;
6465}
6466
6467bool ValidateIsFenceNV(Context *context, GLuint fence)
6468{
6469 if (!context->getExtensions().fence)
6470 {
6471 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6472 return false;
6473 }
6474
6475 return true;
6476}
6477
Jamie Madill007530e2017-12-28 14:27:04 -05006478bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6479{
6480 if (!context->getExtensions().fence)
6481 {
6482 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6483 return false;
6484 }
6485
6486 if (condition != GL_ALL_COMPLETED_NV)
6487 {
6488 context->handleError(InvalidEnum());
6489 return false;
6490 }
6491
6492 FenceNV *fenceObject = context->getFenceNV(fence);
6493
6494 if (fenceObject == nullptr)
6495 {
6496 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6497 return false;
6498 }
6499
6500 return true;
6501}
6502
6503bool ValidateTestFenceNV(Context *context, GLuint fence)
6504{
6505 if (!context->getExtensions().fence)
6506 {
6507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6508 return false;
6509 }
6510
6511 FenceNV *fenceObject = context->getFenceNV(fence);
6512
6513 if (fenceObject == nullptr)
6514 {
6515 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6516 return false;
6517 }
6518
6519 if (fenceObject->isSet() != GL_TRUE)
6520 {
6521 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6522 return false;
6523 }
6524
6525 return true;
6526}
6527
6528bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006529 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006530 GLsizei levels,
6531 GLenum internalformat,
6532 GLsizei width,
6533 GLsizei height)
6534{
6535 if (!context->getExtensions().textureStorage)
6536 {
6537 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6538 return false;
6539 }
6540
6541 if (context->getClientMajorVersion() < 3)
6542 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006543 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006544 height);
6545 }
6546
6547 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006548 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006549 1);
6550}
6551
6552bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6553{
6554 if (!context->getExtensions().instancedArrays)
6555 {
6556 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6557 return false;
6558 }
6559
6560 if (index >= MAX_VERTEX_ATTRIBS)
6561 {
6562 context->handleError(InvalidValue());
6563 return false;
6564 }
6565
6566 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6567 {
6568 if (index == 0 && divisor != 0)
6569 {
6570 const char *errorMessage =
6571 "The current context doesn't support setting a non-zero divisor on the "
6572 "attribute with index zero. "
6573 "Please reorder the attributes in your vertex shader so that attribute zero "
6574 "can have a zero divisor.";
6575 context->handleError(InvalidOperation() << errorMessage);
6576
6577 // We also output an error message to the debugger window if tracing is active, so
6578 // that developers can see the error message.
6579 ERR() << errorMessage;
6580 return false;
6581 }
6582 }
6583
6584 return true;
6585}
6586
6587bool ValidateTexImage3DOES(Context *context,
6588 GLenum target,
6589 GLint level,
6590 GLenum internalformat,
6591 GLsizei width,
6592 GLsizei height,
6593 GLsizei depth,
6594 GLint border,
6595 GLenum format,
6596 GLenum type,
6597 const void *pixels)
6598{
6599 UNIMPLEMENTED(); // FIXME
6600 return false;
6601}
6602
6603bool ValidatePopGroupMarkerEXT(Context *context)
6604{
6605 if (!context->getExtensions().debugMarker)
6606 {
6607 // The debug marker calls should not set error state
6608 // However, it seems reasonable to set an error state if the extension is not enabled
6609 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6610 return false;
6611 }
6612
6613 return true;
6614}
6615
Jamie Madillfa920eb2018-01-04 11:45:50 -05006616bool ValidateTexStorage1DEXT(Context *context,
6617 GLenum target,
6618 GLsizei levels,
6619 GLenum internalformat,
6620 GLsizei width)
6621{
6622 UNIMPLEMENTED();
6623 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6624 return false;
6625}
6626
6627bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006628 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006629 GLsizei levels,
6630 GLenum internalformat,
6631 GLsizei width,
6632 GLsizei height,
6633 GLsizei depth)
6634{
6635 if (!context->getExtensions().textureStorage)
6636 {
6637 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6638 return false;
6639 }
6640
6641 if (context->getClientMajorVersion() < 3)
6642 {
6643 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6644 return false;
6645 }
6646
6647 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6648 depth);
6649}
6650
jchen1082af6202018-06-22 10:59:52 +08006651bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6652{
6653 if (!context->getExtensions().parallelShaderCompile)
6654 {
6655 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6656 return false;
6657 }
6658 return true;
6659}
6660
Jamie Madillc29968b2016-01-20 11:17:23 -05006661} // namespace gl