blob: 52105ede06a57b625855983eaca0f9f98fccf04f [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
Jamie Madill778bf092018-11-14 09:54:36 -05009#include "libANGLE/validationES2_autogen.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"
Jamie Madill778bf092018-11-14 09:54:36 -050028#include "libANGLE/validationES2.h"
29#include "libANGLE/validationES3_autogen.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040030
31namespace gl
32{
33
Jamie Madillc29968b2016-01-20 11:17:23 -050034namespace
35{
36
37bool IsPartialBlit(gl::Context *context,
38 const FramebufferAttachment *readBuffer,
39 const FramebufferAttachment *writeBuffer,
40 GLint srcX0,
41 GLint srcY0,
42 GLint srcX1,
43 GLint srcY1,
44 GLint dstX0,
45 GLint dstY0,
46 GLint dstX1,
47 GLint dstY1)
48{
49 const Extents &writeSize = writeBuffer->getSize();
50 const Extents &readSize = readBuffer->getSize();
51
52 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
53 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
54 {
55 return true;
56 }
57
Jamie Madilldfde6ab2016-06-09 07:07:18 -070058 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050059 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070060 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050061 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
62 scissor.height < writeSize.height;
63 }
64
65 return false;
66}
67
Sami Väisänend59ca052016-06-21 16:10:00 +030068template <typename T>
69bool ValidatePathInstances(gl::Context *context,
70 GLsizei numPaths,
71 const void *paths,
72 GLuint pathBase)
73{
74 const auto *array = static_cast<const T *>(paths);
75
76 for (GLsizei i = 0; i < numPaths; ++i)
77 {
78 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070079 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030080 {
Brandon Jonesafa75152017-07-21 13:11:29 -070081 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030082 return false;
83 }
84 }
85 return true;
86}
87
88bool ValidateInstancedPathParameters(gl::Context *context,
89 GLsizei numPaths,
90 GLenum pathNameType,
91 const void *paths,
92 GLuint pathBase,
93 GLenum transformType,
94 const GLfloat *transformValues)
95{
96 if (!context->getExtensions().pathRendering)
97 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050098 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030099 return false;
100 }
101
102 if (paths == nullptr)
103 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500104 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300105 return false;
106 }
107
108 if (numPaths < 0)
109 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500110 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300111 return false;
112 }
113
114 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
115 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700116 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300117 return false;
118 }
119
120 std::uint32_t pathNameTypeSize = 0;
121 std::uint32_t componentCount = 0;
122
123 switch (pathNameType)
124 {
125 case GL_UNSIGNED_BYTE:
126 pathNameTypeSize = sizeof(GLubyte);
127 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
128 return false;
129 break;
130
131 case GL_BYTE:
132 pathNameTypeSize = sizeof(GLbyte);
133 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
134 return false;
135 break;
136
137 case GL_UNSIGNED_SHORT:
138 pathNameTypeSize = sizeof(GLushort);
139 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
140 return false;
141 break;
142
143 case GL_SHORT:
144 pathNameTypeSize = sizeof(GLshort);
145 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
146 return false;
147 break;
148
149 case GL_UNSIGNED_INT:
150 pathNameTypeSize = sizeof(GLuint);
151 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
152 return false;
153 break;
154
155 case GL_INT:
156 pathNameTypeSize = sizeof(GLint);
157 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
158 return false;
159 break;
160
161 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500162 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300163 return false;
164 }
165
166 switch (transformType)
167 {
168 case GL_NONE:
169 componentCount = 0;
170 break;
171 case GL_TRANSLATE_X_CHROMIUM:
172 case GL_TRANSLATE_Y_CHROMIUM:
173 componentCount = 1;
174 break;
175 case GL_TRANSLATE_2D_CHROMIUM:
176 componentCount = 2;
177 break;
178 case GL_TRANSLATE_3D_CHROMIUM:
179 componentCount = 3;
180 break;
181 case GL_AFFINE_2D_CHROMIUM:
182 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
183 componentCount = 6;
184 break;
185 case GL_AFFINE_3D_CHROMIUM:
186 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
187 componentCount = 12;
188 break;
189 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500190 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300191 return false;
192 }
193 if (componentCount != 0 && transformValues == nullptr)
194 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500195 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300196 return false;
197 }
198
199 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
200 checkedSize += (numPaths * pathNameTypeSize);
201 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
202 if (!checkedSize.IsValid())
203 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700204 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300205 return false;
206 }
207
208 return true;
209}
210
Geoff Lang4f0e0032017-05-01 16:04:35 -0400211bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700212{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400213 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400214 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700215 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400216 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700217 case GL_ALPHA:
218 case GL_LUMINANCE:
219 case GL_LUMINANCE_ALPHA:
220 case GL_RGB:
221 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400222 case GL_RGB8:
223 case GL_RGBA8:
224 case GL_BGRA_EXT:
225 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700226 return true;
227
Geoff Lang4f0e0032017-05-01 16:04:35 -0400228 default:
229 return false;
230 }
231}
Geoff Lang97073d12016-04-20 10:42:34 -0700232
Geoff Lang4f0e0032017-05-01 16:04:35 -0400233bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
234{
235 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
236}
237
Geoff Lang4f0e0032017-05-01 16:04:35 -0400238bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
239{
240 // Table 1.0 from the CHROMIUM_copy_texture spec
241 switch (internalFormat)
242 {
243 case GL_RGB:
244 case GL_RGBA:
245 case GL_RGB8:
246 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700247 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400248 case GL_BGRA8_EXT:
249 case GL_SRGB_EXT:
250 case GL_SRGB_ALPHA_EXT:
251 case GL_R8:
252 case GL_R8UI:
253 case GL_RG8:
254 case GL_RG8UI:
255 case GL_SRGB8:
256 case GL_RGB565:
257 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400258 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400259 case GL_SRGB8_ALPHA8:
260 case GL_RGB5_A1:
261 case GL_RGBA4:
262 case GL_RGBA8UI:
263 case GL_RGB9_E5:
264 case GL_R16F:
265 case GL_R32F:
266 case GL_RG16F:
267 case GL_RG32F:
268 case GL_RGB16F:
269 case GL_RGB32F:
270 case GL_RGBA16F:
271 case GL_RGBA32F:
272 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700273 case GL_LUMINANCE:
274 case GL_LUMINANCE_ALPHA:
275 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400276 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700277
278 default:
279 return false;
280 }
281}
282
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400283bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
284{
285 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
286}
287
Geoff Lang97073d12016-04-20 10:42:34 -0700288bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
289{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400290 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700291 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700292 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400293 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700294 }
295
Geoff Langc0094ec2017-08-16 14:16:24 -0400296 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
297 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700298 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Langc0094ec2017-08-16 14:16:24 -0400299 return false;
300 }
301
Geoff Lang4f0e0032017-05-01 16:04:35 -0400302 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
303 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700304 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400306 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700307 }
308
309 return true;
310}
311
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800312bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700313{
314 switch (target)
315 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800316 case TextureTarget::_2D:
317 case TextureTarget::CubeMapNegativeX:
318 case TextureTarget::CubeMapNegativeY:
319 case TextureTarget::CubeMapNegativeZ:
320 case TextureTarget::CubeMapPositiveX:
321 case TextureTarget::CubeMapPositiveY:
322 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400323 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700324
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800325 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400326 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700327
328 default:
329 return false;
330 }
331}
332
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800333bool IsValidCopyTextureDestinationTarget(Context *context,
334 TextureType textureType,
335 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400336{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800337 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400338}
339
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700343 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400345 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800346 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400347 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400348
349 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
350 // supported
351
352 default:
353 return false;
354 }
355}
356
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800359 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400360 {
361 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700362 }
363
Geoff Lang4f0e0032017-05-01 16:04:35 -0400364 if (level > 0 && context->getClientVersion() < ES_3_0)
365 {
366 return false;
367 }
Geoff Lang97073d12016-04-20 10:42:34 -0700368
Geoff Lang4f0e0032017-05-01 16:04:35 -0400369 return true;
370}
371
372bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800373 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400374 GLint level,
375 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800376 GLsizei height,
377 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400378{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800379 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400380 {
381 return false;
382 }
383
Brandon Jones28783792018-03-05 09:37:32 -0800384 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
385 {
386 return false;
387 }
388
Geoff Lang4f0e0032017-05-01 16:04:35 -0400389 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800390 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400391 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800392 case TextureType::_2D:
393 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
394 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
395 case TextureType::Rectangle:
396 ASSERT(level == 0);
397 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
398 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400399
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800400 case TextureType::CubeMap:
401 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
402 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
403 default:
404 return true;
405 }
Geoff Lang97073d12016-04-20 10:42:34 -0700406}
407
Jamie Madillc1d770e2017-04-13 17:31:24 -0400408bool IsValidStencilFunc(GLenum func)
409{
410 switch (func)
411 {
412 case GL_NEVER:
413 case GL_ALWAYS:
414 case GL_LESS:
415 case GL_LEQUAL:
416 case GL_EQUAL:
417 case GL_GEQUAL:
418 case GL_GREATER:
419 case GL_NOTEQUAL:
420 return true;
421
422 default:
423 return false;
424 }
425}
426
427bool IsValidStencilFace(GLenum face)
428{
429 switch (face)
430 {
431 case GL_FRONT:
432 case GL_BACK:
433 case GL_FRONT_AND_BACK:
434 return true;
435
436 default:
437 return false;
438 }
439}
440
441bool IsValidStencilOp(GLenum op)
442{
443 switch (op)
444 {
445 case GL_ZERO:
446 case GL_KEEP:
447 case GL_REPLACE:
448 case GL_INCR:
449 case GL_DECR:
450 case GL_INVERT:
451 case GL_INCR_WRAP:
452 case GL_DECR_WRAP:
453 return true;
454
455 default:
456 return false;
457 }
458}
459
Jamie Madill5b772312018-03-08 20:28:32 -0500460bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800461 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400462 GLint level,
463 GLenum internalformat,
464 bool isSubImage,
465 GLint xoffset,
466 GLint yoffset,
467 GLint x,
468 GLint y,
469 GLsizei width,
470 GLsizei height,
471 GLint border)
472{
473 if (!ValidTexture2DDestinationTarget(context, target))
474 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700475 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400476 return false;
477 }
478
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800479 TextureType texType = TextureTargetToType(target);
480 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500482 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400483 return false;
484 }
485
486 Format textureFormat = Format::Invalid();
487 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
488 xoffset, yoffset, 0, x, y, width, height, border,
489 &textureFormat))
490 {
491 return false;
492 }
493
494 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
495 GLenum colorbufferFormat =
496 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
497 const auto &formatInfo = *textureFormat.info;
498
499 // [OpenGL ES 2.0.24] table 3.9
500 if (isSubImage)
501 {
502 switch (formatInfo.format)
503 {
504 case GL_ALPHA:
505 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400506 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
507 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400508 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700509 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400510 return false;
511 }
512 break;
513 case GL_LUMINANCE:
514 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
515 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
516 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400517 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
518 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400519 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700520 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400521 return false;
522 }
523 break;
524 case GL_RED_EXT:
525 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
526 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
527 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
528 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
529 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400530 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
531 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400532 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700533 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400534 return false;
535 }
536 break;
537 case GL_RG_EXT:
538 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
539 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
540 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
541 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400542 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
543 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400544 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700545 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400546 return false;
547 }
548 break;
549 case GL_RGB:
550 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
551 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
552 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400553 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
554 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700556 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400557 return false;
558 }
559 break;
560 case GL_LUMINANCE_ALPHA:
561 case GL_RGBA:
562 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400563 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
564 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400565 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700566 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400567 return false;
568 }
569 break;
570 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
571 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
572 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
573 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
574 case GL_ETC1_RGB8_OES:
575 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
576 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
578 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
579 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +0300580 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
581 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
582 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
583 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Brandon Jones6cad5662017-06-14 13:25:13 -0700584 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400585 return false;
586 case GL_DEPTH_COMPONENT:
587 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700588 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400589 return false;
590 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 }
594
595 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
596 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700597 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400598 return false;
599 }
600 }
601 else
602 {
603 switch (internalformat)
604 {
605 case GL_ALPHA:
606 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
607 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
608 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
609 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700610 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400611 return false;
612 }
613 break;
614 case GL_LUMINANCE:
615 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
616 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
617 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
618 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
619 colorbufferFormat != GL_BGR5_A1_ANGLEX)
620 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700621 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400622 return false;
623 }
624 break;
625 case GL_RED_EXT:
626 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
627 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
628 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
629 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
630 colorbufferFormat != GL_BGR5_A1_ANGLEX)
631 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700632 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400633 return false;
634 }
635 break;
636 case GL_RG_EXT:
637 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
638 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
639 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
640 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
641 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700642 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400643 return false;
644 }
645 break;
646 case GL_RGB:
647 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
648 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
649 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
650 colorbufferFormat != GL_BGR5_A1_ANGLEX)
651 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700652 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400653 return false;
654 }
655 break;
656 case GL_LUMINANCE_ALPHA:
657 case GL_RGBA:
658 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
659 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
660 colorbufferFormat != GL_BGR5_A1_ANGLEX)
661 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700662 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400663 return false;
664 }
665 break;
666 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
667 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
668 if (context->getExtensions().textureCompressionDXT1)
669 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700670 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400671 return false;
672 }
673 else
674 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700675 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400676 return false;
677 }
678 break;
679 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
680 if (context->getExtensions().textureCompressionDXT3)
681 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700682 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400683 return false;
684 }
685 else
686 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700687 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400688 return false;
689 }
690 break;
691 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
692 if (context->getExtensions().textureCompressionDXT5)
693 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700694 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400695 return false;
696 }
697 else
698 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700699 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400700 return false;
701 }
702 break;
703 case GL_ETC1_RGB8_OES:
704 if (context->getExtensions().compressedETC1RGB8Texture)
705 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500706 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400707 return false;
708 }
709 else
710 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500711 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400712 return false;
713 }
714 break;
715 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
716 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
717 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
718 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
719 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
720 if (context->getExtensions().lossyETCDecode)
721 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500722 context->handleError(InvalidOperation()
723 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400724 return false;
725 }
726 else
727 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500728 context->handleError(InvalidEnum()
729 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400730 return false;
731 }
732 break;
733 case GL_DEPTH_COMPONENT:
734 case GL_DEPTH_COMPONENT16:
735 case GL_DEPTH_COMPONENT32_OES:
736 case GL_DEPTH_STENCIL_OES:
737 case GL_DEPTH24_STENCIL8_OES:
738 if (context->getExtensions().depthTextures)
739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500740 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400741 return false;
742 }
743 else
744 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500745 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400746 return false;
747 }
748 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500749 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400750 return false;
751 }
752 }
753
754 // If width or height is zero, it is a no-op. Return false without setting an error.
755 return (width > 0 && height > 0);
756}
757
758bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
759{
760 switch (cap)
761 {
762 // EXT_multisample_compatibility
763 case GL_MULTISAMPLE_EXT:
764 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
765 return context->getExtensions().multisampleCompatibility;
766
767 case GL_CULL_FACE:
768 case GL_POLYGON_OFFSET_FILL:
769 case GL_SAMPLE_ALPHA_TO_COVERAGE:
770 case GL_SAMPLE_COVERAGE:
771 case GL_SCISSOR_TEST:
772 case GL_STENCIL_TEST:
773 case GL_DEPTH_TEST:
774 case GL_BLEND:
775 case GL_DITHER:
776 return true;
777
778 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
779 case GL_RASTERIZER_DISCARD:
780 return (context->getClientMajorVersion() >= 3);
781
782 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
783 case GL_DEBUG_OUTPUT:
784 return context->getExtensions().debug;
785
786 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
787 return queryOnly && context->getExtensions().bindGeneratesResource;
788
789 case GL_CLIENT_ARRAYS_ANGLE:
790 return queryOnly && context->getExtensions().clientArrays;
791
792 case GL_FRAMEBUFFER_SRGB_EXT:
793 return context->getExtensions().sRGBWriteControl;
794
795 case GL_SAMPLE_MASK:
796 return context->getClientVersion() >= Version(3, 1);
797
Geoff Langb433e872017-10-05 14:01:47 -0400798 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400799 return queryOnly && context->getExtensions().robustResourceInitialization;
800
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700801 // GLES1 emulation: GLES1-specific caps
802 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700803 case GL_VERTEX_ARRAY:
804 case GL_NORMAL_ARRAY:
805 case GL_COLOR_ARRAY:
806 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700807 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700808 case GL_LIGHTING:
809 case GL_LIGHT0:
810 case GL_LIGHT1:
811 case GL_LIGHT2:
812 case GL_LIGHT3:
813 case GL_LIGHT4:
814 case GL_LIGHT5:
815 case GL_LIGHT6:
816 case GL_LIGHT7:
817 case GL_NORMALIZE:
818 case GL_RESCALE_NORMAL:
819 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700820 case GL_CLIP_PLANE0:
821 case GL_CLIP_PLANE1:
822 case GL_CLIP_PLANE2:
823 case GL_CLIP_PLANE3:
824 case GL_CLIP_PLANE4:
825 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700826 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700827 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700828 case GL_LINE_SMOOTH:
829 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700830 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700831 case GL_POINT_SIZE_ARRAY_OES:
832 return context->getClientVersion() < Version(2, 0) &&
833 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700834 case GL_TEXTURE_CUBE_MAP:
835 return context->getClientVersion() < Version(2, 0) &&
836 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700837 case GL_POINT_SPRITE_OES:
838 return context->getClientVersion() < Version(2, 0) &&
839 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400840 default:
841 return false;
842 }
843}
844
Geoff Langfc32e8b2017-05-31 14:16:59 -0400845// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
846// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400847bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400848{
849 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400850 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
851 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400852 {
853 return true;
854 }
855
856 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
857 if (c >= 9 && c <= 13)
858 {
859 return true;
860 }
861
862 return false;
863}
864
Geoff Langcab92ee2017-07-19 17:32:07 -0400865bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400866{
Geoff Langa71a98e2017-06-19 15:15:00 -0400867 for (size_t i = 0; i < len; i++)
868 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400869 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400870 {
871 return false;
872 }
873 }
874
875 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400876}
877
Geoff Langcab92ee2017-07-19 17:32:07 -0400878bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
879{
880 enum class ParseState
881 {
882 // Have not seen an ASCII non-whitespace character yet on
883 // this line. Possible that we might see a preprocessor
884 // directive.
885 BEGINING_OF_LINE,
886
887 // Have seen at least one ASCII non-whitespace character
888 // on this line.
889 MIDDLE_OF_LINE,
890
891 // Handling a preprocessor directive. Passes through all
892 // characters up to the end of the line. Disables comment
893 // processing.
894 IN_PREPROCESSOR_DIRECTIVE,
895
896 // Handling a single-line comment. The comment text is
897 // replaced with a single space.
898 IN_SINGLE_LINE_COMMENT,
899
900 // Handling a multi-line comment. Newlines are passed
901 // through to preserve line numbers.
902 IN_MULTI_LINE_COMMENT
903 };
904
905 ParseState state = ParseState::BEGINING_OF_LINE;
906 size_t pos = 0;
907
908 while (pos < len)
909 {
910 char c = str[pos];
911 char next = pos + 1 < len ? str[pos + 1] : 0;
912
913 // Check for newlines
914 if (c == '\n' || c == '\r')
915 {
916 if (state != ParseState::IN_MULTI_LINE_COMMENT)
917 {
918 state = ParseState::BEGINING_OF_LINE;
919 }
920
921 pos++;
922 continue;
923 }
924
925 switch (state)
926 {
927 case ParseState::BEGINING_OF_LINE:
928 if (c == ' ')
929 {
930 // Maintain the BEGINING_OF_LINE state until a non-space is seen
931 pos++;
932 }
933 else if (c == '#')
934 {
935 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
936 pos++;
937 }
938 else
939 {
940 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
941 state = ParseState::MIDDLE_OF_LINE;
942 }
943 break;
944
945 case ParseState::MIDDLE_OF_LINE:
946 if (c == '/' && next == '/')
947 {
948 state = ParseState::IN_SINGLE_LINE_COMMENT;
949 pos++;
950 }
951 else if (c == '/' && next == '*')
952 {
953 state = ParseState::IN_MULTI_LINE_COMMENT;
954 pos++;
955 }
956 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
957 {
958 // Skip line continuation characters
959 }
960 else if (!IsValidESSLCharacter(c))
961 {
962 return false;
963 }
964 pos++;
965 break;
966
967 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700968 // Line-continuation characters may not be permitted.
969 // Otherwise, just pass it through. Do not parse comments in this state.
970 if (!lineContinuationAllowed && c == '\\')
971 {
972 return false;
973 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400974 pos++;
975 break;
976
977 case ParseState::IN_SINGLE_LINE_COMMENT:
978 // Line-continuation characters are processed before comment processing.
979 // Advance string if a new line character is immediately behind
980 // line-continuation character.
981 if (c == '\\' && (next == '\n' || next == '\r'))
982 {
983 pos++;
984 }
985 pos++;
986 break;
987
988 case ParseState::IN_MULTI_LINE_COMMENT:
989 if (c == '*' && next == '/')
990 {
991 state = ParseState::MIDDLE_OF_LINE;
992 pos++;
993 }
994 pos++;
995 break;
996 }
997 }
998
999 return true;
1000}
1001
Jamie Madill5b772312018-03-08 20:28:32 -05001002bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001003{
1004 ASSERT(context->isWebGL());
1005
1006 // WebGL 1.0 [Section 6.16] GLSL Constructs
1007 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1008 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1009 {
1010 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1011 return false;
1012 }
1013
1014 return true;
1015}
1016
Jamie Madill5b772312018-03-08 20:28:32 -05001017bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001018{
1019 ASSERT(context->isWebGL());
1020
1021 if (context->isWebGL1() && length > 256)
1022 {
1023 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1024 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1025 // locations.
1026 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1027
1028 return false;
1029 }
1030 else if (length > 1024)
1031 {
1032 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1033 // uniform and attribute locations.
1034 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1035 return false;
1036 }
1037
1038 return true;
1039}
1040
Jamie Madill007530e2017-12-28 14:27:04 -05001041bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1042{
1043 if (!context->getExtensions().pathRendering)
1044 {
1045 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1046 return false;
1047 }
1048
1049 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1050 {
1051 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1052 return false;
1053 }
1054 return true;
1055}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001056
1057bool ValidBlendFunc(const Context *context, GLenum val)
1058{
1059 const gl::Extensions &ext = context->getExtensions();
1060
1061 // these are always valid for src and dst.
1062 switch (val)
1063 {
1064 case GL_ZERO:
1065 case GL_ONE:
1066 case GL_SRC_COLOR:
1067 case GL_ONE_MINUS_SRC_COLOR:
1068 case GL_DST_COLOR:
1069 case GL_ONE_MINUS_DST_COLOR:
1070 case GL_SRC_ALPHA:
1071 case GL_ONE_MINUS_SRC_ALPHA:
1072 case GL_DST_ALPHA:
1073 case GL_ONE_MINUS_DST_ALPHA:
1074 case GL_CONSTANT_COLOR:
1075 case GL_ONE_MINUS_CONSTANT_COLOR:
1076 case GL_CONSTANT_ALPHA:
1077 case GL_ONE_MINUS_CONSTANT_ALPHA:
1078 return true;
1079
1080 // EXT_blend_func_extended.
1081 case GL_SRC1_COLOR_EXT:
1082 case GL_SRC1_ALPHA_EXT:
1083 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1084 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1085 case GL_SRC_ALPHA_SATURATE_EXT:
1086 return ext.blendFuncExtended;
1087
1088 default:
1089 return false;
1090 }
1091}
1092
1093bool ValidSrcBlendFunc(const Context *context, GLenum val)
1094{
1095 if (ValidBlendFunc(context, val))
1096 return true;
1097
1098 if (val == GL_SRC_ALPHA_SATURATE)
1099 return true;
1100
1101 return false;
1102}
1103
1104bool ValidDstBlendFunc(const Context *context, GLenum val)
1105{
1106 if (ValidBlendFunc(context, val))
1107 return true;
1108
1109 if (val == GL_SRC_ALPHA_SATURATE)
1110 {
1111 if (context->getClientMajorVersion() >= 3)
1112 return true;
1113 }
1114
1115 return false;
1116}
1117
Jamie Madillac66f982018-10-09 18:30:01 -04001118void RecordBindTextureTypeError(Context *context, TextureType target)
1119{
1120 ASSERT(!context->getStateCache().isValidBindTextureType(target));
1121
1122 switch (target)
1123 {
1124 case TextureType::Rectangle:
1125 ASSERT(!context->getExtensions().textureRectangle);
1126 context->handleError(InvalidEnum()
1127 << "Context does not support GL_ANGLE_texture_rectangle");
1128 break;
1129
1130 case TextureType::_3D:
1131 case TextureType::_2DArray:
1132 ASSERT(context->getClientMajorVersion() < 3);
1133 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
1134 break;
1135
1136 case TextureType::_2DMultisample:
Yizhou Jiang7818a852018-09-06 15:02:04 +08001137 ASSERT(context->getClientVersion() < Version(3, 1) &&
1138 !context->getExtensions().textureMultisample);
1139 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleTextureExtensionOrES31Required);
Jamie Madillac66f982018-10-09 18:30:01 -04001140 break;
1141
1142 case TextureType::_2DMultisampleArray:
1143 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
1144 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
1145 break;
1146
1147 case TextureType::External:
1148 ASSERT(!context->getExtensions().eglImageExternal &&
1149 !context->getExtensions().eglStreamConsumerExternal);
1150 context->handleError(InvalidEnum() << "External texture extension not enabled");
1151 break;
1152
1153 default:
1154 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
1155 }
1156}
Jamie Madillc29968b2016-01-20 11:17:23 -05001157} // anonymous namespace
1158
Geoff Langff5b2d52016-09-07 11:32:23 -04001159bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001160 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001161 GLint level,
1162 GLenum internalformat,
1163 bool isCompressed,
1164 bool isSubImage,
1165 GLint xoffset,
1166 GLint yoffset,
1167 GLsizei width,
1168 GLsizei height,
1169 GLint border,
1170 GLenum format,
1171 GLenum type,
1172 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001173 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001174{
Jamie Madill6f38f822014-06-06 17:12:20 -04001175 if (!ValidTexture2DDestinationTarget(context, target))
1176 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001177 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001178 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001179 }
1180
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001181 TextureType texType = TextureTargetToType(target);
1182 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001183 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001184 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001185 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001186 }
1187
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001188 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001189 {
1190 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1191 return false;
1192 }
1193
1194 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001195 std::numeric_limits<GLsizei>::max() - yoffset < height)
1196 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001197 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001198 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001199 }
1200
Geoff Lang6e898aa2017-06-02 11:17:26 -04001201 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1202 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1203 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1204 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1205 // case.
1206 bool nonEqualFormatsAllowed =
1207 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1208 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1209
1210 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001211 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001212 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001213 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001214 }
1215
Geoff Langaae65a42014-05-26 12:43:44 -04001216 const gl::Caps &caps = context->getCaps();
1217
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001218 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001219 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001220 case TextureType::_2D:
1221 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1222 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1223 {
1224 context->handleError(InvalidValue());
1225 return false;
1226 }
1227 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001228
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001229 case TextureType::Rectangle:
1230 ASSERT(level == 0);
1231 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1232 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1233 {
1234 context->handleError(InvalidValue());
1235 return false;
1236 }
1237 if (isCompressed)
1238 {
1239 context->handleError(InvalidEnum()
1240 << "Rectangle texture cannot have a compressed format.");
1241 return false;
1242 }
1243 break;
1244
1245 case TextureType::CubeMap:
1246 if (!isSubImage && width != height)
1247 {
1248 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1249 return false;
1250 }
1251
1252 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1253 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1254 {
1255 context->handleError(InvalidValue());
1256 return false;
1257 }
1258 break;
1259
1260 default:
1261 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001262 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001263 }
1264
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001265 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001266 if (!texture)
1267 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001268 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001269 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001270 }
1271
Geoff Langa9be0dc2014-12-17 12:34:40 -05001272 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001273 {
Geoff Langca271392017-04-05 12:30:00 -04001274 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1275 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001276 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001277 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001278 return false;
1279 }
1280
Geoff Langa9be0dc2014-12-17 12:34:40 -05001281 if (format != GL_NONE)
1282 {
Geoff Langca271392017-04-05 12:30:00 -04001283 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1284 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001285 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001286 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001287 return false;
1288 }
1289 }
1290
1291 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1292 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1293 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001294 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001295 return false;
1296 }
Geoff Langfb052642017-10-24 13:42:09 -04001297
1298 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001299 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001300 {
1301 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1302 return false;
1303 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001304 }
1305 else
1306 {
Geoff Lang69cce582015-09-17 13:20:36 -04001307 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001308 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001309 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001310 return false;
1311 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001312 }
1313
1314 // Verify zero border
1315 if (border != 0)
1316 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001317 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001318 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001319 }
1320
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001321 if (isCompressed)
1322 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001323 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001324 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1325 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001326
1327 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1328
1329 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001330 {
Geoff Lange88e4542018-05-03 15:05:57 -04001331 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1332 return false;
1333 }
1334
1335 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1336 context->getExtensions()))
1337 {
1338 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1339 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001340 }
Geoff Lang966c9402017-04-18 12:38:27 -04001341
1342 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001343 {
Geoff Lange88e4542018-05-03 15:05:57 -04001344 // From the OES_compressed_ETC1_RGB8_texture spec:
1345 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1346 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1347 // ETC1_RGB8_OES.
1348 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1349 {
1350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1351 return false;
1352 }
1353
Geoff Lang966c9402017-04-18 12:38:27 -04001354 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1355 height, texture->getWidth(target, level),
1356 texture->getHeight(target, level)))
1357 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001358 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001359 return false;
1360 }
1361
1362 if (format != actualInternalFormat)
1363 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001365 return false;
1366 }
1367 }
1368 else
1369 {
1370 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1371 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001372 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001373 return false;
1374 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001375 }
1376 }
1377 else
1378 {
1379 // validate <type> by itself (used as secondary key below)
1380 switch (type)
1381 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001382 case GL_UNSIGNED_BYTE:
1383 case GL_UNSIGNED_SHORT_5_6_5:
1384 case GL_UNSIGNED_SHORT_4_4_4_4:
1385 case GL_UNSIGNED_SHORT_5_5_5_1:
1386 case GL_UNSIGNED_SHORT:
1387 case GL_UNSIGNED_INT:
1388 case GL_UNSIGNED_INT_24_8_OES:
1389 case GL_HALF_FLOAT_OES:
1390 case GL_FLOAT:
1391 break;
1392 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001393 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001394 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001395 }
1396
1397 // validate <format> + <type> combinations
1398 // - invalid <format> -> sets INVALID_ENUM
1399 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1400 switch (format)
1401 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001402 case GL_ALPHA:
1403 case GL_LUMINANCE:
1404 case GL_LUMINANCE_ALPHA:
1405 switch (type)
1406 {
1407 case GL_UNSIGNED_BYTE:
1408 case GL_FLOAT:
1409 case GL_HALF_FLOAT_OES:
1410 break;
1411 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001412 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001413 return false;
1414 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001415 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001416 case GL_RED:
1417 case GL_RG:
1418 if (!context->getExtensions().textureRG)
1419 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001420 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001421 return false;
1422 }
1423 switch (type)
1424 {
1425 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001426 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001427 case GL_FLOAT:
1428 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001429 if (!context->getExtensions().textureFloat)
1430 {
1431 context->handleError(InvalidEnum());
1432 return false;
1433 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001434 break;
1435 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001436 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001437 return false;
1438 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001439 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001440 case GL_RGB:
1441 switch (type)
1442 {
1443 case GL_UNSIGNED_BYTE:
1444 case GL_UNSIGNED_SHORT_5_6_5:
1445 case GL_FLOAT:
1446 case GL_HALF_FLOAT_OES:
1447 break;
1448 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001449 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001450 return false;
1451 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001452 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001453 case GL_RGBA:
1454 switch (type)
1455 {
1456 case GL_UNSIGNED_BYTE:
1457 case GL_UNSIGNED_SHORT_4_4_4_4:
1458 case GL_UNSIGNED_SHORT_5_5_5_1:
1459 case GL_FLOAT:
1460 case GL_HALF_FLOAT_OES:
1461 break;
1462 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001463 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001464 return false;
1465 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001466 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001468 if (!context->getExtensions().textureFormatBGRA8888)
1469 {
1470 context->handleError(InvalidEnum());
1471 return false;
1472 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001473 switch (type)
1474 {
1475 case GL_UNSIGNED_BYTE:
1476 break;
1477 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001478 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001479 return false;
1480 }
1481 break;
1482 case GL_SRGB_EXT:
1483 case GL_SRGB_ALPHA_EXT:
1484 if (!context->getExtensions().sRGB)
1485 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001486 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 return false;
1488 }
1489 switch (type)
1490 {
1491 case GL_UNSIGNED_BYTE:
1492 break;
1493 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001494 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001495 return false;
1496 }
1497 break;
1498 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1499 // handled below
1500 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1501 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1502 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1503 break;
1504 case GL_DEPTH_COMPONENT:
1505 switch (type)
1506 {
1507 case GL_UNSIGNED_SHORT:
1508 case GL_UNSIGNED_INT:
1509 break;
1510 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001512 return false;
1513 }
1514 break;
1515 case GL_DEPTH_STENCIL_OES:
1516 switch (type)
1517 {
1518 case GL_UNSIGNED_INT_24_8_OES:
1519 break;
1520 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001521 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001522 return false;
1523 }
1524 break;
1525 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001526 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001527 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001528 }
1529
1530 switch (format)
1531 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001532 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1533 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1534 if (context->getExtensions().textureCompressionDXT1)
1535 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001536 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001537 return false;
1538 }
1539 else
1540 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001541 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001542 return false;
1543 }
1544 break;
1545 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1546 if (context->getExtensions().textureCompressionDXT3)
1547 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001548 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001549 return false;
1550 }
1551 else
1552 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001553 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001554 return false;
1555 }
1556 break;
1557 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1558 if (context->getExtensions().textureCompressionDXT5)
1559 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001560 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001561 return false;
1562 }
1563 else
1564 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001565 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001566 return false;
1567 }
1568 break;
1569 case GL_ETC1_RGB8_OES:
1570 if (context->getExtensions().compressedETC1RGB8Texture)
1571 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001572 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001573 return false;
1574 }
1575 else
1576 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001577 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001578 return false;
1579 }
1580 break;
1581 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001582 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1583 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1584 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1585 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001586 if (context->getExtensions().lossyETCDecode)
1587 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001588 context->handleError(InvalidOperation()
1589 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001590 return false;
1591 }
1592 else
1593 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001594 context->handleError(InvalidEnum()
1595 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001596 return false;
1597 }
1598 break;
1599 case GL_DEPTH_COMPONENT:
1600 case GL_DEPTH_STENCIL_OES:
1601 if (!context->getExtensions().depthTextures)
1602 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001603 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001604 return false;
1605 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001606 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001607 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001608 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001609 return false;
1610 }
1611 // OES_depth_texture supports loading depth data and multiple levels,
1612 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001613 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001614 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1616 return false;
1617 }
1618 if (level != 0)
1619 {
1620 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001621 return false;
1622 }
1623 break;
1624 default:
1625 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001626 }
1627
Geoff Lang6e898aa2017-06-02 11:17:26 -04001628 if (!isSubImage)
1629 {
1630 switch (internalformat)
1631 {
1632 case GL_RGBA32F:
1633 if (!context->getExtensions().colorBufferFloatRGBA)
1634 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001635 context->handleError(InvalidValue()
1636 << "Sized GL_RGBA32F internal format requires "
1637 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001638 return false;
1639 }
1640 if (type != GL_FLOAT)
1641 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001642 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001643 return false;
1644 }
1645 if (format != GL_RGBA)
1646 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001647 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001648 return false;
1649 }
1650 break;
1651
1652 case GL_RGB32F:
1653 if (!context->getExtensions().colorBufferFloatRGB)
1654 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001655 context->handleError(InvalidValue()
1656 << "Sized GL_RGB32F internal format requires "
1657 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001658 return false;
1659 }
1660 if (type != GL_FLOAT)
1661 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001662 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001663 return false;
1664 }
1665 if (format != GL_RGB)
1666 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001667 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001668 return false;
1669 }
1670 break;
1671
1672 default:
1673 break;
1674 }
1675 }
1676
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001677 if (type == GL_FLOAT)
1678 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001679 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001680 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001681 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001682 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001683 }
1684 }
1685 else if (type == GL_HALF_FLOAT_OES)
1686 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001687 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001688 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001689 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001690 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001691 }
1692 }
1693 }
1694
Geoff Langdbcced82017-06-06 15:55:54 -04001695 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001696 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001697 imageSize))
1698 {
1699 return false;
1700 }
1701
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001702 return true;
1703}
1704
He Yunchaoced53ae2016-11-29 15:00:51 +08001705bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001706 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001707 GLsizei levels,
1708 GLenum internalformat,
1709 GLsizei width,
1710 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001711{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001712 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1713 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001714 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001715 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001716 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001717 }
1718
1719 if (width < 1 || height < 1 || levels < 1)
1720 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001721 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001722 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001723 }
1724
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001725 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001726 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001727 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001728 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001729 }
1730
1731 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001733 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001734 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001735 }
1736
Geoff Langca271392017-04-05 12:30:00 -04001737 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001738 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001740 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001741 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001742 }
1743
Geoff Langaae65a42014-05-26 12:43:44 -04001744 const gl::Caps &caps = context->getCaps();
1745
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001746 switch (target)
1747 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001748 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001749 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1750 static_cast<GLuint>(height) > caps.max2DTextureSize)
1751 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001752 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001753 return false;
1754 }
1755 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001756 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001757 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1758 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1759 {
1760 context->handleError(InvalidValue());
1761 return false;
1762 }
1763 if (formatInfo.compressed)
1764 {
1765 context->handleError(InvalidEnum()
1766 << "Rectangle texture cannot have a compressed format.");
1767 return false;
1768 }
1769 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001770 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001771 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1772 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1773 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001774 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001775 return false;
1776 }
1777 break;
1778 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001779 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001780 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001781 }
1782
Geoff Langc0b9ef42014-07-02 10:02:37 -04001783 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001784 {
1785 if (!gl::isPow2(width) || !gl::isPow2(height))
1786 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001787 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001788 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001789 }
1790 }
1791
1792 switch (internalformat)
1793 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001794 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1795 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1796 if (!context->getExtensions().textureCompressionDXT1)
1797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001798 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001799 return false;
1800 }
1801 break;
1802 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1803 if (!context->getExtensions().textureCompressionDXT3)
1804 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001805 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001806 return false;
1807 }
1808 break;
1809 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1810 if (!context->getExtensions().textureCompressionDXT5)
1811 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001812 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001813 return false;
1814 }
1815 break;
1816 case GL_ETC1_RGB8_OES:
1817 if (!context->getExtensions().compressedETC1RGB8Texture)
1818 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001819 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001820 return false;
1821 }
1822 break;
1823 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001824 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1825 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1826 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1827 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001828 if (!context->getExtensions().lossyETCDecode)
1829 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001830 context->handleError(InvalidEnum()
1831 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001832 return false;
1833 }
1834 break;
1835 case GL_RGBA32F_EXT:
1836 case GL_RGB32F_EXT:
1837 case GL_ALPHA32F_EXT:
1838 case GL_LUMINANCE32F_EXT:
1839 case GL_LUMINANCE_ALPHA32F_EXT:
1840 if (!context->getExtensions().textureFloat)
1841 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001842 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001843 return false;
1844 }
1845 break;
1846 case GL_RGBA16F_EXT:
1847 case GL_RGB16F_EXT:
1848 case GL_ALPHA16F_EXT:
1849 case GL_LUMINANCE16F_EXT:
1850 case GL_LUMINANCE_ALPHA16F_EXT:
1851 if (!context->getExtensions().textureHalfFloat)
1852 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001853 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001854 return false;
1855 }
1856 break;
1857 case GL_R8_EXT:
1858 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001859 if (!context->getExtensions().textureRG)
1860 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001861 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001862 return false;
1863 }
1864 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001865 case GL_R16F_EXT:
1866 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001867 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001869 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001870 return false;
1871 }
1872 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001873 case GL_R32F_EXT:
1874 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001875 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001876 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001877 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001878 return false;
1879 }
1880 break;
1881 case GL_DEPTH_COMPONENT16:
1882 case GL_DEPTH_COMPONENT32_OES:
1883 case GL_DEPTH24_STENCIL8_OES:
1884 if (!context->getExtensions().depthTextures)
1885 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001886 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001887 return false;
1888 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001889 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001890 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001891 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001892 return false;
1893 }
1894 // ANGLE_depth_texture only supports 1-level textures
1895 if (levels != 1)
1896 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001897 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001898 return false;
1899 }
1900 break;
1901 default:
1902 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001903 }
1904
Geoff Lang691e58c2014-12-19 17:03:25 -05001905 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001906 if (!texture || texture->id() == 0)
1907 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001908 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001909 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001910 }
1911
Geoff Lang69cce582015-09-17 13:20:36 -04001912 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001913 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001914 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001915 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001916 }
1917
1918 return true;
1919}
1920
He Yunchaoced53ae2016-11-29 15:00:51 +08001921bool ValidateDiscardFramebufferEXT(Context *context,
1922 GLenum target,
1923 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001924 const GLenum *attachments)
1925{
Jamie Madillc29968b2016-01-20 11:17:23 -05001926 if (!context->getExtensions().discardFramebuffer)
1927 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001928 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001929 return false;
1930 }
1931
Austin Kinross08332632015-05-05 13:35:47 -07001932 bool defaultFramebuffer = false;
1933
1934 switch (target)
1935 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001936 case GL_FRAMEBUFFER:
1937 defaultFramebuffer =
1938 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1939 break;
1940 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001941 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001942 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001943 }
1944
He Yunchaoced53ae2016-11-29 15:00:51 +08001945 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1946 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001947}
1948
Austin Kinrossbc781f32015-10-26 09:27:38 -07001949bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1950{
1951 if (!context->getExtensions().vertexArrayObject)
1952 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001953 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001954 return false;
1955 }
1956
1957 return ValidateBindVertexArrayBase(context, array);
1958}
1959
Jamie Madilld7576732017-08-26 18:49:50 -04001960bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001961{
1962 if (!context->getExtensions().vertexArrayObject)
1963 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001964 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001965 return false;
1966 }
1967
Olli Etuaho41997e72016-03-10 13:38:39 +02001968 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001969}
1970
Jamie Madilld7576732017-08-26 18:49:50 -04001971bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001972{
1973 if (!context->getExtensions().vertexArrayObject)
1974 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001975 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001976 return false;
1977 }
1978
Olli Etuaho41997e72016-03-10 13:38:39 +02001979 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001980}
1981
Jamie Madilld7576732017-08-26 18:49:50 -04001982bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001983{
1984 if (!context->getExtensions().vertexArrayObject)
1985 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001986 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001987 return false;
1988 }
1989
1990 return true;
1991}
Geoff Langc5629752015-12-07 16:29:04 -05001992
1993bool ValidateProgramBinaryOES(Context *context,
1994 GLuint program,
1995 GLenum binaryFormat,
1996 const void *binary,
1997 GLint length)
1998{
1999 if (!context->getExtensions().getProgramBinary)
2000 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002001 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002002 return false;
2003 }
2004
2005 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2006}
2007
2008bool ValidateGetProgramBinaryOES(Context *context,
2009 GLuint program,
2010 GLsizei bufSize,
2011 GLsizei *length,
2012 GLenum *binaryFormat,
2013 void *binary)
2014{
2015 if (!context->getExtensions().getProgramBinary)
2016 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002017 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002018 return false;
2019 }
2020
2021 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2022}
Geoff Lange102fee2015-12-10 11:23:30 -05002023
Geoff Lang70d0f492015-12-10 17:45:46 -05002024static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2025{
2026 switch (source)
2027 {
2028 case GL_DEBUG_SOURCE_API:
2029 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2030 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2031 case GL_DEBUG_SOURCE_OTHER:
2032 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2033 return !mustBeThirdPartyOrApplication;
2034
2035 case GL_DEBUG_SOURCE_THIRD_PARTY:
2036 case GL_DEBUG_SOURCE_APPLICATION:
2037 return true;
2038
2039 default:
2040 return false;
2041 }
2042}
2043
2044static bool ValidDebugType(GLenum type)
2045{
2046 switch (type)
2047 {
2048 case GL_DEBUG_TYPE_ERROR:
2049 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2050 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2051 case GL_DEBUG_TYPE_PERFORMANCE:
2052 case GL_DEBUG_TYPE_PORTABILITY:
2053 case GL_DEBUG_TYPE_OTHER:
2054 case GL_DEBUG_TYPE_MARKER:
2055 case GL_DEBUG_TYPE_PUSH_GROUP:
2056 case GL_DEBUG_TYPE_POP_GROUP:
2057 return true;
2058
2059 default:
2060 return false;
2061 }
2062}
2063
2064static bool ValidDebugSeverity(GLenum severity)
2065{
2066 switch (severity)
2067 {
2068 case GL_DEBUG_SEVERITY_HIGH:
2069 case GL_DEBUG_SEVERITY_MEDIUM:
2070 case GL_DEBUG_SEVERITY_LOW:
2071 case GL_DEBUG_SEVERITY_NOTIFICATION:
2072 return true;
2073
2074 default:
2075 return false;
2076 }
2077}
2078
Geoff Lange102fee2015-12-10 11:23:30 -05002079bool ValidateDebugMessageControlKHR(Context *context,
2080 GLenum source,
2081 GLenum type,
2082 GLenum severity,
2083 GLsizei count,
2084 const GLuint *ids,
2085 GLboolean enabled)
2086{
2087 if (!context->getExtensions().debug)
2088 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002089 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002090 return false;
2091 }
2092
Geoff Lang70d0f492015-12-10 17:45:46 -05002093 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2094 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002095 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002096 return false;
2097 }
2098
2099 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2100 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002101 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002102 return false;
2103 }
2104
2105 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2106 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002107 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002108 return false;
2109 }
2110
2111 if (count > 0)
2112 {
2113 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2114 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002115 context->handleError(
2116 InvalidOperation()
2117 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002118 return false;
2119 }
2120
2121 if (severity != GL_DONT_CARE)
2122 {
Jamie Madill437fa652016-05-03 15:13:24 -04002123 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002124 InvalidOperation()
2125 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 return false;
2127 }
2128 }
2129
Geoff Lange102fee2015-12-10 11:23:30 -05002130 return true;
2131}
2132
2133bool ValidateDebugMessageInsertKHR(Context *context,
2134 GLenum source,
2135 GLenum type,
2136 GLuint id,
2137 GLenum severity,
2138 GLsizei length,
2139 const GLchar *buf)
2140{
2141 if (!context->getExtensions().debug)
2142 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002143 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002144 return false;
2145 }
2146
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002147 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002148 {
2149 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2150 // not generate an error.
2151 return false;
2152 }
2153
2154 if (!ValidDebugSeverity(severity))
2155 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002156 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002157 return false;
2158 }
2159
2160 if (!ValidDebugType(type))
2161 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002162 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002163 return false;
2164 }
2165
2166 if (!ValidDebugSource(source, true))
2167 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002168 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002169 return false;
2170 }
2171
2172 size_t messageLength = (length < 0) ? strlen(buf) : length;
2173 if (messageLength > context->getExtensions().maxDebugMessageLength)
2174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002175 context->handleError(InvalidValue()
2176 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002177 return false;
2178 }
2179
Geoff Lange102fee2015-12-10 11:23:30 -05002180 return true;
2181}
2182
2183bool ValidateDebugMessageCallbackKHR(Context *context,
2184 GLDEBUGPROCKHR callback,
2185 const void *userParam)
2186{
2187 if (!context->getExtensions().debug)
2188 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002189 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002190 return false;
2191 }
2192
Geoff Lange102fee2015-12-10 11:23:30 -05002193 return true;
2194}
2195
2196bool ValidateGetDebugMessageLogKHR(Context *context,
2197 GLuint count,
2198 GLsizei bufSize,
2199 GLenum *sources,
2200 GLenum *types,
2201 GLuint *ids,
2202 GLenum *severities,
2203 GLsizei *lengths,
2204 GLchar *messageLog)
2205{
2206 if (!context->getExtensions().debug)
2207 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002208 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002209 return false;
2210 }
2211
Geoff Lang70d0f492015-12-10 17:45:46 -05002212 if (bufSize < 0 && messageLog != nullptr)
2213 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002214 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002215 return false;
2216 }
2217
Geoff Lange102fee2015-12-10 11:23:30 -05002218 return true;
2219}
2220
2221bool ValidatePushDebugGroupKHR(Context *context,
2222 GLenum source,
2223 GLuint id,
2224 GLsizei length,
2225 const GLchar *message)
2226{
2227 if (!context->getExtensions().debug)
2228 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002229 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002230 return false;
2231 }
2232
Geoff Lang70d0f492015-12-10 17:45:46 -05002233 if (!ValidDebugSource(source, true))
2234 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002235 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002236 return false;
2237 }
2238
2239 size_t messageLength = (length < 0) ? strlen(message) : length;
2240 if (messageLength > context->getExtensions().maxDebugMessageLength)
2241 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002242 context->handleError(InvalidValue()
2243 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002244 return false;
2245 }
2246
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002247 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002248 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2249 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002250 context
2251 ->handleError(StackOverflow()
2252 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002253 return false;
2254 }
2255
Geoff Lange102fee2015-12-10 11:23:30 -05002256 return true;
2257}
2258
2259bool ValidatePopDebugGroupKHR(Context *context)
2260{
2261 if (!context->getExtensions().debug)
2262 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002263 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002264 return false;
2265 }
2266
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002267 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002268 if (currentStackSize <= 1)
2269 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002270 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002271 return false;
2272 }
2273
2274 return true;
2275}
2276
2277static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2278{
2279 switch (identifier)
2280 {
2281 case GL_BUFFER:
2282 if (context->getBuffer(name) == nullptr)
2283 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002284 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002285 return false;
2286 }
2287 return true;
2288
2289 case GL_SHADER:
2290 if (context->getShader(name) == nullptr)
2291 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002292 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002293 return false;
2294 }
2295 return true;
2296
2297 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002298 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002299 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002300 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002301 return false;
2302 }
2303 return true;
2304
2305 case GL_VERTEX_ARRAY:
2306 if (context->getVertexArray(name) == nullptr)
2307 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002308 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002309 return false;
2310 }
2311 return true;
2312
2313 case GL_QUERY:
2314 if (context->getQuery(name) == nullptr)
2315 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002316 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002317 return false;
2318 }
2319 return true;
2320
2321 case GL_TRANSFORM_FEEDBACK:
2322 if (context->getTransformFeedback(name) == nullptr)
2323 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002324 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002325 return false;
2326 }
2327 return true;
2328
2329 case GL_SAMPLER:
2330 if (context->getSampler(name) == nullptr)
2331 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002332 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002333 return false;
2334 }
2335 return true;
2336
2337 case GL_TEXTURE:
2338 if (context->getTexture(name) == nullptr)
2339 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002340 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002341 return false;
2342 }
2343 return true;
2344
2345 case GL_RENDERBUFFER:
2346 if (context->getRenderbuffer(name) == nullptr)
2347 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002348 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002349 return false;
2350 }
2351 return true;
2352
2353 case GL_FRAMEBUFFER:
2354 if (context->getFramebuffer(name) == nullptr)
2355 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002356 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002357 return false;
2358 }
2359 return true;
2360
2361 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002362 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002363 return false;
2364 }
Geoff Lange102fee2015-12-10 11:23:30 -05002365}
2366
Martin Radev9d901792016-07-15 15:58:58 +03002367static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2368{
2369 size_t labelLength = 0;
2370
2371 if (length < 0)
2372 {
2373 if (label != nullptr)
2374 {
2375 labelLength = strlen(label);
2376 }
2377 }
2378 else
2379 {
2380 labelLength = static_cast<size_t>(length);
2381 }
2382
2383 if (labelLength > context->getExtensions().maxLabelLength)
2384 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002385 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002386 return false;
2387 }
2388
2389 return true;
2390}
2391
Geoff Lange102fee2015-12-10 11:23:30 -05002392bool ValidateObjectLabelKHR(Context *context,
2393 GLenum identifier,
2394 GLuint name,
2395 GLsizei length,
2396 const GLchar *label)
2397{
2398 if (!context->getExtensions().debug)
2399 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002401 return false;
2402 }
2403
Geoff Lang70d0f492015-12-10 17:45:46 -05002404 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2405 {
2406 return false;
2407 }
2408
Martin Radev9d901792016-07-15 15:58:58 +03002409 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002410 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002411 return false;
2412 }
2413
Geoff Lange102fee2015-12-10 11:23:30 -05002414 return true;
2415}
2416
2417bool ValidateGetObjectLabelKHR(Context *context,
2418 GLenum identifier,
2419 GLuint name,
2420 GLsizei bufSize,
2421 GLsizei *length,
2422 GLchar *label)
2423{
2424 if (!context->getExtensions().debug)
2425 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002426 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002427 return false;
2428 }
2429
Geoff Lang70d0f492015-12-10 17:45:46 -05002430 if (bufSize < 0)
2431 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002432 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002433 return false;
2434 }
2435
2436 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2437 {
2438 return false;
2439 }
2440
Martin Radev9d901792016-07-15 15:58:58 +03002441 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002442}
2443
2444static bool ValidateObjectPtrName(Context *context, const void *ptr)
2445{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002446 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002447 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002448 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002449 return false;
2450 }
2451
Geoff Lange102fee2015-12-10 11:23:30 -05002452 return true;
2453}
2454
2455bool ValidateObjectPtrLabelKHR(Context *context,
2456 const void *ptr,
2457 GLsizei length,
2458 const GLchar *label)
2459{
2460 if (!context->getExtensions().debug)
2461 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002462 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002463 return false;
2464 }
2465
Geoff Lang70d0f492015-12-10 17:45:46 -05002466 if (!ValidateObjectPtrName(context, ptr))
2467 {
2468 return false;
2469 }
2470
Martin Radev9d901792016-07-15 15:58:58 +03002471 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002472 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002473 return false;
2474 }
2475
Geoff Lange102fee2015-12-10 11:23:30 -05002476 return true;
2477}
2478
2479bool ValidateGetObjectPtrLabelKHR(Context *context,
2480 const void *ptr,
2481 GLsizei bufSize,
2482 GLsizei *length,
2483 GLchar *label)
2484{
2485 if (!context->getExtensions().debug)
2486 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002487 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002488 return false;
2489 }
2490
Geoff Lang70d0f492015-12-10 17:45:46 -05002491 if (bufSize < 0)
2492 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002493 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002494 return false;
2495 }
2496
2497 if (!ValidateObjectPtrName(context, ptr))
2498 {
2499 return false;
2500 }
2501
Martin Radev9d901792016-07-15 15:58:58 +03002502 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002503}
2504
2505bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2506{
2507 if (!context->getExtensions().debug)
2508 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002509 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002510 return false;
2511 }
2512
Geoff Lang70d0f492015-12-10 17:45:46 -05002513 // TODO: represent this in Context::getQueryParameterInfo.
2514 switch (pname)
2515 {
2516 case GL_DEBUG_CALLBACK_FUNCTION:
2517 case GL_DEBUG_CALLBACK_USER_PARAM:
2518 break;
2519
2520 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002521 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002522 return false;
2523 }
2524
Geoff Lange102fee2015-12-10 11:23:30 -05002525 return true;
2526}
Jamie Madillc29968b2016-01-20 11:17:23 -05002527
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002528bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2529 GLenum pname,
2530 GLsizei bufSize,
2531 GLsizei *length,
2532 void **params)
2533{
2534 UNIMPLEMENTED();
2535 return false;
2536}
2537
Jamie Madillc29968b2016-01-20 11:17:23 -05002538bool ValidateBlitFramebufferANGLE(Context *context,
2539 GLint srcX0,
2540 GLint srcY0,
2541 GLint srcX1,
2542 GLint srcY1,
2543 GLint dstX0,
2544 GLint dstY0,
2545 GLint dstX1,
2546 GLint dstY1,
2547 GLbitfield mask,
2548 GLenum filter)
2549{
2550 if (!context->getExtensions().framebufferBlit)
2551 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002552 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002553 return false;
2554 }
2555
2556 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2557 {
2558 // TODO(jmadill): Determine if this should be available on other implementations.
Olli Etuahof0e3c192018-08-15 13:37:21 +03002559 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002560 return false;
2561 }
2562
2563 if (filter == GL_LINEAR)
2564 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002565 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002566 return false;
2567 }
2568
Jamie Madill51f40ec2016-06-15 14:06:00 -04002569 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2570 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002571
2572 if (mask & GL_COLOR_BUFFER_BIT)
2573 {
2574 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2575 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2576
2577 if (readColorAttachment && drawColorAttachment)
2578 {
2579 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002580 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002581 readColorAttachment->type() != GL_RENDERBUFFER &&
2582 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2583 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002584 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2585 BlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002586 return false;
2587 }
2588
Geoff Langa15472a2015-08-11 11:48:03 -04002589 for (size_t drawbufferIdx = 0;
2590 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002591 {
Geoff Langa15472a2015-08-11 11:48:03 -04002592 const FramebufferAttachment *attachment =
2593 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2594 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002595 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002596 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002597 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002598 attachment->type() != GL_RENDERBUFFER &&
2599 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2600 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002601 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2602 BlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002603 return false;
2604 }
2605
2606 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002607 if (!Format::EquivalentForBlit(attachment->getFormat(),
2608 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002609 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002610 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2611 BlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002612 return false;
2613 }
2614 }
2615 }
2616
Jamie Madill427064d2018-04-13 16:20:34 -04002617 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002618 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002619 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2620 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2621 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002622 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2623 BlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002624 return false;
2625 }
2626 }
2627 }
2628
2629 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2630 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2631 for (size_t i = 0; i < 2; i++)
2632 {
2633 if (mask & masks[i])
2634 {
2635 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002636 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002637 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002638 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002639
2640 if (readBuffer && drawBuffer)
2641 {
2642 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2643 dstX0, dstY0, dstX1, dstY1))
2644 {
2645 // only whole-buffer copies are permitted
Olli Etuahof0e3c192018-08-15 13:37:21 +03002646 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2647 BlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002648 return false;
2649 }
2650
2651 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2652 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002653 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2654 BlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002655 return false;
2656 }
2657 }
2658 }
2659 }
2660
2661 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2662 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002663}
Jamie Madillc29968b2016-01-20 11:17:23 -05002664
Jamie Madill5b772312018-03-08 20:28:32 -05002665bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002666{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002667 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002668 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002669
Jamie Madill427064d2018-04-13 16:20:34 -04002670 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002671 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002672 return false;
2673 }
2674
2675 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2676 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002677 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002678 return false;
2679 }
2680
Olli Etuaho94c91a92018-07-19 15:10:24 +03002681 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002682 {
2683 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2684 GL_SIGNED_NORMALIZED};
2685
Corentin Wallez59c41592017-07-11 13:19:54 -04002686 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002687 drawBufferIdx++)
2688 {
2689 if (!ValidateWebGLFramebufferAttachmentClearType(
2690 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2691 {
2692 return false;
2693 }
2694 }
2695 }
2696
Olli Etuaho94c91a92018-07-19 15:10:24 +03002697 if (extensions.multiview && extensions.disjointTimerQuery)
2698 {
2699 const State &state = context->getGLState();
2700 Framebuffer *framebuffer = state.getDrawFramebuffer();
2701 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2702 {
2703 context->handleError(InvalidOperation() << "There is an active query for target "
2704 "GL_TIME_ELAPSED_EXT when the number of "
2705 "views in the active draw framebuffer is "
2706 "greater than 1.");
2707 return false;
2708 }
2709 }
2710
Jamie Madillc29968b2016-01-20 11:17:23 -05002711 return true;
2712}
2713
Jamie Madill5b772312018-03-08 20:28:32 -05002714bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002715{
2716 if (!context->getExtensions().drawBuffers)
2717 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002718 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002719 return false;
2720 }
2721
2722 return ValidateDrawBuffersBase(context, n, bufs);
2723}
2724
Jamie Madill73a84962016-02-12 09:27:23 -05002725bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002726 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002727 GLint level,
2728 GLint internalformat,
2729 GLsizei width,
2730 GLsizei height,
2731 GLint border,
2732 GLenum format,
2733 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002734 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002735{
Martin Radev1be913c2016-07-11 17:59:16 +03002736 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002737 {
2738 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002739 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002740 }
2741
Martin Radev1be913c2016-07-11 17:59:16 +03002742 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002743 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002744 0, 0, width, height, 1, border, format, type, -1,
2745 pixels);
2746}
2747
Brandon Jones416aaf92018-04-10 08:10:16 -07002748bool ValidateTexImage2DRobustANGLE(Context *context,
2749 TextureTarget target,
2750 GLint level,
2751 GLint internalformat,
2752 GLsizei width,
2753 GLsizei height,
2754 GLint border,
2755 GLenum format,
2756 GLenum type,
2757 GLsizei bufSize,
2758 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002759{
2760 if (!ValidateRobustEntryPoint(context, bufSize))
2761 {
2762 return false;
2763 }
2764
2765 if (context->getClientMajorVersion() < 3)
2766 {
2767 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2768 0, 0, width, height, border, format, type, bufSize,
2769 pixels);
2770 }
2771
2772 ASSERT(context->getClientMajorVersion() >= 3);
2773 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2774 0, 0, width, height, 1, border, format, type, bufSize,
2775 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002776}
2777
2778bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002779 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002780 GLint level,
2781 GLint xoffset,
2782 GLint yoffset,
2783 GLsizei width,
2784 GLsizei height,
2785 GLenum format,
2786 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002787 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002788{
2789
Martin Radev1be913c2016-07-11 17:59:16 +03002790 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002791 {
2792 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002793 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002794 }
2795
Martin Radev1be913c2016-07-11 17:59:16 +03002796 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002797 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002798 yoffset, 0, width, height, 1, 0, format, type, -1,
2799 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002800}
2801
Geoff Langc52f6f12016-10-14 10:18:00 -04002802bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002803 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002804 GLint level,
2805 GLint xoffset,
2806 GLint yoffset,
2807 GLsizei width,
2808 GLsizei height,
2809 GLenum format,
2810 GLenum type,
2811 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002812 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002813{
2814 if (!ValidateRobustEntryPoint(context, bufSize))
2815 {
2816 return false;
2817 }
2818
2819 if (context->getClientMajorVersion() < 3)
2820 {
2821 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2822 yoffset, width, height, 0, format, type, bufSize,
2823 pixels);
2824 }
2825
2826 ASSERT(context->getClientMajorVersion() >= 3);
2827 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2828 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2829 pixels);
2830}
2831
Jamie Madill73a84962016-02-12 09:27:23 -05002832bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002833 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002834 GLint level,
2835 GLenum internalformat,
2836 GLsizei width,
2837 GLsizei height,
2838 GLint border,
2839 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002840 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002841{
Martin Radev1be913c2016-07-11 17:59:16 +03002842 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002843 {
2844 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002845 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002846 {
2847 return false;
2848 }
2849 }
2850 else
2851 {
Martin Radev1be913c2016-07-11 17:59:16 +03002852 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002853 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002854 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002855 data))
2856 {
2857 return false;
2858 }
2859 }
2860
Geoff Langca271392017-04-05 12:30:00 -04002861 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002862
2863 GLuint blockSize = 0;
2864 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002865 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002866 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002867 return false;
2868 }
2869
Jamie Madillca2ff382018-07-11 09:01:17 -04002870 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002871 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002872 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002873 return false;
2874 }
2875
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002876 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002877 {
2878 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2879 return false;
2880 }
2881
Jamie Madill73a84962016-02-12 09:27:23 -05002882 return true;
2883}
2884
Corentin Wallezb2931602017-04-11 15:58:57 -04002885bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002886 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002887 GLint level,
2888 GLenum internalformat,
2889 GLsizei width,
2890 GLsizei height,
2891 GLint border,
2892 GLsizei imageSize,
2893 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002894 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002895{
2896 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2897 {
2898 return false;
2899 }
2900
2901 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2902 border, imageSize, data);
2903}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002904
Corentin Wallezb2931602017-04-11 15:58:57 -04002905bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002906 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002907 GLint level,
2908 GLint xoffset,
2909 GLint yoffset,
2910 GLsizei width,
2911 GLsizei height,
2912 GLenum format,
2913 GLsizei imageSize,
2914 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002915 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002916{
2917 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2918 {
2919 return false;
2920 }
2921
2922 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2923 format, imageSize, data);
2924}
2925
Jamie Madill73a84962016-02-12 09:27:23 -05002926bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002927 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002928 GLint level,
2929 GLint xoffset,
2930 GLint yoffset,
2931 GLsizei width,
2932 GLsizei height,
2933 GLenum format,
2934 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002935 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002936{
Martin Radev1be913c2016-07-11 17:59:16 +03002937 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002938 {
2939 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002940 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002941 {
2942 return false;
2943 }
2944 }
2945 else
2946 {
Martin Radev1be913c2016-07-11 17:59:16 +03002947 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002948 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002949 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002950 data))
2951 {
2952 return false;
2953 }
2954 }
2955
Geoff Langca271392017-04-05 12:30:00 -04002956 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002957 GLuint blockSize = 0;
2958 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002959 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002960 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002961 return false;
2962 }
2963
Jamie Madillca2ff382018-07-11 09:01:17 -04002964 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002965 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002966 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002967 return false;
2968 }
2969
2970 return true;
2971}
2972
Corentin Wallez336129f2017-10-17 15:55:40 -04002973bool ValidateGetBufferPointervOES(Context *context,
2974 BufferBinding target,
2975 GLenum pname,
2976 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002977{
Geoff Lang496c02d2016-10-20 11:38:11 -07002978 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002979}
2980
Corentin Wallez336129f2017-10-17 15:55:40 -04002981bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002982{
2983 if (!context->getExtensions().mapBuffer)
2984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002985 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002986 return false;
2987 }
2988
Corentin Walleze4477002017-12-01 14:39:58 -05002989 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002990 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002991 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002992 return false;
2993 }
2994
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002995 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002996
2997 if (buffer == nullptr)
2998 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002999 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003000 return false;
3001 }
3002
3003 if (access != GL_WRITE_ONLY_OES)
3004 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003005 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003006 return false;
3007 }
3008
3009 if (buffer->isMapped())
3010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003011 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003012 return false;
3013 }
3014
Geoff Lang79f71042017-08-14 16:43:43 -04003015 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003016}
3017
Corentin Wallez336129f2017-10-17 15:55:40 -04003018bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003019{
3020 if (!context->getExtensions().mapBuffer)
3021 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003022 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003023 return false;
3024 }
3025
3026 return ValidateUnmapBufferBase(context, target);
3027}
3028
3029bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003030 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003031 GLintptr offset,
3032 GLsizeiptr length,
3033 GLbitfield access)
3034{
3035 if (!context->getExtensions().mapBufferRange)
3036 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003037 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003038 return false;
3039 }
3040
3041 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3042}
3043
Corentin Wallez336129f2017-10-17 15:55:40 -04003044bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003045{
3046 Buffer *buffer = context->getGLState().getTargetBuffer(target);
3047 ASSERT(buffer != nullptr);
3048
3049 // Check if this buffer is currently being used as a transform feedback output buffer
3050 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3051 if (transformFeedback != nullptr && transformFeedback->isActive())
3052 {
3053 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3054 {
3055 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3056 if (transformFeedbackBuffer.get() == buffer)
3057 {
3058 context->handleError(InvalidOperation()
3059 << "Buffer is currently bound for transform feedback.");
3060 return false;
3061 }
3062 }
3063 }
3064
James Darpiniane8a93c62018-01-04 18:02:24 -08003065 if (context->getExtensions().webglCompatibility &&
3066 buffer->isBoundForTransformFeedbackAndOtherUse())
3067 {
3068 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
3069 return false;
3070 }
3071
Geoff Lang79f71042017-08-14 16:43:43 -04003072 return true;
3073}
3074
Olli Etuaho4f667482016-03-30 15:56:35 +03003075bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003076 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003077 GLintptr offset,
3078 GLsizeiptr length)
3079{
3080 if (!context->getExtensions().mapBufferRange)
3081 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003082 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003083 return false;
3084 }
3085
3086 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3087}
3088
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003089bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05003090{
Jamie Madillac66f982018-10-09 18:30:01 -04003091 if (!context->getStateCache().isValidBindTextureType(target))
Ian Ewell54f87462016-03-10 13:47:21 -05003092 {
Jamie Madillac66f982018-10-09 18:30:01 -04003093 RecordBindTextureTypeError(context, target);
3094 return false;
Ian Ewell54f87462016-03-10 13:47:21 -05003095 }
3096
Jamie Madill0fdb9562018-09-17 17:18:43 -04003097 if (texture == 0)
3098 {
3099 return true;
3100 }
3101
3102 Texture *textureObject = context->getTexture(texture);
3103 if (textureObject && textureObject->getType() != target)
3104 {
3105 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
3106 return false;
3107 }
3108
3109 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3110 !context->isTextureGenerated(texture))
3111 {
3112 context->handleError(InvalidOperation() << "Texture was not generated");
3113 return false;
3114 }
3115
Ian Ewell54f87462016-03-10 13:47:21 -05003116 return true;
3117}
3118
Geoff Langd8605522016-04-13 10:19:12 -04003119bool ValidateBindUniformLocationCHROMIUM(Context *context,
3120 GLuint program,
3121 GLint location,
3122 const GLchar *name)
3123{
3124 if (!context->getExtensions().bindUniformLocation)
3125 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003126 context->handleError(InvalidOperation()
3127 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003128 return false;
3129 }
3130
3131 Program *programObject = GetValidProgram(context, program);
3132 if (!programObject)
3133 {
3134 return false;
3135 }
3136
3137 if (location < 0)
3138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003139 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003140 return false;
3141 }
3142
3143 const Caps &caps = context->getCaps();
3144 if (static_cast<size_t>(location) >=
3145 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3146 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003147 context->handleError(InvalidValue() << "Location must be less than "
3148 "(MAX_VERTEX_UNIFORM_VECTORS + "
3149 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003150 return false;
3151 }
3152
Geoff Langfc32e8b2017-05-31 14:16:59 -04003153 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3154 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003155 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003157 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003158 return false;
3159 }
3160
Geoff Langd8605522016-04-13 10:19:12 -04003161 if (strncmp(name, "gl_", 3) == 0)
3162 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003163 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003164 return false;
3165 }
3166
3167 return true;
3168}
3169
Jamie Madille2e406c2016-06-02 13:04:10 -04003170bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003171{
3172 if (!context->getExtensions().framebufferMixedSamples)
3173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003174 context->handleError(InvalidOperation()
3175 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003176 return false;
3177 }
3178 switch (components)
3179 {
3180 case GL_RGB:
3181 case GL_RGBA:
3182 case GL_ALPHA:
3183 case GL_NONE:
3184 break;
3185 default:
3186 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003187 InvalidEnum()
3188 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003189 return false;
3190 }
3191
3192 return true;
3193}
3194
Sami Väisänene45e53b2016-05-25 10:36:04 +03003195// CHROMIUM_path_rendering
3196
Jamie Madill007530e2017-12-28 14:27:04 -05003197bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003198{
Jamie Madill007530e2017-12-28 14:27:04 -05003199 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003200 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003201 return false;
3202 }
Jamie Madill007530e2017-12-28 14:27:04 -05003203
Sami Väisänene45e53b2016-05-25 10:36:04 +03003204 if (matrix == nullptr)
3205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003206 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003207 return false;
3208 }
Jamie Madill007530e2017-12-28 14:27:04 -05003209
Sami Väisänene45e53b2016-05-25 10:36:04 +03003210 return true;
3211}
3212
Jamie Madill007530e2017-12-28 14:27:04 -05003213bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003214{
Jamie Madill007530e2017-12-28 14:27:04 -05003215 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003216}
3217
Jamie Madill007530e2017-12-28 14:27:04 -05003218bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003219{
3220 if (!context->getExtensions().pathRendering)
3221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003222 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003223 return false;
3224 }
3225
3226 // range = 0 is undefined in NV_path_rendering.
3227 // we add stricter semantic check here and require a non zero positive range.
3228 if (range <= 0)
3229 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003230 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003231 return false;
3232 }
3233
3234 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3235 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003236 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003237 return false;
3238 }
3239
3240 return true;
3241}
3242
Jamie Madill007530e2017-12-28 14:27:04 -05003243bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003244{
3245 if (!context->getExtensions().pathRendering)
3246 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003247 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003248 return false;
3249 }
3250
3251 // range = 0 is undefined in NV_path_rendering.
3252 // we add stricter semantic check here and require a non zero positive range.
3253 if (range <= 0)
3254 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003255 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003256 return false;
3257 }
3258
3259 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3260 checkedRange += range;
3261
3262 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3263 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003264 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003265 return false;
3266 }
3267 return true;
3268}
3269
Jamie Madill007530e2017-12-28 14:27:04 -05003270bool ValidatePathCommandsCHROMIUM(Context *context,
3271 GLuint path,
3272 GLsizei numCommands,
3273 const GLubyte *commands,
3274 GLsizei numCoords,
3275 GLenum coordType,
3276 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003277{
3278 if (!context->getExtensions().pathRendering)
3279 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003280 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003281 return false;
3282 }
Brandon Jones59770802018-04-02 13:18:42 -07003283 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003284 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003285 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003286 return false;
3287 }
3288
3289 if (numCommands < 0)
3290 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003291 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003292 return false;
3293 }
3294 else if (numCommands > 0)
3295 {
3296 if (!commands)
3297 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003298 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003299 return false;
3300 }
3301 }
3302
3303 if (numCoords < 0)
3304 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003305 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003306 return false;
3307 }
3308 else if (numCoords > 0)
3309 {
3310 if (!coords)
3311 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003312 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003313 return false;
3314 }
3315 }
3316
3317 std::uint32_t coordTypeSize = 0;
3318 switch (coordType)
3319 {
3320 case GL_BYTE:
3321 coordTypeSize = sizeof(GLbyte);
3322 break;
3323
3324 case GL_UNSIGNED_BYTE:
3325 coordTypeSize = sizeof(GLubyte);
3326 break;
3327
3328 case GL_SHORT:
3329 coordTypeSize = sizeof(GLshort);
3330 break;
3331
3332 case GL_UNSIGNED_SHORT:
3333 coordTypeSize = sizeof(GLushort);
3334 break;
3335
3336 case GL_FLOAT:
3337 coordTypeSize = sizeof(GLfloat);
3338 break;
3339
3340 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003341 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003342 return false;
3343 }
3344
3345 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3346 checkedSize += (coordTypeSize * numCoords);
3347 if (!checkedSize.IsValid())
3348 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003349 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003350 return false;
3351 }
3352
3353 // early return skips command data validation when it doesn't exist.
3354 if (!commands)
3355 return true;
3356
3357 GLsizei expectedNumCoords = 0;
3358 for (GLsizei i = 0; i < numCommands; ++i)
3359 {
3360 switch (commands[i])
3361 {
3362 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3363 break;
3364 case GL_MOVE_TO_CHROMIUM:
3365 case GL_LINE_TO_CHROMIUM:
3366 expectedNumCoords += 2;
3367 break;
3368 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3369 expectedNumCoords += 4;
3370 break;
3371 case GL_CUBIC_CURVE_TO_CHROMIUM:
3372 expectedNumCoords += 6;
3373 break;
3374 case GL_CONIC_CURVE_TO_CHROMIUM:
3375 expectedNumCoords += 5;
3376 break;
3377 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003378 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003379 return false;
3380 }
3381 }
3382 if (expectedNumCoords != numCoords)
3383 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003384 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003385 return false;
3386 }
3387
3388 return true;
3389}
3390
Jamie Madill007530e2017-12-28 14:27:04 -05003391bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003392{
3393 if (!context->getExtensions().pathRendering)
3394 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003395 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003396 return false;
3397 }
Brandon Jones59770802018-04-02 13:18:42 -07003398 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003399 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003401 return false;
3402 }
3403
3404 switch (pname)
3405 {
3406 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3407 if (value < 0.0f)
3408 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003409 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003410 return false;
3411 }
3412 break;
3413 case GL_PATH_END_CAPS_CHROMIUM:
3414 switch (static_cast<GLenum>(value))
3415 {
3416 case GL_FLAT_CHROMIUM:
3417 case GL_SQUARE_CHROMIUM:
3418 case GL_ROUND_CHROMIUM:
3419 break;
3420 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003421 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003422 return false;
3423 }
3424 break;
3425 case GL_PATH_JOIN_STYLE_CHROMIUM:
3426 switch (static_cast<GLenum>(value))
3427 {
3428 case GL_MITER_REVERT_CHROMIUM:
3429 case GL_BEVEL_CHROMIUM:
3430 case GL_ROUND_CHROMIUM:
3431 break;
3432 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003433 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003434 return false;
3435 }
Nico Weber41b072b2018-02-09 10:01:32 -05003436 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003437 case GL_PATH_MITER_LIMIT_CHROMIUM:
3438 if (value < 0.0f)
3439 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003440 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003441 return false;
3442 }
3443 break;
3444
3445 case GL_PATH_STROKE_BOUND_CHROMIUM:
3446 // no errors, only clamping.
3447 break;
3448
3449 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003450 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003451 return false;
3452 }
3453 return true;
3454}
3455
Jamie Madill007530e2017-12-28 14:27:04 -05003456bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3457{
3458 // TODO(jmadill): Use proper clamping cast.
3459 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3460}
3461
3462bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003463{
3464 if (!context->getExtensions().pathRendering)
3465 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003466 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003467 return false;
3468 }
3469
Brandon Jones59770802018-04-02 13:18:42 -07003470 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003472 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003473 return false;
3474 }
3475 if (!value)
3476 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003477 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003478 return false;
3479 }
3480
3481 switch (pname)
3482 {
3483 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3484 case GL_PATH_END_CAPS_CHROMIUM:
3485 case GL_PATH_JOIN_STYLE_CHROMIUM:
3486 case GL_PATH_MITER_LIMIT_CHROMIUM:
3487 case GL_PATH_STROKE_BOUND_CHROMIUM:
3488 break;
3489
3490 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003491 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003492 return false;
3493 }
3494
3495 return true;
3496}
3497
Jamie Madill007530e2017-12-28 14:27:04 -05003498bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3499{
3500 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3501 reinterpret_cast<GLfloat *>(value));
3502}
3503
3504bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003505{
3506 if (!context->getExtensions().pathRendering)
3507 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003508 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003509 return false;
3510 }
3511
3512 switch (func)
3513 {
3514 case GL_NEVER:
3515 case GL_ALWAYS:
3516 case GL_LESS:
3517 case GL_LEQUAL:
3518 case GL_EQUAL:
3519 case GL_GEQUAL:
3520 case GL_GREATER:
3521 case GL_NOTEQUAL:
3522 break;
3523 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003524 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003525 return false;
3526 }
3527
3528 return true;
3529}
3530
3531// Note that the spec specifies that for the path drawing commands
3532// if the path object is not an existing path object the command
3533// does nothing and no error is generated.
3534// However if the path object exists but has not been specified any
3535// commands then an error is generated.
3536
Jamie Madill007530e2017-12-28 14:27:04 -05003537bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003538{
3539 if (!context->getExtensions().pathRendering)
3540 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003541 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003542 return false;
3543 }
Brandon Jones59770802018-04-02 13:18:42 -07003544 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003545 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003546 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003547 return false;
3548 }
3549
3550 switch (fillMode)
3551 {
3552 case GL_COUNT_UP_CHROMIUM:
3553 case GL_COUNT_DOWN_CHROMIUM:
3554 break;
3555 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003556 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003557 return false;
3558 }
3559
3560 if (!isPow2(mask + 1))
3561 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003562 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003563 return false;
3564 }
3565
3566 return true;
3567}
3568
Jamie Madill007530e2017-12-28 14:27:04 -05003569bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003570{
3571 if (!context->getExtensions().pathRendering)
3572 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003573 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003574 return false;
3575 }
Brandon Jones59770802018-04-02 13:18:42 -07003576 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003577 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003578 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003579 return false;
3580 }
3581
3582 return true;
3583}
3584
Jamie Madill007530e2017-12-28 14:27:04 -05003585bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003586{
3587 if (!context->getExtensions().pathRendering)
3588 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003589 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003590 return false;
3591 }
Brandon Jones59770802018-04-02 13:18:42 -07003592 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003593 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003594 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003595 return false;
3596 }
3597
3598 switch (coverMode)
3599 {
3600 case GL_CONVEX_HULL_CHROMIUM:
3601 case GL_BOUNDING_BOX_CHROMIUM:
3602 break;
3603 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003604 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003605 return false;
3606 }
3607 return true;
3608}
3609
Jamie Madill778bf092018-11-14 09:54:36 -05003610bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3611{
3612 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3613}
3614
3615bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3616{
3617 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3618}
3619
Jamie Madill007530e2017-12-28 14:27:04 -05003620bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3621 GLuint path,
3622 GLenum fillMode,
3623 GLuint mask,
3624 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003625{
Jamie Madill007530e2017-12-28 14:27:04 -05003626 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3627 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003628}
3629
Jamie Madill007530e2017-12-28 14:27:04 -05003630bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3631 GLuint path,
3632 GLint reference,
3633 GLuint mask,
3634 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003635{
Jamie Madill007530e2017-12-28 14:27:04 -05003636 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3637 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003638}
3639
Brandon Jonesd1049182018-03-28 10:02:20 -07003640bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003641{
3642 if (!context->getExtensions().pathRendering)
3643 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003644 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003645 return false;
3646 }
3647 return true;
3648}
3649
Jamie Madill007530e2017-12-28 14:27:04 -05003650bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3651 GLsizei numPaths,
3652 GLenum pathNameType,
3653 const void *paths,
3654 GLuint pathBase,
3655 GLenum coverMode,
3656 GLenum transformType,
3657 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003658{
3659 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3660 transformType, transformValues))
3661 return false;
3662
3663 switch (coverMode)
3664 {
3665 case GL_CONVEX_HULL_CHROMIUM:
3666 case GL_BOUNDING_BOX_CHROMIUM:
3667 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3668 break;
3669 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003670 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003671 return false;
3672 }
3673
3674 return true;
3675}
3676
Jamie Madill007530e2017-12-28 14:27:04 -05003677bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3678 GLsizei numPaths,
3679 GLenum pathNameType,
3680 const void *paths,
3681 GLuint pathBase,
3682 GLenum coverMode,
3683 GLenum transformType,
3684 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003685{
3686 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3687 transformType, transformValues))
3688 return false;
3689
3690 switch (coverMode)
3691 {
3692 case GL_CONVEX_HULL_CHROMIUM:
3693 case GL_BOUNDING_BOX_CHROMIUM:
3694 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3695 break;
3696 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003697 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003698 return false;
3699 }
3700
3701 return true;
3702}
3703
Jamie Madill007530e2017-12-28 14:27:04 -05003704bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3705 GLsizei numPaths,
3706 GLenum pathNameType,
3707 const void *paths,
3708 GLuint pathBase,
3709 GLenum fillMode,
3710 GLuint mask,
3711 GLenum transformType,
3712 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003713{
3714
3715 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3716 transformType, transformValues))
3717 return false;
3718
3719 switch (fillMode)
3720 {
3721 case GL_COUNT_UP_CHROMIUM:
3722 case GL_COUNT_DOWN_CHROMIUM:
3723 break;
3724 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003725 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003726 return false;
3727 }
3728 if (!isPow2(mask + 1))
3729 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003730 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003731 return false;
3732 }
3733 return true;
3734}
3735
Jamie Madill007530e2017-12-28 14:27:04 -05003736bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3737 GLsizei numPaths,
3738 GLenum pathNameType,
3739 const void *paths,
3740 GLuint pathBase,
3741 GLint reference,
3742 GLuint mask,
3743 GLenum transformType,
3744 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003745{
3746 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3747 transformType, transformValues))
3748 return false;
3749
3750 // no more validation here.
3751
3752 return true;
3753}
3754
Jamie Madill007530e2017-12-28 14:27:04 -05003755bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3756 GLsizei numPaths,
3757 GLenum pathNameType,
3758 const void *paths,
3759 GLuint pathBase,
3760 GLenum fillMode,
3761 GLuint mask,
3762 GLenum coverMode,
3763 GLenum transformType,
3764 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003765{
3766 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3767 transformType, transformValues))
3768 return false;
3769
3770 switch (coverMode)
3771 {
3772 case GL_CONVEX_HULL_CHROMIUM:
3773 case GL_BOUNDING_BOX_CHROMIUM:
3774 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3775 break;
3776 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003777 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003778 return false;
3779 }
3780
3781 switch (fillMode)
3782 {
3783 case GL_COUNT_UP_CHROMIUM:
3784 case GL_COUNT_DOWN_CHROMIUM:
3785 break;
3786 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003787 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003788 return false;
3789 }
3790 if (!isPow2(mask + 1))
3791 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003792 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003793 return false;
3794 }
3795
3796 return true;
3797}
3798
Jamie Madill007530e2017-12-28 14:27:04 -05003799bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3800 GLsizei numPaths,
3801 GLenum pathNameType,
3802 const void *paths,
3803 GLuint pathBase,
3804 GLint reference,
3805 GLuint mask,
3806 GLenum coverMode,
3807 GLenum transformType,
3808 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003809{
3810 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3811 transformType, transformValues))
3812 return false;
3813
3814 switch (coverMode)
3815 {
3816 case GL_CONVEX_HULL_CHROMIUM:
3817 case GL_BOUNDING_BOX_CHROMIUM:
3818 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3819 break;
3820 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003821 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003822 return false;
3823 }
3824
3825 return true;
3826}
3827
Jamie Madill007530e2017-12-28 14:27:04 -05003828bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3829 GLuint program,
3830 GLint location,
3831 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003832{
3833 if (!context->getExtensions().pathRendering)
3834 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003835 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003836 return false;
3837 }
3838
3839 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3840 if (location >= MaxLocation)
3841 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003842 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003843 return false;
3844 }
3845
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003846 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003847 if (!programObject)
3848 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003849 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003850 return false;
3851 }
3852
3853 if (!name)
3854 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003855 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003856 return false;
3857 }
3858
3859 if (angle::BeginsWith(name, "gl_"))
3860 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003861 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003862 return false;
3863 }
3864
3865 return true;
3866}
3867
Jamie Madill007530e2017-12-28 14:27:04 -05003868bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3869 GLuint program,
3870 GLint location,
3871 GLenum genMode,
3872 GLint components,
3873 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003874{
3875 if (!context->getExtensions().pathRendering)
3876 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003877 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003878 return false;
3879 }
3880
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003881 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003882 if (!programObject || programObject->isFlaggedForDeletion())
3883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003884 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003885 return false;
3886 }
3887
3888 if (!programObject->isLinked())
3889 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003890 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003891 return false;
3892 }
3893
3894 switch (genMode)
3895 {
3896 case GL_NONE:
3897 if (components != 0)
3898 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003899 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003900 return false;
3901 }
3902 break;
3903
3904 case GL_OBJECT_LINEAR_CHROMIUM:
3905 case GL_EYE_LINEAR_CHROMIUM:
3906 case GL_CONSTANT_CHROMIUM:
3907 if (components < 1 || components > 4)
3908 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003909 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003910 return false;
3911 }
3912 if (!coeffs)
3913 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003914 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003915 return false;
3916 }
3917 break;
3918
3919 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003920 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003921 return false;
3922 }
3923
3924 // If the location is -1 then the command is silently ignored
3925 // and no further validation is needed.
3926 if (location == -1)
3927 return true;
3928
jchen103fd614d2018-08-13 12:21:58 +08003929 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003930
3931 if (!binding.valid)
3932 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003933 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003934 return false;
3935 }
3936
3937 if (binding.type != GL_NONE)
3938 {
3939 GLint expectedComponents = 0;
3940 switch (binding.type)
3941 {
3942 case GL_FLOAT:
3943 expectedComponents = 1;
3944 break;
3945 case GL_FLOAT_VEC2:
3946 expectedComponents = 2;
3947 break;
3948 case GL_FLOAT_VEC3:
3949 expectedComponents = 3;
3950 break;
3951 case GL_FLOAT_VEC4:
3952 expectedComponents = 4;
3953 break;
3954 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003955 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003956 InvalidOperation()
3957 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003958 return false;
3959 }
3960 if (expectedComponents != components && genMode != GL_NONE)
3961 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003962 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003963 return false;
3964 }
3965 }
3966 return true;
3967}
3968
Geoff Lang97073d12016-04-20 10:42:34 -07003969bool ValidateCopyTextureCHROMIUM(Context *context,
3970 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003971 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003972 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003973 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003974 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003975 GLint internalFormat,
3976 GLenum destType,
3977 GLboolean unpackFlipY,
3978 GLboolean unpackPremultiplyAlpha,
3979 GLboolean unpackUnmultiplyAlpha)
3980{
3981 if (!context->getExtensions().copyTexture)
3982 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003983 context->handleError(InvalidOperation()
3984 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003985 return false;
3986 }
3987
Geoff Lang4f0e0032017-05-01 16:04:35 -04003988 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003989 if (source == nullptr)
3990 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003991 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003992 return false;
3993 }
3994
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003995 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003996 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07003997 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003998 return false;
3999 }
4000
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004001 TextureType sourceType = source->getType();
4002 ASSERT(sourceType != TextureType::CubeMap);
4003 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004004
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004005 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004006 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004007 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004008 return false;
4009 }
4010
Geoff Lang4f0e0032017-05-01 16:04:35 -04004011 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4012 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4013 if (sourceWidth == 0 || sourceHeight == 0)
4014 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004015 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004016 return false;
4017 }
4018
4019 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4020 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004021 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004022 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004023 return false;
4024 }
4025
Geoff Lang63458a32017-10-30 15:16:53 -04004026 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4027 {
4028 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4029 return false;
4030 }
4031
Geoff Lang4f0e0032017-05-01 16:04:35 -04004032 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004033 if (dest == nullptr)
4034 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004035 context->handleError(InvalidValue()
4036 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004037 return false;
4038 }
4039
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004040 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004042 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004043 return false;
4044 }
4045
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004046 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004047 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004048 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004049 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004050 return false;
4051 }
4052
Geoff Lang97073d12016-04-20 10:42:34 -07004053 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4054 {
Geoff Lang97073d12016-04-20 10:42:34 -07004055 return false;
4056 }
4057
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004058 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004059 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004060 context->handleError(
4061 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004062 return false;
4063 }
4064
Geoff Lang97073d12016-04-20 10:42:34 -07004065 if (dest->getImmutableFormat())
4066 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004067 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07004068 return false;
4069 }
4070
4071 return true;
4072}
4073
4074bool ValidateCopySubTextureCHROMIUM(Context *context,
4075 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004076 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004077 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004078 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004079 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004080 GLint xoffset,
4081 GLint yoffset,
4082 GLint x,
4083 GLint y,
4084 GLsizei width,
4085 GLsizei height,
4086 GLboolean unpackFlipY,
4087 GLboolean unpackPremultiplyAlpha,
4088 GLboolean unpackUnmultiplyAlpha)
4089{
4090 if (!context->getExtensions().copyTexture)
4091 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004092 context->handleError(InvalidOperation()
4093 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004094 return false;
4095 }
4096
Geoff Lang4f0e0032017-05-01 16:04:35 -04004097 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004098 if (source == nullptr)
4099 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004100 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004101 return false;
4102 }
4103
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004104 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004105 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004106 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004107 return false;
4108 }
4109
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004110 TextureType sourceType = source->getType();
4111 ASSERT(sourceType != TextureType::CubeMap);
4112 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004113
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004114 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004115 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004116 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004117 return false;
4118 }
4119
4120 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4121 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004123 context->handleError(InvalidValue()
4124 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004125 return false;
4126 }
4127
4128 if (x < 0 || y < 0)
4129 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004130 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004131 return false;
4132 }
4133
4134 if (width < 0 || height < 0)
4135 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004136 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004137 return false;
4138 }
4139
Geoff Lang4f0e0032017-05-01 16:04:35 -04004140 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4141 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004142 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004143 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004144 return false;
4145 }
4146
Geoff Lang4f0e0032017-05-01 16:04:35 -04004147 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4148 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004149 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004150 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004151 return false;
4152 }
4153
Geoff Lang63458a32017-10-30 15:16:53 -04004154 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4155 {
4156 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4157 return false;
4158 }
4159
Geoff Lang4f0e0032017-05-01 16:04:35 -04004160 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004161 if (dest == nullptr)
4162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004163 context->handleError(InvalidValue()
4164 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004165 return false;
4166 }
4167
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004168 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004169 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004170 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004171 return false;
4172 }
4173
Brandon Jones28783792018-03-05 09:37:32 -08004174 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4175 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004176 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004177 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004178 return false;
4179 }
4180
Geoff Lang4f0e0032017-05-01 16:04:35 -04004181 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4182 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004183 context
4184 ->handleError(InvalidOperation()
4185 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004186 return false;
4187 }
4188
4189 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4190 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004191 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004192 context->handleError(InvalidOperation()
4193 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004194 return false;
4195 }
4196
4197 if (xoffset < 0 || yoffset < 0)
4198 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004199 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004200 return false;
4201 }
4202
Geoff Lang4f0e0032017-05-01 16:04:35 -04004203 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4204 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004206 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004207 return false;
4208 }
4209
4210 return true;
4211}
4212
Geoff Lang47110bf2016-04-20 11:13:22 -07004213bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4214{
4215 if (!context->getExtensions().copyCompressedTexture)
4216 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004217 context->handleError(InvalidOperation()
4218 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004219 return false;
4220 }
4221
4222 const gl::Texture *source = context->getTexture(sourceId);
4223 if (source == nullptr)
4224 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004225 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004226 return false;
4227 }
4228
Corentin Wallez99d492c2018-02-27 15:17:10 -05004229 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004230 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004231 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004232 return false;
4233 }
4234
Corentin Wallez99d492c2018-02-27 15:17:10 -05004235 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4236 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004237 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004238 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004239 return false;
4240 }
4241
Corentin Wallez99d492c2018-02-27 15:17:10 -05004242 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004243 if (!sourceFormat.info->compressed)
4244 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004245 context->handleError(InvalidOperation()
4246 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004247 return false;
4248 }
4249
4250 const gl::Texture *dest = context->getTexture(destId);
4251 if (dest == nullptr)
4252 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004253 context->handleError(InvalidValue()
4254 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004255 return false;
4256 }
4257
Corentin Wallez99d492c2018-02-27 15:17:10 -05004258 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004259 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004260 context->handleError(InvalidValue()
4261 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004262 return false;
4263 }
4264
4265 if (dest->getImmutableFormat())
4266 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004267 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004268 return false;
4269 }
4270
4271 return true;
4272}
4273
Jiawei Shao385b3e02018-03-21 09:43:28 +08004274bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004275{
4276 switch (type)
4277 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004278 case ShaderType::Vertex:
4279 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004280 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004281
Jiawei Shao385b3e02018-03-21 09:43:28 +08004282 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004283 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004284 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004285 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004286 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004287 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004288 break;
4289
Jiawei Shao385b3e02018-03-21 09:43:28 +08004290 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004291 if (!context->getExtensions().geometryShader)
4292 {
4293 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4294 return false;
4295 }
4296 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004297 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004298 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004299 return false;
4300 }
Jamie Madill29639852016-09-02 15:00:09 -04004301
4302 return true;
4303}
4304
Jamie Madill5b772312018-03-08 20:28:32 -05004305bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004306 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004307 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004308 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004309 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004310{
4311 if (size < 0)
4312 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004313 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004314 return false;
4315 }
4316
4317 switch (usage)
4318 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004319 case BufferUsage::StreamDraw:
4320 case BufferUsage::StaticDraw:
4321 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004322 break;
4323
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004324 case BufferUsage::StreamRead:
4325 case BufferUsage::StaticRead:
4326 case BufferUsage::DynamicRead:
4327 case BufferUsage::StreamCopy:
4328 case BufferUsage::StaticCopy:
4329 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004330 if (context->getClientMajorVersion() < 3)
4331 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004332 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004333 return false;
4334 }
4335 break;
4336
4337 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004338 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004339 return false;
4340 }
4341
Corentin Walleze4477002017-12-01 14:39:58 -05004342 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004343 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004344 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004345 return false;
4346 }
4347
4348 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4349
4350 if (!buffer)
4351 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004352 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004353 return false;
4354 }
4355
James Darpiniane8a93c62018-01-04 18:02:24 -08004356 if (context->getExtensions().webglCompatibility &&
4357 buffer->isBoundForTransformFeedbackAndOtherUse())
4358 {
4359 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4360 return false;
4361 }
4362
Jamie Madill29639852016-09-02 15:00:09 -04004363 return true;
4364}
4365
Jamie Madill5b772312018-03-08 20:28:32 -05004366bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004367 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004368 GLintptr offset,
4369 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004370 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004371{
Brandon Jones6cad5662017-06-14 13:25:13 -07004372 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004373 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004374 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4375 return false;
4376 }
4377
4378 if (offset < 0)
4379 {
4380 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004381 return false;
4382 }
4383
Corentin Walleze4477002017-12-01 14:39:58 -05004384 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004385 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004386 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004387 return false;
4388 }
4389
4390 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4391
4392 if (!buffer)
4393 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004394 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004395 return false;
4396 }
4397
4398 if (buffer->isMapped())
4399 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004400 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004401 return false;
4402 }
4403
James Darpiniane8a93c62018-01-04 18:02:24 -08004404 if (context->getExtensions().webglCompatibility &&
4405 buffer->isBoundForTransformFeedbackAndOtherUse())
4406 {
4407 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4408 return false;
4409 }
4410
Jamie Madill29639852016-09-02 15:00:09 -04004411 // Check for possible overflow of size + offset
4412 angle::CheckedNumeric<size_t> checkedSize(size);
4413 checkedSize += offset;
4414 if (!checkedSize.IsValid())
4415 {
Jamie Madill526392d2018-11-16 09:35:14 -05004416 context->handleError(InvalidValue());
Jamie Madill29639852016-09-02 15:00:09 -04004417 return false;
4418 }
4419
4420 if (size + offset > buffer->getSize())
4421 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004422 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004423 return false;
4424 }
4425
Martin Radev4c4c8e72016-08-04 12:25:34 +03004426 return true;
4427}
4428
Geoff Lang111a99e2017-10-17 10:58:41 -04004429bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004430{
Geoff Langc339c4e2016-11-29 10:37:36 -05004431 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004432 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004433 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004434 return false;
4435 }
4436
Geoff Lang111a99e2017-10-17 10:58:41 -04004437 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004439 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004440 return false;
4441 }
4442
4443 return true;
4444}
4445
Jamie Madill5b772312018-03-08 20:28:32 -05004446bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004447{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004448 if (context->getClientMajorVersion() < 2)
4449 {
4450 return ValidateMultitextureUnit(context, texture);
4451 }
4452
Jamie Madillef300b12016-10-07 15:12:09 -04004453 if (texture < GL_TEXTURE0 ||
4454 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4455 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004456 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004457 return false;
4458 }
4459
4460 return true;
4461}
4462
Jamie Madill5b772312018-03-08 20:28:32 -05004463bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004464{
4465 Program *programObject = GetValidProgram(context, program);
4466 if (!programObject)
4467 {
4468 return false;
4469 }
4470
4471 Shader *shaderObject = GetValidShader(context, shader);
4472 if (!shaderObject)
4473 {
4474 return false;
4475 }
4476
Jiawei Shao385b3e02018-03-21 09:43:28 +08004477 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004478 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004479 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4480 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004481 }
4482
4483 return true;
4484}
4485
Jamie Madill5b772312018-03-08 20:28:32 -05004486bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004487{
4488 if (index >= MAX_VERTEX_ATTRIBS)
4489 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004490 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004491 return false;
4492 }
4493
4494 if (strncmp(name, "gl_", 3) == 0)
4495 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004496 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004497 return false;
4498 }
4499
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004500 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004501 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004502 const size_t length = strlen(name);
4503
4504 if (!IsValidESSLString(name, length))
4505 {
4506 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4507 // for shader-related entry points
4508 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4509 return false;
4510 }
4511
4512 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4513 {
4514 return false;
4515 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004516 }
4517
Jamie Madill01a80ee2016-11-07 12:06:18 -05004518 return GetValidProgram(context, program) != nullptr;
4519}
4520
Jamie Madill5b772312018-03-08 20:28:32 -05004521bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004522{
Geoff Lange8afa902017-09-27 15:00:43 -04004523 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004524 {
Jamie Madilla139f012018-10-10 16:13:03 -04004525 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004526 return false;
4527 }
4528
4529 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4530 !context->isFramebufferGenerated(framebuffer))
4531 {
Jamie Madilla139f012018-10-10 16:13:03 -04004532 context->validationError(GL_INVALID_OPERATION, kErrorObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004533 return false;
4534 }
4535
4536 return true;
4537}
4538
Jamie Madill5b772312018-03-08 20:28:32 -05004539bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004540{
4541 if (target != GL_RENDERBUFFER)
4542 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004543 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004544 return false;
4545 }
4546
4547 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4548 !context->isRenderbufferGenerated(renderbuffer))
4549 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004550 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004551 return false;
4552 }
4553
4554 return true;
4555}
4556
Jamie Madill5b772312018-03-08 20:28:32 -05004557static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004558{
4559 switch (mode)
4560 {
4561 case GL_FUNC_ADD:
4562 case GL_FUNC_SUBTRACT:
4563 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004564 return true;
4565
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004566 case GL_MIN:
4567 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004568 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004569
4570 default:
4571 return false;
4572 }
4573}
4574
Jamie Madill5b772312018-03-08 20:28:32 -05004575bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004576{
4577 return true;
4578}
4579
Jamie Madill5b772312018-03-08 20:28:32 -05004580bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004581{
Geoff Lang50cac572017-09-26 17:37:43 -04004582 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004583 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004584 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004585 return false;
4586 }
4587
4588 return true;
4589}
4590
Jamie Madill5b772312018-03-08 20:28:32 -05004591bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004592{
Geoff Lang50cac572017-09-26 17:37:43 -04004593 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004594 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004595 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004596 return false;
4597 }
4598
Geoff Lang50cac572017-09-26 17:37:43 -04004599 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004600 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004602 return false;
4603 }
4604
4605 return true;
4606}
4607
Jamie Madill5b772312018-03-08 20:28:32 -05004608bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004609{
4610 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4611}
4612
Jamie Madill5b772312018-03-08 20:28:32 -05004613bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004614 GLenum srcRGB,
4615 GLenum dstRGB,
4616 GLenum srcAlpha,
4617 GLenum dstAlpha)
4618{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004619 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004620 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004621 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004622 return false;
4623 }
4624
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004625 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004626 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004627 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004628 return false;
4629 }
4630
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004631 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004632 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004633 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004634 return false;
4635 }
4636
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004637 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004638 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004639 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004640 return false;
4641 }
4642
Frank Henigman146e8a12017-03-02 23:22:37 -05004643 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4644 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004645 {
4646 bool constantColorUsed =
4647 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4648 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4649
4650 bool constantAlphaUsed =
4651 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4652 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4653
4654 if (constantColorUsed && constantAlphaUsed)
4655 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004656 const char *msg;
4657 if (context->getExtensions().webglCompatibility)
4658 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004659 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004660 }
4661 else
4662 {
4663 msg =
4664 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4665 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4666 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004667 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004668 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004669 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004670 return false;
4671 }
4672 }
4673
4674 return true;
4675}
4676
Geoff Langc339c4e2016-11-29 10:37:36 -05004677bool ValidateGetString(Context *context, GLenum name)
4678{
4679 switch (name)
4680 {
4681 case GL_VENDOR:
4682 case GL_RENDERER:
4683 case GL_VERSION:
4684 case GL_SHADING_LANGUAGE_VERSION:
4685 case GL_EXTENSIONS:
4686 break;
4687
4688 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4689 if (!context->getExtensions().requestExtension)
4690 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004691 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004692 return false;
4693 }
4694 break;
4695
4696 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004697 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004698 return false;
4699 }
4700
4701 return true;
4702}
4703
Jamie Madill5b772312018-03-08 20:28:32 -05004704bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004705{
4706 if (width <= 0.0f || isNaN(width))
4707 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004708 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004709 return false;
4710 }
4711
4712 return true;
4713}
4714
Jamie Madill5b772312018-03-08 20:28:32 -05004715bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004716 GLuint index,
4717 GLint size,
4718 GLenum type,
4719 GLboolean normalized,
4720 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004721 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004722{
Shao80957d92017-02-20 21:25:59 +08004723 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004724 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004725 return false;
4726 }
4727
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004728 if (stride < 0)
4729 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004730 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004731 return false;
4732 }
4733
Shao80957d92017-02-20 21:25:59 +08004734 const Caps &caps = context->getCaps();
4735 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004736 {
Shao80957d92017-02-20 21:25:59 +08004737 if (stride > caps.maxVertexAttribStride)
4738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004739 context->handleError(InvalidValue()
4740 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004741 return false;
4742 }
4743
4744 if (index >= caps.maxVertexAttribBindings)
4745 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004746 context->handleError(InvalidValue()
4747 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004748 return false;
4749 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004750 }
4751
4752 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4753 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4754 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4755 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004756 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4757 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004758 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4759 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004760 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004761 context
4762 ->handleError(InvalidOperation()
4763 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004764 return false;
4765 }
4766
4767 if (context->getExtensions().webglCompatibility)
4768 {
4769 // WebGL 1.0 [Section 6.14] Fixed point support
4770 // The WebGL API does not support the GL_FIXED data type.
4771 if (type == GL_FIXED)
4772 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004773 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004774 return false;
4775 }
4776
Geoff Lang2d62ab72017-03-23 16:54:40 -04004777 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004778 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004779 return false;
4780 }
4781 }
4782
4783 return true;
4784}
4785
Jamie Madill5b772312018-03-08 20:28:32 -05004786bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004787{
4788 if (context->getExtensions().webglCompatibility && zNear > zFar)
4789 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004790 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004791 return false;
4792 }
4793
4794 return true;
4795}
4796
Jamie Madill5b772312018-03-08 20:28:32 -05004797bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004798 GLenum target,
4799 GLenum internalformat,
4800 GLsizei width,
4801 GLsizei height)
4802{
4803 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4804 height);
4805}
4806
Jamie Madill5b772312018-03-08 20:28:32 -05004807bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004808 GLenum target,
4809 GLsizei samples,
4810 GLenum internalformat,
4811 GLsizei width,
4812 GLsizei height)
4813{
4814 if (!context->getExtensions().framebufferMultisample)
4815 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004816 context->handleError(InvalidOperation()
4817 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004818 return false;
4819 }
4820
4821 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4822 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4823 // generated.
4824 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4825 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004826 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004827 return false;
4828 }
4829
4830 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4831 // the specified storage. This is different than ES 3.0 in which a sample number higher
4832 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4833 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4834 if (context->getClientMajorVersion() >= 3)
4835 {
4836 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4837 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4838 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004839 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004840 return false;
4841 }
4842 }
4843
4844 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4845 width, height);
4846}
4847
Jamie Madill5b772312018-03-08 20:28:32 -05004848bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004849{
Geoff Lange8afa902017-09-27 15:00:43 -04004850 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004851 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004852 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004853 return false;
4854 }
4855
4856 return true;
4857}
4858
Jamie Madill5b772312018-03-08 20:28:32 -05004859bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004860{
4861 return true;
4862}
4863
Jamie Madill5b772312018-03-08 20:28:32 -05004864bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004865{
4866 return true;
4867}
4868
Jamie Madill5b772312018-03-08 20:28:32 -05004869bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004870{
4871 return true;
4872}
4873
Jamie Madill5b772312018-03-08 20:28:32 -05004874bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004875 GLboolean red,
4876 GLboolean green,
4877 GLboolean blue,
4878 GLboolean alpha)
4879{
4880 return true;
4881}
4882
Jamie Madill5b772312018-03-08 20:28:32 -05004883bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004884{
4885 return true;
4886}
4887
Jamie Madill5b772312018-03-08 20:28:32 -05004888bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004889{
4890 return true;
4891}
4892
Jamie Madill5b772312018-03-08 20:28:32 -05004893bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894{
4895 switch (mode)
4896 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004897 case CullFaceMode::Front:
4898 case CullFaceMode::Back:
4899 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004900 break;
4901
4902 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004903 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004904 return false;
4905 }
4906
4907 return true;
4908}
4909
Jamie Madill5b772312018-03-08 20:28:32 -05004910bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004911{
4912 if (program == 0)
4913 {
4914 return false;
4915 }
4916
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004917 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004918 {
4919 if (context->getShader(program))
4920 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004921 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004922 return false;
4923 }
4924 else
4925 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004926 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004927 return false;
4928 }
4929 }
4930
4931 return true;
4932}
4933
Jamie Madill5b772312018-03-08 20:28:32 -05004934bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004935{
4936 if (shader == 0)
4937 {
4938 return false;
4939 }
4940
4941 if (!context->getShader(shader))
4942 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004943 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004944 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004945 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004946 return false;
4947 }
4948 else
4949 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004950 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004951 return false;
4952 }
4953 }
4954
4955 return true;
4956}
4957
Jamie Madill5b772312018-03-08 20:28:32 -05004958bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004959{
4960 switch (func)
4961 {
4962 case GL_NEVER:
4963 case GL_ALWAYS:
4964 case GL_LESS:
4965 case GL_LEQUAL:
4966 case GL_EQUAL:
4967 case GL_GREATER:
4968 case GL_GEQUAL:
4969 case GL_NOTEQUAL:
4970 break;
4971
4972 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004973 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004974 return false;
4975 }
4976
4977 return true;
4978}
4979
Jamie Madill5b772312018-03-08 20:28:32 -05004980bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004981{
4982 return true;
4983}
4984
Jamie Madill5b772312018-03-08 20:28:32 -05004985bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004986{
4987 Program *programObject = GetValidProgram(context, program);
4988 if (!programObject)
4989 {
4990 return false;
4991 }
4992
4993 Shader *shaderObject = GetValidShader(context, shader);
4994 if (!shaderObject)
4995 {
4996 return false;
4997 }
4998
Jiawei Shao385b3e02018-03-21 09:43:28 +08004999 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005000 if (attachedShader != shaderObject)
5001 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005002 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005003 return false;
5004 }
5005
5006 return true;
5007}
5008
Jamie Madill5b772312018-03-08 20:28:32 -05005009bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005010{
5011 if (index >= MAX_VERTEX_ATTRIBS)
5012 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005013 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005014 return false;
5015 }
5016
5017 return true;
5018}
5019
Jamie Madill5b772312018-03-08 20:28:32 -05005020bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005021{
5022 if (index >= MAX_VERTEX_ATTRIBS)
5023 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005024 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005025 return false;
5026 }
5027
5028 return true;
5029}
5030
Jamie Madill5b772312018-03-08 20:28:32 -05005031bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005032{
5033 return true;
5034}
5035
Jamie Madill5b772312018-03-08 20:28:32 -05005036bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005037{
5038 return true;
5039}
5040
Jamie Madill5b772312018-03-08 20:28:32 -05005041bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005042{
5043 switch (mode)
5044 {
5045 case GL_CW:
5046 case GL_CCW:
5047 break;
5048 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005049 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005050 return false;
5051 }
5052
5053 return true;
5054}
5055
Jamie Madill5b772312018-03-08 20:28:32 -05005056bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005057 GLuint program,
5058 GLuint index,
5059 GLsizei bufsize,
5060 GLsizei *length,
5061 GLint *size,
5062 GLenum *type,
5063 GLchar *name)
5064{
5065 if (bufsize < 0)
5066 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005067 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005068 return false;
5069 }
5070
5071 Program *programObject = GetValidProgram(context, program);
5072
5073 if (!programObject)
5074 {
5075 return false;
5076 }
5077
5078 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5079 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005080 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005081 return false;
5082 }
5083
5084 return true;
5085}
5086
Jamie Madill5b772312018-03-08 20:28:32 -05005087bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005088 GLuint program,
5089 GLuint index,
5090 GLsizei bufsize,
5091 GLsizei *length,
5092 GLint *size,
5093 GLenum *type,
5094 GLchar *name)
5095{
5096 if (bufsize < 0)
5097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005098 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005099 return false;
5100 }
5101
5102 Program *programObject = GetValidProgram(context, program);
5103
5104 if (!programObject)
5105 {
5106 return false;
5107 }
5108
5109 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5110 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005111 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005112 return false;
5113 }
5114
5115 return true;
5116}
5117
Jamie Madill5b772312018-03-08 20:28:32 -05005118bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005119 GLuint program,
5120 GLsizei maxcount,
5121 GLsizei *count,
5122 GLuint *shaders)
5123{
5124 if (maxcount < 0)
5125 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005126 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005127 return false;
5128 }
5129
5130 Program *programObject = GetValidProgram(context, program);
5131
5132 if (!programObject)
5133 {
5134 return false;
5135 }
5136
5137 return true;
5138}
5139
Jamie Madill5b772312018-03-08 20:28:32 -05005140bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005141{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005142 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5143 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005144 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005145 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005146 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005147 return false;
5148 }
5149
Jamie Madillc1d770e2017-04-13 17:31:24 -04005150 Program *programObject = GetValidProgram(context, program);
5151
5152 if (!programObject)
5153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005155 return false;
5156 }
5157
5158 if (!programObject->isLinked())
5159 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005160 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161 return false;
5162 }
5163
5164 return true;
5165}
5166
Jamie Madill5b772312018-03-08 20:28:32 -05005167bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005168{
5169 GLenum nativeType;
5170 unsigned int numParams = 0;
5171 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5172}
5173
Jamie Madill5b772312018-03-08 20:28:32 -05005174bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005175{
5176 return true;
5177}
5178
Jamie Madill5b772312018-03-08 20:28:32 -05005179bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005180{
5181 GLenum nativeType;
5182 unsigned int numParams = 0;
5183 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5184}
5185
Jamie Madill5b772312018-03-08 20:28:32 -05005186bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005187{
5188 GLenum nativeType;
5189 unsigned int numParams = 0;
5190 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5191}
5192
Jamie Madill5b772312018-03-08 20:28:32 -05005193bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005194 GLuint program,
5195 GLsizei bufsize,
5196 GLsizei *length,
5197 GLchar *infolog)
5198{
5199 if (bufsize < 0)
5200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005201 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005202 return false;
5203 }
5204
5205 Program *programObject = GetValidProgram(context, program);
5206 if (!programObject)
5207 {
5208 return false;
5209 }
5210
5211 return true;
5212}
5213
Jamie Madill5b772312018-03-08 20:28:32 -05005214bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005215 GLuint shader,
5216 GLsizei bufsize,
5217 GLsizei *length,
5218 GLchar *infolog)
5219{
5220 if (bufsize < 0)
5221 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005222 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005223 return false;
5224 }
5225
5226 Shader *shaderObject = GetValidShader(context, shader);
5227 if (!shaderObject)
5228 {
5229 return false;
5230 }
5231
5232 return true;
5233}
5234
Jamie Madill5b772312018-03-08 20:28:32 -05005235bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005236 GLenum shadertype,
5237 GLenum precisiontype,
5238 GLint *range,
5239 GLint *precision)
5240{
5241 switch (shadertype)
5242 {
5243 case GL_VERTEX_SHADER:
5244 case GL_FRAGMENT_SHADER:
5245 break;
5246 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005247 context->handleError(InvalidOperation()
5248 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005249 return false;
5250 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005251 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005252 return false;
5253 }
5254
5255 switch (precisiontype)
5256 {
5257 case GL_LOW_FLOAT:
5258 case GL_MEDIUM_FLOAT:
5259 case GL_HIGH_FLOAT:
5260 case GL_LOW_INT:
5261 case GL_MEDIUM_INT:
5262 case GL_HIGH_INT:
5263 break;
5264
5265 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005266 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005267 return false;
5268 }
5269
5270 return true;
5271}
5272
Jamie Madill5b772312018-03-08 20:28:32 -05005273bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005274 GLuint shader,
5275 GLsizei bufsize,
5276 GLsizei *length,
5277 GLchar *source)
5278{
5279 if (bufsize < 0)
5280 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005281 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005282 return false;
5283 }
5284
5285 Shader *shaderObject = GetValidShader(context, shader);
5286 if (!shaderObject)
5287 {
5288 return false;
5289 }
5290
5291 return true;
5292}
5293
Jamie Madill5b772312018-03-08 20:28:32 -05005294bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005295{
5296 if (strstr(name, "gl_") == name)
5297 {
5298 return false;
5299 }
5300
Geoff Langfc32e8b2017-05-31 14:16:59 -04005301 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5302 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005303 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005304 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005305 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005306 return false;
5307 }
5308
Jamie Madillc1d770e2017-04-13 17:31:24 -04005309 Program *programObject = GetValidProgram(context, program);
5310
5311 if (!programObject)
5312 {
5313 return false;
5314 }
5315
5316 if (!programObject->isLinked())
5317 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005318 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005319 return false;
5320 }
5321
5322 return true;
5323}
5324
Jamie Madill5b772312018-03-08 20:28:32 -05005325bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005326{
5327 switch (mode)
5328 {
5329 case GL_FASTEST:
5330 case GL_NICEST:
5331 case GL_DONT_CARE:
5332 break;
5333
5334 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005335 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005336 return false;
5337 }
5338
5339 switch (target)
5340 {
5341 case GL_GENERATE_MIPMAP_HINT:
5342 break;
5343
Geoff Lange7bd2182017-06-16 16:13:13 -04005344 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5345 if (context->getClientVersion() < ES_3_0 &&
5346 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005348 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005349 return false;
5350 }
5351 break;
5352
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005353 case GL_PERSPECTIVE_CORRECTION_HINT:
5354 case GL_POINT_SMOOTH_HINT:
5355 case GL_LINE_SMOOTH_HINT:
5356 case GL_FOG_HINT:
5357 if (context->getClientMajorVersion() >= 2)
5358 {
5359 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5360 return false;
5361 }
5362 break;
5363
Jamie Madillc1d770e2017-04-13 17:31:24 -04005364 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005365 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005366 return false;
5367 }
5368
5369 return true;
5370}
5371
Jamie Madill5b772312018-03-08 20:28:32 -05005372bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005373{
5374 return true;
5375}
5376
Jamie Madill5b772312018-03-08 20:28:32 -05005377bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378{
5379 return true;
5380}
5381
Jamie Madill5b772312018-03-08 20:28:32 -05005382bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005383{
5384 return true;
5385}
5386
Jamie Madill5b772312018-03-08 20:28:32 -05005387bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005388{
5389 return true;
5390}
5391
Jamie Madill5b772312018-03-08 20:28:32 -05005392bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005393{
5394 return true;
5395}
5396
Jamie Madill5b772312018-03-08 20:28:32 -05005397bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005398{
5399 return true;
5400}
5401
Jamie Madill5b772312018-03-08 20:28:32 -05005402bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005403{
5404 if (context->getClientMajorVersion() < 3)
5405 {
5406 switch (pname)
5407 {
5408 case GL_UNPACK_IMAGE_HEIGHT:
5409 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005410 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005411 return false;
5412
5413 case GL_UNPACK_ROW_LENGTH:
5414 case GL_UNPACK_SKIP_ROWS:
5415 case GL_UNPACK_SKIP_PIXELS:
5416 if (!context->getExtensions().unpackSubimage)
5417 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005418 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005419 return false;
5420 }
5421 break;
5422
5423 case GL_PACK_ROW_LENGTH:
5424 case GL_PACK_SKIP_ROWS:
5425 case GL_PACK_SKIP_PIXELS:
5426 if (!context->getExtensions().packSubimage)
5427 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005428 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005429 return false;
5430 }
5431 break;
5432 }
5433 }
5434
5435 if (param < 0)
5436 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005437 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005438 return false;
5439 }
5440
5441 switch (pname)
5442 {
5443 case GL_UNPACK_ALIGNMENT:
5444 if (param != 1 && param != 2 && param != 4 && param != 8)
5445 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005446 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005447 return false;
5448 }
5449 break;
5450
5451 case GL_PACK_ALIGNMENT:
5452 if (param != 1 && param != 2 && param != 4 && param != 8)
5453 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005454 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005455 return false;
5456 }
5457 break;
5458
5459 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005460 if (!context->getExtensions().packReverseRowOrder)
5461 {
5462 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5463 }
5464 break;
5465
Jamie Madillc1d770e2017-04-13 17:31:24 -04005466 case GL_UNPACK_ROW_LENGTH:
5467 case GL_UNPACK_IMAGE_HEIGHT:
5468 case GL_UNPACK_SKIP_IMAGES:
5469 case GL_UNPACK_SKIP_ROWS:
5470 case GL_UNPACK_SKIP_PIXELS:
5471 case GL_PACK_ROW_LENGTH:
5472 case GL_PACK_SKIP_ROWS:
5473 case GL_PACK_SKIP_PIXELS:
5474 break;
5475
5476 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005477 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005478 return false;
5479 }
5480
5481 return true;
5482}
5483
Jamie Madill5b772312018-03-08 20:28:32 -05005484bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485{
5486 return true;
5487}
5488
Jamie Madill5b772312018-03-08 20:28:32 -05005489bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005490{
5491 return true;
5492}
5493
Jamie Madill5b772312018-03-08 20:28:32 -05005494bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005495{
5496 return true;
5497}
5498
Jamie Madill5b772312018-03-08 20:28:32 -05005499bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005500{
5501 if (width < 0 || height < 0)
5502 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005503 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005504 return false;
5505 }
5506
5507 return true;
5508}
5509
Jamie Madill5b772312018-03-08 20:28:32 -05005510bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005511 GLsizei n,
5512 const GLuint *shaders,
5513 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005514 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005515 GLsizei length)
5516{
5517 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5518 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5519 shaderBinaryFormats.end())
5520 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005521 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005522 return false;
5523 }
5524
5525 return true;
5526}
5527
Jamie Madill5b772312018-03-08 20:28:32 -05005528bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005529 GLuint shader,
5530 GLsizei count,
5531 const GLchar *const *string,
5532 const GLint *length)
5533{
5534 if (count < 0)
5535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005536 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005537 return false;
5538 }
5539
Geoff Langfc32e8b2017-05-31 14:16:59 -04005540 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5541 // shader-related entry points
5542 if (context->getExtensions().webglCompatibility)
5543 {
5544 for (GLsizei i = 0; i < count; i++)
5545 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005546 size_t len =
5547 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005548
5549 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005550 if (!IsValidESSLShaderSourceString(string[i], len,
5551 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005553 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005554 return false;
5555 }
5556 }
5557 }
5558
Jamie Madillc1d770e2017-04-13 17:31:24 -04005559 Shader *shaderObject = GetValidShader(context, shader);
5560 if (!shaderObject)
5561 {
5562 return false;
5563 }
5564
5565 return true;
5566}
5567
Jamie Madill5b772312018-03-08 20:28:32 -05005568bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005569{
5570 if (!IsValidStencilFunc(func))
5571 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005572 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005573 return false;
5574 }
5575
5576 return true;
5577}
5578
Jamie Madill5b772312018-03-08 20:28:32 -05005579bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580{
5581 if (!IsValidStencilFace(face))
5582 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005583 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005584 return false;
5585 }
5586
5587 if (!IsValidStencilFunc(func))
5588 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005589 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005590 return false;
5591 }
5592
5593 return true;
5594}
5595
Jamie Madill5b772312018-03-08 20:28:32 -05005596bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005597{
5598 return true;
5599}
5600
Jamie Madill5b772312018-03-08 20:28:32 -05005601bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602{
5603 if (!IsValidStencilFace(face))
5604 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005605 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005606 return false;
5607 }
5608
5609 return true;
5610}
5611
Jamie Madill5b772312018-03-08 20:28:32 -05005612bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005613{
5614 if (!IsValidStencilOp(fail))
5615 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005616 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005617 return false;
5618 }
5619
5620 if (!IsValidStencilOp(zfail))
5621 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005622 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005623 return false;
5624 }
5625
5626 if (!IsValidStencilOp(zpass))
5627 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005628 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629 return false;
5630 }
5631
5632 return true;
5633}
5634
Jamie Madill5b772312018-03-08 20:28:32 -05005635bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005636 GLenum face,
5637 GLenum fail,
5638 GLenum zfail,
5639 GLenum zpass)
5640{
5641 if (!IsValidStencilFace(face))
5642 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005643 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005644 return false;
5645 }
5646
5647 return ValidateStencilOp(context, fail, zfail, zpass);
5648}
5649
Jamie Madill5b772312018-03-08 20:28:32 -05005650bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005651{
5652 return ValidateUniform(context, GL_FLOAT, location, 1);
5653}
5654
Jamie Madill5b772312018-03-08 20:28:32 -05005655bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005656{
5657 return ValidateUniform(context, GL_FLOAT, location, count);
5658}
5659
Jamie Madill5b772312018-03-08 20:28:32 -05005660bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005661{
5662 return ValidateUniform1iv(context, location, 1, &x);
5663}
5664
Jamie Madill5b772312018-03-08 20:28:32 -05005665bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005666{
5667 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5668}
5669
Jamie Madill5b772312018-03-08 20:28:32 -05005670bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005671{
5672 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5673}
5674
Jamie Madill5b772312018-03-08 20:28:32 -05005675bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005676{
5677 return ValidateUniform(context, GL_INT_VEC2, location, count);
5678}
5679
Jamie Madill5b772312018-03-08 20:28:32 -05005680bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005681{
5682 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5683}
5684
Jamie Madill5b772312018-03-08 20:28:32 -05005685bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005686{
5687 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5688}
5689
Jamie Madill5b772312018-03-08 20:28:32 -05005690bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005691{
5692 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5693}
5694
Jamie Madill5b772312018-03-08 20:28:32 -05005695bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005696{
5697 return ValidateUniform(context, GL_INT_VEC3, location, count);
5698}
5699
Jamie Madill5b772312018-03-08 20:28:32 -05005700bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005701{
5702 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5703}
5704
Jamie Madill5b772312018-03-08 20:28:32 -05005705bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005706{
5707 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5708}
5709
Jamie Madill5b772312018-03-08 20:28:32 -05005710bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005711{
5712 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5713}
5714
Jamie Madill5b772312018-03-08 20:28:32 -05005715bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005716{
5717 return ValidateUniform(context, GL_INT_VEC4, location, count);
5718}
5719
Jamie Madill5b772312018-03-08 20:28:32 -05005720bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005721 GLint location,
5722 GLsizei count,
5723 GLboolean transpose,
5724 const GLfloat *value)
5725{
5726 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5727}
5728
Jamie Madill5b772312018-03-08 20:28:32 -05005729bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005730 GLint location,
5731 GLsizei count,
5732 GLboolean transpose,
5733 const GLfloat *value)
5734{
5735 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5736}
5737
Jamie Madill5b772312018-03-08 20:28:32 -05005738bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005739 GLint location,
5740 GLsizei count,
5741 GLboolean transpose,
5742 const GLfloat *value)
5743{
5744 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5745}
5746
Jamie Madill5b772312018-03-08 20:28:32 -05005747bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005748{
5749 Program *programObject = GetValidProgram(context, program);
5750
5751 if (!programObject)
5752 {
5753 return false;
5754 }
5755
5756 return true;
5757}
5758
Jamie Madill5b772312018-03-08 20:28:32 -05005759bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005760{
5761 return ValidateVertexAttribIndex(context, index);
5762}
5763
Jamie Madill5b772312018-03-08 20:28:32 -05005764bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005765{
5766 return ValidateVertexAttribIndex(context, index);
5767}
5768
Jamie Madill5b772312018-03-08 20:28:32 -05005769bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005770{
5771 return ValidateVertexAttribIndex(context, index);
5772}
5773
Jamie Madill5b772312018-03-08 20:28:32 -05005774bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005775{
5776 return ValidateVertexAttribIndex(context, index);
5777}
5778
Jamie Madill5b772312018-03-08 20:28:32 -05005779bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005780{
5781 return ValidateVertexAttribIndex(context, index);
5782}
5783
Jamie Madill5b772312018-03-08 20:28:32 -05005784bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005785{
5786 return ValidateVertexAttribIndex(context, index);
5787}
5788
Jamie Madill5b772312018-03-08 20:28:32 -05005789bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005790 GLuint index,
5791 GLfloat x,
5792 GLfloat y,
5793 GLfloat z,
5794 GLfloat w)
5795{
5796 return ValidateVertexAttribIndex(context, index);
5797}
5798
Jamie Madill5b772312018-03-08 20:28:32 -05005799bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005800{
5801 return ValidateVertexAttribIndex(context, index);
5802}
5803
Jamie Madill5b772312018-03-08 20:28:32 -05005804bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005805{
5806 if (width < 0 || height < 0)
5807 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005808 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005809 return false;
5810 }
5811
5812 return true;
5813}
5814
Jamie Madill5b772312018-03-08 20:28:32 -05005815bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005816 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005817 GLsizei count,
5818 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005819 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005820{
5821 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5822}
5823
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005824bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005825 GLenum target,
5826 GLenum attachment,
5827 GLenum pname,
5828 GLint *params)
5829{
5830 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5831 nullptr);
5832}
5833
Jamie Madill5b772312018-03-08 20:28:32 -05005834bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005835{
5836 return ValidateGetProgramivBase(context, program, pname, nullptr);
5837}
5838
Jamie Madill5b772312018-03-08 20:28:32 -05005839bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005840 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005841 GLint level,
5842 GLenum internalformat,
5843 GLint x,
5844 GLint y,
5845 GLsizei width,
5846 GLsizei height,
5847 GLint border)
5848{
5849 if (context->getClientMajorVersion() < 3)
5850 {
5851 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5852 0, x, y, width, height, border);
5853 }
5854
5855 ASSERT(context->getClientMajorVersion() == 3);
5856 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5857 0, x, y, width, height, border);
5858}
5859
5860bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005861 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005862 GLint level,
5863 GLint xoffset,
5864 GLint yoffset,
5865 GLint x,
5866 GLint y,
5867 GLsizei width,
5868 GLsizei height)
5869{
5870 if (context->getClientMajorVersion() < 3)
5871 {
5872 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5873 yoffset, x, y, width, height, 0);
5874 }
5875
5876 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5877 yoffset, 0, x, y, width, height, 0);
5878}
5879
5880bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5881{
5882 return ValidateGenOrDelete(context, n);
5883}
5884
5885bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5886{
5887 return ValidateGenOrDelete(context, n);
5888}
5889
5890bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5891{
5892 return ValidateGenOrDelete(context, n);
5893}
5894
5895bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5896{
5897 return ValidateGenOrDelete(context, n);
5898}
5899
5900bool ValidateDisable(Context *context, GLenum cap)
5901{
5902 if (!ValidCap(context, cap, false))
5903 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005904 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005905 return false;
5906 }
5907
5908 return true;
5909}
5910
5911bool ValidateEnable(Context *context, GLenum cap)
5912{
5913 if (!ValidCap(context, cap, false))
5914 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005915 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005916 return false;
5917 }
5918
5919 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5920 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5921 {
5922 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005923 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005924
5925 // We also output an error message to the debugger window if tracing is active, so that
5926 // developers can see the error message.
5927 ERR() << errorMessage;
5928 return false;
5929 }
5930
5931 return true;
5932}
5933
5934bool ValidateFramebufferRenderbuffer(Context *context,
5935 GLenum target,
5936 GLenum attachment,
5937 GLenum renderbuffertarget,
5938 GLuint renderbuffer)
5939{
Geoff Lange8afa902017-09-27 15:00:43 -04005940 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005941 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005942 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5943 return false;
5944 }
5945
5946 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5947 {
5948 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005949 return false;
5950 }
5951
5952 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5953 renderbuffertarget, renderbuffer);
5954}
5955
5956bool ValidateFramebufferTexture2D(Context *context,
5957 GLenum target,
5958 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005959 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005960 GLuint texture,
5961 GLint level)
5962{
5963 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5964 // extension
5965 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5966 level != 0)
5967 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005968 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005969 return false;
5970 }
5971
5972 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5973 {
5974 return false;
5975 }
5976
5977 if (texture != 0)
5978 {
5979 gl::Texture *tex = context->getTexture(texture);
5980 ASSERT(tex);
5981
5982 const gl::Caps &caps = context->getCaps();
5983
5984 switch (textarget)
5985 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005986 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005987 {
5988 if (level > gl::log2(caps.max2DTextureSize))
5989 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005990 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005991 return false;
5992 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005993 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005994 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005995 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005996 return false;
5997 }
5998 }
5999 break;
6000
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006001 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006002 {
6003 if (level != 0)
6004 {
6005 context->handleError(InvalidValue());
6006 return false;
6007 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006008 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006009 {
6010 context->handleError(InvalidOperation()
6011 << "Textarget must match the texture target type.");
6012 return false;
6013 }
6014 }
6015 break;
6016
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006017 case TextureTarget::CubeMapNegativeX:
6018 case TextureTarget::CubeMapNegativeY:
6019 case TextureTarget::CubeMapNegativeZ:
6020 case TextureTarget::CubeMapPositiveX:
6021 case TextureTarget::CubeMapPositiveY:
6022 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006023 {
6024 if (level > gl::log2(caps.maxCubeMapTextureSize))
6025 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006026 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006027 return false;
6028 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006029 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006030 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006031 context->handleError(InvalidOperation()
6032 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006033 return false;
6034 }
6035 }
6036 break;
6037
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006038 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006039 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006040 if (context->getClientVersion() < ES_3_1 &&
6041 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006043 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
6044 MultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 return false;
6046 }
6047
6048 if (level != 0)
6049 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006050 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006051 return false;
6052 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006053 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006054 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006055 context->handleError(InvalidOperation()
6056 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006057 return false;
6058 }
6059 }
6060 break;
6061
6062 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006063 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006064 return false;
6065 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006066 }
6067
6068 return true;
6069}
6070
6071bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6072{
6073 return ValidateGenOrDelete(context, n);
6074}
6075
6076bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6077{
6078 return ValidateGenOrDelete(context, n);
6079}
6080
6081bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6082{
6083 return ValidateGenOrDelete(context, n);
6084}
6085
6086bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6087{
6088 return ValidateGenOrDelete(context, n);
6089}
6090
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006091bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006092{
6093 if (!ValidTextureTarget(context, target))
6094 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006095 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006096 return false;
6097 }
6098
6099 Texture *texture = context->getTargetTexture(target);
6100
6101 if (texture == nullptr)
6102 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006103 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006104 return false;
6105 }
6106
6107 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6108
6109 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6110 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6111 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6112 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006113 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006114 return false;
6115 }
6116
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006117 TextureTarget baseTarget = (target == TextureType::CubeMap)
6118 ? TextureTarget::CubeMapPositiveX
6119 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006120 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6121 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6122 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006123 {
6124 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6125 return false;
6126 }
6127
Geoff Lang536eca12017-09-13 11:23:35 -04006128 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6129 bool formatUnsized = !format.sized;
6130 bool formatColorRenderableAndFilterable =
6131 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006132 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006133 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006134 {
Geoff Lang536eca12017-09-13 11:23:35 -04006135 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006136 return false;
6137 }
6138
Geoff Lang536eca12017-09-13 11:23:35 -04006139 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6140 // generation
6141 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6142 {
6143 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6144 return false;
6145 }
6146
Jiange2c00842018-07-13 16:50:49 +08006147 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6148 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6149 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006150 {
Geoff Lang536eca12017-09-13 11:23:35 -04006151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006152 return false;
6153 }
6154
6155 // Non-power of 2 ES2 check
6156 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6157 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6158 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6159 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006160 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6161 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006162 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006163 return false;
6164 }
6165
6166 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006167 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006168 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006169 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006170 return false;
6171 }
6172
6173 return true;
6174}
6175
Jamie Madill5b772312018-03-08 20:28:32 -05006176bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006177 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006178 GLenum pname,
6179 GLint *params)
6180{
6181 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6182}
6183
6184bool ValidateGetRenderbufferParameteriv(Context *context,
6185 GLenum target,
6186 GLenum pname,
6187 GLint *params)
6188{
6189 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6190}
6191
6192bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6193{
6194 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6195}
6196
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006197bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006198{
6199 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6200}
6201
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006202bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006203{
6204 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6205}
6206
Till Rathmannb8543632018-10-02 19:46:14 +02006207bool ValidateGetTexParameterIivOES(Context *context,
6208 TextureType target,
6209 GLenum pname,
6210 GLint *params)
6211{
6212 if (context->getClientMajorVersion() < 3)
6213 {
6214 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6215 return false;
6216 }
6217 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6218}
6219
6220bool ValidateGetTexParameterIuivOES(Context *context,
6221 TextureType target,
6222 GLenum pname,
6223 GLuint *params)
6224{
6225 if (context->getClientMajorVersion() < 3)
6226 {
6227 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6228 return false;
6229 }
6230 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6231}
6232
Jamie Madillbe849e42017-05-02 15:49:00 -04006233bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6234{
6235 return ValidateGetUniformBase(context, program, location);
6236}
6237
6238bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6239{
6240 return ValidateGetUniformBase(context, program, location);
6241}
6242
6243bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6244{
6245 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6246}
6247
6248bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6249{
6250 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6251}
6252
6253bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6254{
6255 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6256}
6257
6258bool ValidateIsEnabled(Context *context, GLenum cap)
6259{
6260 if (!ValidCap(context, cap, true))
6261 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006262 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006263 return false;
6264 }
6265
6266 return true;
6267}
6268
6269bool ValidateLinkProgram(Context *context, GLuint program)
6270{
6271 if (context->hasActiveTransformFeedback(program))
6272 {
6273 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006274 context->handleError(InvalidOperation() << "Cannot link program while program is "
6275 "associated with an active transform "
6276 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006277 return false;
6278 }
6279
6280 Program *programObject = GetValidProgram(context, program);
6281 if (!programObject)
6282 {
6283 return false;
6284 }
6285
6286 return true;
6287}
6288
Jamie Madill4928b7c2017-06-20 12:57:39 -04006289bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006290 GLint x,
6291 GLint y,
6292 GLsizei width,
6293 GLsizei height,
6294 GLenum format,
6295 GLenum type,
6296 void *pixels)
6297{
6298 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6299 nullptr, pixels);
6300}
6301
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006302bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006303{
Till Rathmannb8543632018-10-02 19:46:14 +02006304 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006305}
6306
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006307bool ValidateTexParameterfv(Context *context,
6308 TextureType target,
6309 GLenum pname,
6310 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006311{
Till Rathmannb8543632018-10-02 19:46:14 +02006312 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006313}
6314
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006315bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006316{
Till Rathmannb8543632018-10-02 19:46:14 +02006317 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006318}
6319
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006320bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006321{
Till Rathmannb8543632018-10-02 19:46:14 +02006322 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6323}
6324
6325bool ValidateTexParameterIivOES(Context *context,
6326 TextureType target,
6327 GLenum pname,
6328 const GLint *params)
6329{
6330 if (context->getClientMajorVersion() < 3)
6331 {
6332 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6333 return false;
6334 }
6335 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6336}
6337
6338bool ValidateTexParameterIuivOES(Context *context,
6339 TextureType target,
6340 GLenum pname,
6341 const GLuint *params)
6342{
6343 if (context->getClientMajorVersion() < 3)
6344 {
6345 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6346 return false;
6347 }
6348 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006349}
6350
6351bool ValidateUseProgram(Context *context, GLuint program)
6352{
6353 if (program != 0)
6354 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006355 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006356 if (!programObject)
6357 {
6358 // ES 3.1.0 section 7.3 page 72
6359 if (context->getShader(program))
6360 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006361 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006362 return false;
6363 }
6364 else
6365 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006366 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006367 return false;
6368 }
6369 }
6370 if (!programObject->isLinked())
6371 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006372 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006373 return false;
6374 }
6375 }
6376 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6377 {
6378 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006379 context
6380 ->handleError(InvalidOperation()
6381 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006382 return false;
6383 }
6384
6385 return true;
6386}
6387
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006388bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6389{
6390 if (!context->getExtensions().fence)
6391 {
6392 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6393 return false;
6394 }
6395
6396 if (n < 0)
6397 {
6398 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6399 return false;
6400 }
6401
6402 return true;
6403}
6404
6405bool ValidateFinishFenceNV(Context *context, GLuint fence)
6406{
6407 if (!context->getExtensions().fence)
6408 {
6409 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6410 return false;
6411 }
6412
6413 FenceNV *fenceObject = context->getFenceNV(fence);
6414
6415 if (fenceObject == nullptr)
6416 {
6417 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6418 return false;
6419 }
6420
6421 if (!fenceObject->isSet())
6422 {
6423 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6424 return false;
6425 }
6426
6427 return true;
6428}
6429
6430bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6431{
6432 if (!context->getExtensions().fence)
6433 {
6434 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6435 return false;
6436 }
6437
6438 if (n < 0)
6439 {
6440 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6441 return false;
6442 }
6443
6444 return true;
6445}
6446
6447bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6448{
6449 if (!context->getExtensions().fence)
6450 {
6451 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6452 return false;
6453 }
6454
6455 FenceNV *fenceObject = context->getFenceNV(fence);
6456
6457 if (fenceObject == nullptr)
6458 {
6459 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6460 return false;
6461 }
6462
6463 if (!fenceObject->isSet())
6464 {
6465 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6466 return false;
6467 }
6468
6469 switch (pname)
6470 {
6471 case GL_FENCE_STATUS_NV:
6472 case GL_FENCE_CONDITION_NV:
6473 break;
6474
6475 default:
6476 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6477 return false;
6478 }
6479
6480 return true;
6481}
6482
6483bool ValidateGetGraphicsResetStatusEXT(Context *context)
6484{
6485 if (!context->getExtensions().robustness)
6486 {
6487 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6488 return false;
6489 }
6490
6491 return true;
6492}
6493
6494bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6495 GLuint shader,
6496 GLsizei bufsize,
6497 GLsizei *length,
6498 GLchar *source)
6499{
6500 if (!context->getExtensions().translatedShaderSource)
6501 {
6502 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6503 return false;
6504 }
6505
6506 if (bufsize < 0)
6507 {
6508 context->handleError(InvalidValue());
6509 return false;
6510 }
6511
6512 Shader *shaderObject = context->getShader(shader);
6513
6514 if (!shaderObject)
6515 {
6516 context->handleError(InvalidOperation());
6517 return false;
6518 }
6519
6520 return true;
6521}
6522
6523bool ValidateIsFenceNV(Context *context, GLuint fence)
6524{
6525 if (!context->getExtensions().fence)
6526 {
6527 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6528 return false;
6529 }
6530
6531 return true;
6532}
6533
Jamie Madill007530e2017-12-28 14:27:04 -05006534bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6535{
6536 if (!context->getExtensions().fence)
6537 {
6538 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6539 return false;
6540 }
6541
6542 if (condition != GL_ALL_COMPLETED_NV)
6543 {
6544 context->handleError(InvalidEnum());
6545 return false;
6546 }
6547
6548 FenceNV *fenceObject = context->getFenceNV(fence);
6549
6550 if (fenceObject == nullptr)
6551 {
6552 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6553 return false;
6554 }
6555
6556 return true;
6557}
6558
6559bool ValidateTestFenceNV(Context *context, GLuint fence)
6560{
6561 if (!context->getExtensions().fence)
6562 {
6563 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6564 return false;
6565 }
6566
6567 FenceNV *fenceObject = context->getFenceNV(fence);
6568
6569 if (fenceObject == nullptr)
6570 {
6571 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6572 return false;
6573 }
6574
6575 if (fenceObject->isSet() != GL_TRUE)
6576 {
6577 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6578 return false;
6579 }
6580
6581 return true;
6582}
6583
6584bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006585 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006586 GLsizei levels,
6587 GLenum internalformat,
6588 GLsizei width,
6589 GLsizei height)
6590{
6591 if (!context->getExtensions().textureStorage)
6592 {
6593 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6594 return false;
6595 }
6596
6597 if (context->getClientMajorVersion() < 3)
6598 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006599 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006600 height);
6601 }
6602
6603 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006604 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006605 1);
6606}
6607
6608bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6609{
6610 if (!context->getExtensions().instancedArrays)
6611 {
6612 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6613 return false;
6614 }
6615
6616 if (index >= MAX_VERTEX_ATTRIBS)
6617 {
6618 context->handleError(InvalidValue());
6619 return false;
6620 }
6621
6622 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6623 {
6624 if (index == 0 && divisor != 0)
6625 {
6626 const char *errorMessage =
6627 "The current context doesn't support setting a non-zero divisor on the "
6628 "attribute with index zero. "
6629 "Please reorder the attributes in your vertex shader so that attribute zero "
6630 "can have a zero divisor.";
6631 context->handleError(InvalidOperation() << errorMessage);
6632
6633 // We also output an error message to the debugger window if tracing is active, so
6634 // that developers can see the error message.
6635 ERR() << errorMessage;
6636 return false;
6637 }
6638 }
6639
6640 return true;
6641}
6642
6643bool ValidateTexImage3DOES(Context *context,
6644 GLenum target,
6645 GLint level,
6646 GLenum internalformat,
6647 GLsizei width,
6648 GLsizei height,
6649 GLsizei depth,
6650 GLint border,
6651 GLenum format,
6652 GLenum type,
6653 const void *pixels)
6654{
6655 UNIMPLEMENTED(); // FIXME
6656 return false;
6657}
6658
6659bool ValidatePopGroupMarkerEXT(Context *context)
6660{
6661 if (!context->getExtensions().debugMarker)
6662 {
6663 // The debug marker calls should not set error state
6664 // However, it seems reasonable to set an error state if the extension is not enabled
6665 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6666 return false;
6667 }
6668
6669 return true;
6670}
6671
Jamie Madillfa920eb2018-01-04 11:45:50 -05006672bool ValidateTexStorage1DEXT(Context *context,
6673 GLenum target,
6674 GLsizei levels,
6675 GLenum internalformat,
6676 GLsizei width)
6677{
6678 UNIMPLEMENTED();
6679 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6680 return false;
6681}
6682
6683bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006684 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006685 GLsizei levels,
6686 GLenum internalformat,
6687 GLsizei width,
6688 GLsizei height,
6689 GLsizei depth)
6690{
6691 if (!context->getExtensions().textureStorage)
6692 {
6693 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6694 return false;
6695 }
6696
6697 if (context->getClientMajorVersion() < 3)
6698 {
6699 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6700 return false;
6701 }
6702
6703 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6704 depth);
6705}
6706
jchen1082af6202018-06-22 10:59:52 +08006707bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6708{
6709 if (!context->getExtensions().parallelShaderCompile)
6710 {
6711 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6712 return false;
6713 }
6714 return true;
6715}
6716
Austin Eng1bf18ce2018-10-19 15:34:02 -07006717bool ValidateMultiDrawArraysANGLE(Context *context,
6718 PrimitiveMode mode,
6719 const GLint *firsts,
6720 const GLsizei *counts,
6721 GLsizei drawcount)
6722{
6723 if (!context->getExtensions().multiDraw)
6724 {
6725 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6726 return false;
6727 }
6728 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6729 {
6730 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6731 {
6732 return false;
6733 }
6734 }
6735 return true;
6736}
6737
6738bool ValidateMultiDrawElementsANGLE(Context *context,
6739 PrimitiveMode mode,
6740 const GLsizei *counts,
6741 GLenum type,
6742 const GLsizei *offsets,
6743 GLsizei drawcount)
6744{
6745 if (!context->getExtensions().multiDraw)
6746 {
6747 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6748 return false;
6749 }
6750 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6751 {
6752 const void *indices = reinterpret_cast<void *>(static_cast<long>(offsets[drawID]));
6753 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices))
6754 {
6755 return false;
6756 }
6757 }
6758 return true;
6759}
6760
Jamie Madillc29968b2016-01-20 11:17:23 -05006761} // namespace gl